#![doc(html_root_url = "https://docs.rs/clingo/0.6.0")]
#![allow(non_upper_case_globals)]
#![allow(clippy::try_err)]
use bitflags::bitflags;
use clingo_sys::*;
use std::cmp::Ordering;
use std::collections::HashSet;
use std::ffi::CStr;
use std::ffi::CString;
use std::ffi::NulError;
use std::hash::{Hash, Hasher};
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::ptr::NonNull;
use std::str::Utf8Error;
use thiserror::Error;
pub mod ast;
#[derive(Error, Debug)]
pub enum ClingoError {
#[error("NulError: ")]
NulError(#[from] NulError),
#[error("Utf8Error: ")]
Utf8Error(#[from] Utf8Error),
#[error("FFIError: {msg}")]
FFIError { msg: &'static str },
#[error("InternalError: {msg}, code: {code:?}, last: {last}")]
InternalError {
msg: &'static str,
code: ErrorCode,
last: &'static str,
},
#[error("ExternalError: ")]
ExternalError(#[from] ExternalError),
}
impl ClingoError {
fn new_internal(msg: &'static str) -> ClingoError {
ClingoError::InternalError {
msg,
code: error_code(),
last: error_message(),
}
}
}
#[derive(Error, Debug)]
#[error("ExternalError: {msg}")]
pub struct ExternalError {
pub msg: &'static str,
}
#[derive(Debug, Copy, Clone)]
pub enum ErrorType {
Success = clingo_error_clingo_error_success as isize,
Runtime = clingo_error_clingo_error_runtime as isize,
Logic = clingo_error_clingo_error_logic as isize,
BadAlloc = clingo_error_clingo_error_bad_alloc as isize,
Unknown = clingo_error_clingo_error_unknown as isize,
}
#[derive(Debug, Copy, Clone)]
pub enum ErrorCode {
Success,
Runtime,
Logic,
BadAlloc,
Unknown,
FFIError,
}
impl From<i32> for ErrorCode {
fn from(error: i32) -> Self {
match error as u32 {
clingo_error_clingo_error_success => ErrorCode::Success,
clingo_error_clingo_error_runtime => ErrorCode::Runtime,
clingo_error_clingo_error_logic => ErrorCode::Logic,
clingo_error_clingo_error_bad_alloc => ErrorCode::BadAlloc,
clingo_error_clingo_error_unknown => ErrorCode::Unknown,
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_error {}",
file!(),
line!(),
column!(),
x
);
ErrorCode::FFIError
}
}
}
}
fn error_code() -> ErrorCode {
ErrorCode::from(unsafe { clingo_error_code() })
}
fn error_message() -> &'static str {
let char_ptr: *const c_char = unsafe { clingo_error_message() };
if char_ptr.is_null() {
"Ooops, original error message is null."
} else {
let c_str = unsafe { CStr::from_ptr(char_ptr) };
c_str
.to_str()
.unwrap_or("Ooops, original error message was no valid utf8 string.")
}
}
pub fn set_error(code: ErrorType, message: &str) -> Result<(), NulError> {
let message = CString::new(message)?;
unsafe { clingo_set_error(code as clingo_error_t, message.as_ptr()) }
Ok(())
}
fn set_internal_error(code: ErrorType, message: &'static str) {
let message = CString::new(message).unwrap();
unsafe { clingo_set_error(code as clingo_error_t, message.as_ptr()) }
}
#[derive(Debug, Copy, Clone)]
pub enum TruthValue {
Free = clingo_truth_value_clingo_truth_value_free as isize,
True = clingo_truth_value_clingo_truth_value_true as isize,
False = clingo_truth_value_clingo_truth_value_false as isize,
}
impl TruthValue {
fn try_from(code: i32) -> Result<TruthValue, ClingoError> {
match code as u32 {
clingo_truth_value_clingo_truth_value_false => Ok(TruthValue::False),
clingo_truth_value_clingo_truth_value_true => Ok(TruthValue::True),
clingo_truth_value_clingo_truth_value_free => Ok(TruthValue::Free),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_truth_value {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_truth_value.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum ClauseType {
Learnt = clingo_clause_type_clingo_clause_type_learnt as isize,
Static = clingo_clause_type_clingo_clause_type_static as isize,
Volatile = clingo_clause_type_clingo_clause_type_volatile as isize,
VolatileStatic = clingo_clause_type_clingo_clause_type_volatile_static as isize,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum SolveEventType {
Model = clingo_solve_event_type_clingo_solve_event_type_model as isize,
Statistics = clingo_solve_event_type_clingo_solve_event_type_statistics as isize,
Finish = clingo_solve_event_type_clingo_solve_event_type_finish as isize,
}
impl SolveEventType {
fn try_from(code: u32) -> Result<SolveEventType, ClingoError> {
match code {
clingo_solve_event_type_clingo_solve_event_type_model => Ok(SolveEventType::Model),
clingo_solve_event_type_clingo_solve_event_type_statistics => {
Ok(SolveEventType::Statistics)
}
clingo_solve_event_type_clingo_solve_event_type_finish => Ok(SolveEventType::Finish),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_solve_event_type {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_solve_event_type.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum StatisticsType {
Empty = clingo_statistics_type_clingo_statistics_type_empty as isize,
Value = clingo_statistics_type_clingo_statistics_type_value as isize,
Array = clingo_statistics_type_clingo_statistics_type_array as isize,
Map = clingo_statistics_type_clingo_statistics_type_map as isize,
}
impl StatisticsType {
fn try_from(code: i32) -> Result<StatisticsType, ClingoError> {
match code as u32 {
clingo_statistics_type_clingo_statistics_type_empty => Ok(StatisticsType::Empty),
clingo_statistics_type_clingo_statistics_type_value => Ok(StatisticsType::Value),
clingo_statistics_type_clingo_statistics_type_array => Ok(StatisticsType::Array),
clingo_statistics_type_clingo_statistics_type_map => Ok(StatisticsType::Map),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_statistics_type {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_statistics_type.",
})
}
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum SymbolType {
Infimum = clingo_symbol_type_clingo_symbol_type_infimum as isize,
Number = clingo_symbol_type_clingo_symbol_type_number as isize,
String = clingo_symbol_type_clingo_symbol_type_string as isize,
Function = clingo_symbol_type_clingo_symbol_type_function as isize,
Supremum = clingo_symbol_type_clingo_symbol_type_supremum as isize,
}
impl SymbolType {
fn try_from(code: i32) -> Result<SymbolType, ClingoError> {
match code as u32 {
clingo_symbol_type_clingo_symbol_type_infimum => Ok(SymbolType::Infimum),
clingo_symbol_type_clingo_symbol_type_number => Ok(SymbolType::Number),
clingo_symbol_type_clingo_symbol_type_string => Ok(SymbolType::String),
clingo_symbol_type_clingo_symbol_type_function => Ok(SymbolType::Function),
clingo_symbol_type_clingo_symbol_type_supremum => Ok(SymbolType::Supremum),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_symbol_type {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_symbol_type.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum Warning {
OperationUndefined = clingo_warning_clingo_warning_operation_undefined as isize,
RuntimeError = clingo_warning_clingo_warning_runtime_error as isize,
AtomUndefined = clingo_warning_clingo_warning_atom_undefined as isize,
FileIncluded = clingo_warning_clingo_warning_file_included as isize,
VariableUnbound = clingo_warning_clingo_warning_variable_unbounded as isize,
GlobalVariable = clingo_warning_clingo_warning_global_variable as isize,
Other = clingo_warning_clingo_warning_other as isize,
}
impl Warning {
fn try_from(code: i32) -> Result<Warning, ClingoError> {
match code as u32 {
clingo_warning_clingo_warning_atom_undefined => Ok(Warning::AtomUndefined),
clingo_warning_clingo_warning_file_included => Ok(Warning::FileIncluded),
clingo_warning_clingo_warning_global_variable => Ok(Warning::GlobalVariable),
clingo_warning_clingo_warning_operation_undefined => Ok(Warning::OperationUndefined),
clingo_warning_clingo_warning_other => Ok(Warning::Other),
clingo_warning_clingo_warning_runtime_error => Ok(Warning::RuntimeError),
clingo_warning_clingo_warning_variable_unbounded => Ok(Warning::VariableUnbound),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_warning {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_warning.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum ExternalType {
Free = clingo_external_type_clingo_external_type_free as isize,
True = clingo_external_type_clingo_external_type_true as isize,
False = clingo_external_type_clingo_external_type_false as isize,
Release = clingo_external_type_clingo_external_type_release as isize,
}
impl ExternalType {
fn try_from(code: i32) -> Result<ExternalType, ClingoError> {
match code as u32 {
clingo_external_type_clingo_external_type_false => Ok(ExternalType::False),
clingo_external_type_clingo_external_type_free => Ok(ExternalType::Free),
clingo_external_type_clingo_external_type_release => Ok(ExternalType::Release),
clingo_external_type_clingo_external_type_true => Ok(ExternalType::True),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_external_type {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_external_type.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum HeuristicType {
Level = clingo_heuristic_type_clingo_heuristic_type_level as isize,
Sign = clingo_heuristic_type_clingo_heuristic_type_sign as isize,
Factor = clingo_heuristic_type_clingo_heuristic_type_factor as isize,
Init = clingo_heuristic_type_clingo_heuristic_type_init as isize,
True = clingo_heuristic_type_clingo_heuristic_type_true as isize,
False = clingo_heuristic_type_clingo_heuristic_type_false as isize,
}
impl HeuristicType {
fn try_from(code: i32) -> Result<HeuristicType, ClingoError> {
match code as u32 {
clingo_heuristic_type_clingo_heuristic_type_factor => Ok(HeuristicType::Factor),
clingo_heuristic_type_clingo_heuristic_type_false => Ok(HeuristicType::False),
clingo_heuristic_type_clingo_heuristic_type_init => Ok(HeuristicType::Init),
clingo_heuristic_type_clingo_heuristic_type_level => Ok(HeuristicType::Level),
clingo_heuristic_type_clingo_heuristic_type_sign => Ok(HeuristicType::Sign),
clingo_heuristic_type_clingo_heuristic_type_true => Ok(HeuristicType::True),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_heuristic_type {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_heuristic_type.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum TheoryTermType {
Tuple = clingo_theory_term_type_clingo_theory_term_type_tuple as isize,
List = clingo_theory_term_type_clingo_theory_term_type_list as isize,
Set = clingo_theory_term_type_clingo_theory_term_type_set as isize,
Function = clingo_theory_term_type_clingo_theory_term_type_function as isize,
Number = clingo_theory_term_type_clingo_theory_term_type_number as isize,
Symbol = clingo_theory_term_type_clingo_theory_term_type_symbol as isize,
}
impl TheoryTermType {
fn try_from(code: i32) -> Result<TheoryTermType, ClingoError> {
match code as u32 {
clingo_theory_term_type_clingo_theory_term_type_tuple => Ok(TheoryTermType::Tuple),
clingo_theory_term_type_clingo_theory_term_type_list => Ok(TheoryTermType::List),
clingo_theory_term_type_clingo_theory_term_type_set => Ok(TheoryTermType::Set),
clingo_theory_term_type_clingo_theory_term_type_function => {
Ok(TheoryTermType::Function)
}
clingo_theory_term_type_clingo_theory_term_type_number => Ok(TheoryTermType::Number),
clingo_theory_term_type_clingo_theory_term_type_symbol => Ok(TheoryTermType::Symbol),
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_theory_term_type {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_theory_term_type.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum ModelType {
StableModel = clingo_model_type_clingo_model_type_stable_model as isize,
BraveConsequences = clingo_model_type_clingo_model_type_brave_consequences as isize,
CautiousConsequences = clingo_model_type_clingo_model_type_cautious_consequences as isize,
}
impl ModelType {
fn try_from(code: i32) -> Result<ModelType, ClingoError> {
match code as u32 {
clingo_model_type_clingo_model_type_stable_model => Ok(ModelType::StableModel),
clingo_model_type_clingo_model_type_brave_consequences => {
Ok(ModelType::BraveConsequences)
}
clingo_model_type_clingo_model_type_cautious_consequences => {
Ok(ModelType::CautiousConsequences)
}
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_model_type {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_model_type.",
})
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum PropagatorCheckMode {
None = clingo_propagator_check_mode_clingo_propagator_check_mode_none as isize,
Total = clingo_propagator_check_mode_clingo_propagator_check_mode_total as isize,
Fixpoint = clingo_propagator_check_mode_clingo_propagator_check_mode_fixpoint as isize,
}
impl PropagatorCheckMode {
fn try_from(code: i32) -> Result<PropagatorCheckMode, ClingoError> {
match code as u32 {
clingo_propagator_check_mode_clingo_propagator_check_mode_fixpoint => {
Ok(PropagatorCheckMode::Fixpoint)
}
clingo_propagator_check_mode_clingo_propagator_check_mode_total => {
Ok(PropagatorCheckMode::Total)
}
clingo_propagator_check_mode_clingo_propagator_check_mode_none => {
Ok(PropagatorCheckMode::None)
}
x => {
eprintln!(
"FFIError in {} {}, {} : Failed to match clingo_propagator_check_mode {}",
file!(),
line!(),
column!(),
x
);
Err(ClingoError::FFIError {
msg: "Failed to match clingo_propagator_check_mode.",
})
}
}
}
}
bitflags! {
pub struct ConfigurationType: u32 {
const VALUE =
clingo_configuration_type_clingo_configuration_type_value;
const ARRAY =
clingo_configuration_type_clingo_configuration_type_array;
const MAP =
clingo_configuration_type_clingo_configuration_type_map;
}
}
bitflags! {
pub struct SolveMode: u32 {
const ASYNC = clingo_solve_mode_clingo_solve_mode_async;
const YIELD = clingo_solve_mode_clingo_solve_mode_yield;
}
}
bitflags! {
pub struct ShowType: u32 {
const CSP = clingo_show_type_clingo_show_type_csp;
const SHOWN = clingo_show_type_clingo_show_type_shown;
const ATOMS = clingo_show_type_clingo_show_type_atoms;
const TERMS = clingo_show_type_clingo_show_type_terms;
const ALL = clingo_show_type_clingo_show_type_all;
const COMPLEMENT = clingo_show_type_clingo_show_type_complement;
}
}
bitflags! {
pub struct SolveResult: u32 {
const SATISFIABLE = clingo_solve_result_clingo_solve_result_satisfiable;
const UNSATISFIABLE =
clingo_solve_result_clingo_solve_result_unsatisfiable;
const EXHAUSTED = clingo_solve_result_clingo_solve_result_exhausted;
const INTERRUPTED = clingo_solve_result_clingo_solve_result_interrupted;
}
}
type SolveEventCallback = unsafe extern "C" fn(
type_: clingo_solve_event_type_t,
event: *mut c_void,
event_handler: *mut c_void,
goon: *mut bool,
) -> bool;
pub trait SolveEventHandler {
fn on_solve_event(&mut self, etype: SolveEventType, goon: &mut bool) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_solve_callback<T: SolveEventHandler>(
etype: clingo_solve_event_type_t,
event: *mut c_void,
event_handler: *mut c_void,
goon: *mut bool,
) -> bool {
if event_handler.is_null() | goon.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_solve_callback() got a null pointer.",
);
return false;
}
let event_handler = &mut *(event_handler as *mut T);
let goon = &mut *goon;
match SolveEventType::try_from(etype) {
Err(_) => {
set_internal_error(ErrorType::Runtime, "Error in unsafe_solve_callback().");
false
}
Ok(etype) => event_handler.on_solve_event(etype, goon),
}
}
}
type AstCallback =
unsafe extern "C" fn(arg1: *const clingo_ast_statement_t, arg2: *mut c_void) -> bool;
pub trait StatementHandler {
fn on_statement(&mut self, arg1: &ast::Statement) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_ast_callback<T: StatementHandler>(
stm: *const clingo_ast_statement_t,
event_handler: *mut c_void,
) -> bool {
if stm.is_null() | event_handler.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_ast_callback() got a null pointer.",
);
return false;
}
let stm = &*(stm as *const ast::Statement);
let event_handler = &mut *(event_handler as *mut T);
event_handler.on_statement(stm)
}
}
type LoggingCallback =
unsafe extern "C" fn(code: clingo_warning_t, message: *const c_char, logger: *mut c_void);
pub trait Logger {
fn log(&mut self, code: Warning, message: &str) {
print!("warn {:?}: {}", code, message);
}
#[doc(hidden)]
unsafe extern "C" fn unsafe_logging_callback<L: Logger>(
code: clingo_warning_t,
message: *const c_char,
logger: *mut c_void,
) {
if message.is_null() | logger.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_logging_callback() got a null pointer.",
);
return;
}
let message = CStr::from_ptr(message);
let logger = &mut *(logger as *mut L);
if let Err(e) = logger.try_logging_callback(code, message) {
eprintln!("Error in unsafe_logging_callback(): {}.", e);
set_internal_error(ErrorType::Runtime, "Error in unsafe_logging_callback().");
}
}
#[doc(hidden)]
fn try_logging_callback(
&mut self,
code: clingo_warning_t,
message: &CStr,
) -> Result<(), ClingoError> {
let code = Warning::try_from(code)?;
let message = message.to_str()?;
self.log(code, message);
Ok(())
}
}
type GroundCallback = unsafe extern "C" fn(
location: *const clingo_location_t,
name: *const c_char,
arguments: *const clingo_symbol_t,
arguments_size: usize,
event_handler: *mut c_void,
symbol_callback: clingo_symbol_callback_t,
symbol_callback_data: *mut c_void,
) -> bool;
pub trait ExternalFunctionHandler {
fn on_external_function(
&mut self,
location: &Location,
name: &str,
arguments: &[Symbol],
) -> Result<Vec<Symbol>, ExternalError>;
#[doc(hidden)]
unsafe extern "C" fn unsafe_ground_callback<T: ExternalFunctionHandler>(
location: *const clingo_location_t,
name: *const c_char,
arguments: *const clingo_symbol_t,
arguments_size: usize,
event_handler: *mut c_void,
symbol_callback: clingo_symbol_callback_t,
symbol_callback_data: *mut c_void,
) -> bool {
if location.is_null()
| name.is_null()
| (arguments_size > 0 && arguments.is_null())
| event_handler.is_null()
{
set_internal_error(
ErrorType::Runtime,
"unsafe_ground_callback() got a null pointer.",
);
return false;
}
let location = &*(location as *const Location);
let name = CStr::from_ptr(name);
let arguments = std::slice::from_raw_parts(arguments as *const Symbol, arguments_size);
let event_handler = &mut *(event_handler as *mut T);
match event_handler.try_symbol_callback(
location,
name,
arguments,
symbol_callback,
symbol_callback_data,
) {
Ok(x) => x,
Err(e) => {
eprintln!("Error in unsafe_ground_callback(): {}.", e);
set_internal_error(ErrorType::Runtime, "Error in unsafe_ground_callback().");
false
}
}
}
#[doc(hidden)]
fn try_symbol_callback(
&mut self,
location: &Location,
name: &CStr,
arguments: &[Symbol],
symbol_callback: clingo_symbol_callback_t,
symbol_callback_data: *mut c_void,
) -> Result<bool, ClingoError> {
let name = name.to_str()?;
let symbols = self.on_external_function(location, name, arguments)?;
if let Some(symbol_callback) = symbol_callback {
let v: Vec<clingo_symbol_t> = symbols.iter().map(|symbol| (*symbol).0).collect();
Ok(unsafe { symbol_callback(v.as_slice().as_ptr(), v.len(), symbol_callback_data) })
} else {
Ok(true)
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Literal(clingo_literal_t);
impl Literal {
pub fn negate(self) -> Literal {
Literal(-(self.0))
}
pub fn from(Atom(atom): Atom) -> Literal {
Literal(atom as clingo_literal_t)
}
pub fn get_integer(self) -> i32 {
self.0
}
}
#[derive(Debug, Copy, Clone)]
pub struct Atom(clingo_atom_t);
#[derive(Debug, Copy, Clone)]
pub struct Id(clingo_id_t);
impl Id {
pub fn get_integer(self) -> u32 {
self.0
}
}
#[derive(Debug, Copy, Clone)]
pub struct WeightedLiteral(clingo_weighted_literal);
impl WeightedLiteral {
pub fn literal(self) -> Literal {
Literal(self.0.literal)
}
pub fn weight(self) -> i32 {
self.0.weight
}
}
#[derive(Debug, Copy, Clone)]
pub struct Location(clingo_location);
impl Location {
fn default() -> clingo_location {
let file = CString::new("").unwrap();
clingo_location {
begin_line: 0,
end_line: 0,
begin_column: 0,
end_column: 0,
begin_file: file.as_ptr(),
end_file: file.as_ptr(),
}
}
pub fn new(
begin_file: &str,
end_file: &str,
begin_line: usize,
end_line: usize,
begin_column: usize,
end_column: usize,
) -> Result<Location, NulError> {
let begin_file = CString::new(begin_file)?;
let end_file = CString::new(end_file)?;
let loc = clingo_location {
begin_line,
end_line,
begin_column,
end_column,
begin_file: begin_file.as_ptr(),
end_file: end_file.as_ptr(),
};
Ok(Location(loc))
}
pub fn begin_file(&self) -> Result<&str, Utf8Error> {
if self.0.begin_file.is_null() {
Ok("")
} else {
let c_str = unsafe { CStr::from_ptr(self.0.begin_file) };
c_str.to_str()
}
}
pub fn end_file(&self) -> Result<&str, Utf8Error> {
if self.0.end_file.is_null() {
Ok("")
} else {
let c_str = unsafe { CStr::from_ptr(self.0.end_file) };
c_str.to_str()
}
}
pub fn begin_line(&self) -> usize {
self.0.begin_line
}
pub fn end_line(&self) -> usize {
self.0.end_line
}
pub fn begin_column(&self) -> usize {
self.0.begin_column
}
pub fn end_column(&self) -> usize {
self.0.end_column
}
}
#[derive(Debug, Copy, Clone)]
pub struct Signature(clingo_signature_t);
impl PartialEq for Signature {
fn eq(&self, other: &Signature) -> bool {
unsafe { clingo_signature_is_equal_to(self.0, other.0) }
}
}
impl Eq for Signature {}
impl PartialOrd for Signature {
fn partial_cmp(&self, other: &Signature) -> Option<Ordering> {
if unsafe { clingo_signature_is_less_than(self.0, other.0) } {
return Some(Ordering::Less);
}
if unsafe { clingo_signature_is_less_than(other.0, self.0) } {
return Some(Ordering::Greater);
}
Some(Ordering::Equal)
}
}
impl Hash for Signature {
fn hash<H: Hasher>(&self, state: &mut H) {
unsafe { clingo_signature_hash(self.0) }.hash(state);
}
}
impl Signature {
pub fn new(name: &str, arity: u32, positive: bool) -> Result<Signature, ClingoError> {
let name = CString::new(name)?;
let mut signature = 0;
if !unsafe { clingo_signature_create(name.as_ptr(), arity, positive, &mut signature) } {
return Err(ClingoError::new_internal(
"Call to clingo_signature_create() failed",
));
}
Ok(Signature(signature))
}
pub fn name(&self) -> Result<&str, Utf8Error> {
let char_ptr: *const c_char = unsafe { clingo_signature_name(self.0) };
if char_ptr.is_null() {
Ok("")
} else {
let c_str = unsafe { CStr::from_ptr(char_ptr) };
c_str.to_str()
}
}
pub fn arity(self) -> u32 {
unsafe { clingo_signature_arity(self.0) }
}
pub fn is_positive(self) -> bool {
unsafe { clingo_signature_is_positive(self.0) }
}
pub fn is_negative(self) -> bool {
unsafe { clingo_signature_is_negative(self.0) }
}
}
#[derive(Debug, Copy, Clone)]
pub struct Symbol(clingo_symbol_t);
impl PartialEq for Symbol {
fn eq(&self, other: &Symbol) -> bool {
unsafe { clingo_symbol_is_equal_to(self.0, other.0) }
}
}
impl Eq for Symbol {}
impl PartialOrd for Symbol {
fn partial_cmp(&self, other: &Symbol) -> Option<Ordering> {
if unsafe { clingo_symbol_is_less_than(self.0, other.0) } {
return Some(Ordering::Less);
}
if unsafe { clingo_symbol_is_less_than(other.0, self.0) } {
return Some(Ordering::Greater);
}
Some(Ordering::Equal)
}
}
impl Hash for Symbol {
fn hash<H: Hasher>(&self, state: &mut H) {
unsafe { clingo_symbol_hash(self.0) }.hash(state);
}
}
impl Symbol {
pub fn create_number(number: i32) -> Symbol {
let mut symbol = 0 as clingo_symbol_t;
unsafe { clingo_symbol_create_number(number, &mut symbol) };
Symbol(symbol)
}
pub fn create_supremum() -> Symbol {
let mut symbol = 0 as clingo_symbol_t;
unsafe { clingo_symbol_create_supremum(&mut symbol) };
Symbol(symbol)
}
pub fn create_infimum() -> Symbol {
let mut symbol = 0 as clingo_symbol_t;
unsafe { clingo_symbol_create_infimum(&mut symbol) };
Symbol(symbol)
}
pub fn create_string(string: &str) -> Result<Symbol, ClingoError> {
let mut symbol = 0 as clingo_symbol_t;
let c_str = CString::new(string)?;
if !unsafe { clingo_symbol_create_string(c_str.as_ptr(), &mut symbol) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_create_string() failed",
));
}
Ok(Symbol(symbol))
}
pub fn create_id(name: &str, positive: bool) -> Result<Symbol, ClingoError> {
let mut symbol = 0 as clingo_symbol_t;
let name = CString::new(name)?;
if !unsafe { clingo_symbol_create_id(name.as_ptr(), positive, &mut symbol) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_create_id() failed",
));
}
Ok(Symbol(symbol))
}
pub fn create_function(
name: &str,
arguments: &[Symbol],
positive: bool,
) -> Result<Symbol, ClingoError> {
let mut symbol = 0 as clingo_symbol_t;
let name = CString::new(name)?;
if !unsafe {
clingo_symbol_create_function(
name.as_ptr(),
arguments.as_ptr() as *const clingo_symbol_t,
arguments.len(),
positive,
&mut symbol,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_create_function() failed",
));
}
Ok(Symbol(symbol))
}
pub fn number(self) -> Result<i32, ClingoError> {
let mut number = 0;
if !unsafe { clingo_symbol_number(self.0, &mut number) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_number() failed",
));
}
Ok(number)
}
pub fn name(&self) -> Result<&str, ClingoError> {
let mut char_ptr = std::ptr::null();
if !unsafe { clingo_symbol_name(self.0, &mut char_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_name() failed",
));
}
if char_ptr.is_null() {
return Err(ClingoError::new_internal(
"clingo_symbol_name() returned a null pointer.",
));
}
let c_str = unsafe { CStr::from_ptr(char_ptr) };
Ok(c_str.to_str()?)
}
pub fn string(&self) -> Result<&str, ClingoError> {
let mut char_ptr = std::ptr::null();
if !unsafe { clingo_symbol_string(self.0, &mut char_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_string() failed",
));
}
if char_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_symbol_string() returned a null pointer.",
});
}
let c_str = unsafe { CStr::from_ptr(char_ptr) };
Ok(c_str.to_str()?)
}
pub fn is_positive(self) -> Result<bool, ClingoError> {
let mut positive = false;
if !unsafe { clingo_symbol_is_positive(self.0, &mut positive) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_is_positive() failed",
));
}
Ok(positive)
}
pub fn is_negative(self) -> Result<bool, ClingoError> {
let mut negative = false;
if !unsafe { clingo_symbol_is_negative(self.0, &mut negative) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_is_negative() failed",
));
}
Ok(negative)
}
pub fn arguments(self) -> Result<Vec<Symbol>, ClingoError> {
let mut symbol_ptr = std::ptr::null();
let mut size: usize = 0;
if !unsafe { clingo_symbol_arguments(self.0, &mut symbol_ptr, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_arguments() failed",
));
}
let mut symbols = Vec::<Symbol>::with_capacity(size);
for _ in 0..size {
if symbol_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_symbol_arguments() returned a null pointer.",
});
}
let nsymbol = unsafe { *symbol_ptr };
symbols.push(Symbol(nsymbol));
symbol_ptr = unsafe { symbol_ptr.offset(1) };
}
Ok(symbols)
}
pub fn symbol_type(self) -> Result<SymbolType, ClingoError> {
SymbolType::try_from(unsafe { clingo_symbol_type(self.0) })
}
pub fn to_string(self) -> Result<String, ClingoError> {
let mut size: usize = 0;
if !unsafe { clingo_symbol_to_string_size(self.0, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_to_string_size() failed",
));
}
let mut string = Vec::with_capacity(size);
let string_ptr = string.as_mut_ptr();
if !unsafe { clingo_symbol_to_string(self.0, string_ptr, size) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbol_to_string() failed",
));
}
let c_str: &CStr = unsafe { CStr::from_ptr(string_ptr) };
let str_slice: &str = c_str.to_str()?;
Ok(str_slice.to_owned())
}
}
pub fn parse_program<T: StatementHandler>(
program: &str,
handler: &mut T,
) -> Result<(), ClingoError> {
let logger = None;
let logger_data = std::ptr::null_mut();
let program = CString::new(program)?;
let handler = handler as *mut T;
if !unsafe {
clingo_parse_program(
program.as_ptr(),
Some(T::unsafe_ast_callback::<T> as AstCallback),
handler as *mut c_void,
logger,
logger_data,
0,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_parse_program() failed",
));
}
Ok(())
}
pub fn parse_program_with_logger<T: StatementHandler, L: Logger>(
program: &str,
handler: &mut T,
logger: &mut L,
message_limit: u32,
) -> Result<(), ClingoError> {
let handler = handler as *mut T;
let logger = logger as *mut L;
let program = CString::new(program)?;
if !unsafe {
clingo_parse_program(
program.as_ptr(),
Some(T::unsafe_ast_callback::<T> as AstCallback),
handler as *mut c_void,
Some(L::unsafe_logging_callback::<L> as LoggingCallback),
logger as *mut c_void,
message_limit,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_parse_program() failed",
));
}
Ok(())
}
pub fn version() -> (i32, i32, i32) {
let mut major = 0;
let mut minor = 0;
let mut revision = 0;
unsafe { clingo_version(&mut major, &mut minor, &mut revision) };
(major, minor, revision)
}
pub struct Part<'a> {
name: CString,
params: &'a [Symbol],
}
impl<'a> Part<'a> {
pub fn new(name: &str, params: &'a [Symbol]) -> Result<Part<'a>, ClingoError> {
Ok(Part {
name: CString::new(name)?,
params,
})
}
fn from(&self) -> clingo_part {
clingo_part {
name: self.name.as_ptr(),
params: self.params.as_ptr() as *const clingo_symbol_t,
size: self.params.len(),
}
}
}
pub trait Propagator {
fn init(&mut self, _init: &mut PropagateInit) -> bool {
true
}
#[doc(hidden)]
unsafe extern "C" fn unsafe_init<T: Propagator>(
init: *mut clingo_propagate_init_t,
propagator: *mut c_void,
) -> bool {
if init.is_null() | propagator.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_init() got a null pointer.");
return false;
}
let init = &mut *(init as *mut PropagateInit);
let propagator = &mut *(propagator as *mut T);
propagator.init(init)
}
fn propagate(&mut self, _control: &mut PropagateControl, _changes: &[Literal]) -> bool {
true
}
#[doc(hidden)]
unsafe extern "C" fn unsafe_propagate<T: Propagator>(
control: *mut clingo_propagate_control_t,
changes: *const clingo_literal_t,
size: usize,
propagator: *mut c_void,
) -> bool {
if control.is_null() | (size > 0 && changes.is_null()) | propagator.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_propagate() got a null pointer.");
return false;
}
let control = &mut *(control as *mut PropagateControl);
let changes = std::slice::from_raw_parts(changes as *const Literal, size);
let propagator = &mut *(propagator as *mut T);
propagator.propagate(control, changes)
}
fn undo(&mut self, _control: &mut PropagateControl, _changes: &[Literal]) -> bool {
true
}
#[doc(hidden)]
unsafe extern "C" fn unsafe_undo<T: Propagator>(
control: *const clingo_propagate_control_t,
changes: *const clingo_literal_t,
size: usize,
propagator: *mut c_void,
) -> bool {
if control.is_null() | (size > 0 && changes.is_null()) | propagator.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_undo() got a null pointer.");
return false;
}
let control = &mut *(control as *mut PropagateControl);
let changes = std::slice::from_raw_parts(changes as *const Literal, size);
let propagator = &mut *(propagator as *mut T);
propagator.undo(control, changes)
}
fn check(&mut self, _control: &mut PropagateControl) -> bool {
true
}
#[doc(hidden)]
unsafe extern "C" fn unsafe_check<T: Propagator>(
control: *mut clingo_propagate_control_t,
propagator: *mut c_void,
) -> bool {
if control.is_null() | propagator.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_check() got a null pointer.");
return false;
}
let control = &mut *(control as *mut PropagateControl);
let propagator = &mut *(propagator as *mut T);
propagator.check(control)
}
fn decide(
&mut self,
_thread_id: Id,
_assignment: &Assignment,
_fallback: Literal,
_decision: &mut Literal,
) -> bool {
true
}
#[doc(hidden)]
unsafe extern "C" fn unsafe_decide<T: Propagator>(
thread_id: clingo_id_t,
assignment: *const clingo_assignment_t,
fallback: clingo_literal_t,
propagator: *mut ::std::os::raw::c_void,
decision: *mut clingo_literal_t,
) -> bool {
if assignment.is_null() | propagator.is_null() | decision.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_decide() got a null pointer.");
return false;
}
let assignment = &*(assignment as *const Assignment);
let fallback = Literal(fallback);
let propagator = &mut *(propagator as *mut T);
let decision = &mut *(decision as *mut Literal);
propagator.decide(Id(thread_id), assignment, fallback, decision)
}
}
#[derive(Debug)]
pub struct Control {
ctl: NonNull<clingo_control_t>,
}
impl Drop for Control {
fn drop(&mut self) {
unsafe { clingo_control_free(self.ctl.as_ptr()) }
}
}
impl Control {
pub fn new(arguments: std::vec::Vec<String>) -> Result<Control, ClingoError> {
let logger = None;
let logger_data = std::ptr::null_mut();
let mut args = vec![];
for arg in arguments {
args.push(CString::new(arg)?);
}
let c_args = args
.iter()
.map(|arg| arg.as_ptr())
.collect::<Vec<*const c_char>>();
let mut ctl_ptr = std::ptr::null_mut();
if !unsafe {
clingo_control_new(
c_args.as_ptr(),
c_args.len(),
logger,
logger_data,
0,
&mut ctl_ptr,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_new() failed",
));
}
match NonNull::new(ctl_ptr) {
Some(ctl) => Ok(Control { ctl }),
None => Err(ClingoError::FFIError {
msg: "Tried creating NonNull from a null pointer.",
})?,
}
}
pub fn new_with_logger<L: Logger>(
arguments: Vec<String>,
logger: &mut L,
message_limit: u32,
) -> Result<Control, ClingoError> {
let mut args = vec![];
for arg in arguments {
args.push(CString::new(arg)?);
}
let c_args = args
.iter()
.map(|arg| arg.as_ptr())
.collect::<Vec<*const c_char>>();
let mut ctl_ptr = std::ptr::null_mut();
let logger = logger as *mut L;
if !unsafe {
clingo_control_new(
c_args.as_ptr(),
c_args.len(),
Some(L::unsafe_logging_callback::<L> as LoggingCallback),
logger as *mut c_void,
message_limit,
&mut ctl_ptr,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_new() failed",
));
}
match NonNull::new(ctl_ptr) {
Some(ctl) => Ok(Control { ctl }),
None => Err(ClingoError::FFIError {
msg: "Tried creating NonNull from a null pointer.",
})?,
}
}
pub fn add(
&mut self,
name: &str,
parameters: &[&str],
program: &str,
) -> Result<(), ClingoError> {
let name = CString::new(name)?;
let program = CString::new(program)?;
let program_ptr = program.as_ptr();
let parameters_size = parameters.len();
let mut l_parameters = vec![];
for arg in parameters {
l_parameters.push(CString::new(*arg)?);
}
let c_parameters = l_parameters
.iter()
.map(|arg| arg.as_ptr())
.collect::<Vec<*const c_char>>();
if !unsafe {
clingo_control_add(
self.ctl.as_ptr(),
name.as_ptr(),
c_parameters.as_ptr(),
parameters_size,
program_ptr,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_add() failed",
));
}
Ok(())
}
pub fn add_facts(&mut self, facts: &FactBase) {
for sym in facts.iter() {
let atom = ast::Term::from(*sym);
let lit = ast::Literal::from_term(ast::Sign::None, &atom);
let hlit = ast::HeadLiteral::from(&lit);
let rule = ast::Rule::new(hlit, &[]);
let stm = rule.ast_statement();
let mut builder = ast::ProgramBuilder::from(self).unwrap();
builder
.add(&stm)
.expect("Failed to add statement to ProgramBuilder.");
builder.end().expect("Failed to finish building a program.");
}
}
pub fn ground(&mut self, parts: &[Part]) -> Result<(), ClingoError> {
let parts_size = parts.len();
let parts = parts
.iter()
.map(|arg| arg.from())
.collect::<Vec<clingo_part>>();
if !unsafe {
clingo_control_ground(
self.ctl.as_ptr(),
parts.as_ptr(),
parts_size,
None,
std::ptr::null_mut(),
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_ground() failed",
));
}
Ok(())
}
pub fn ground_with_event_handler<T: ExternalFunctionHandler>(
&mut self,
parts: &[Part],
handler: &mut T,
) -> Result<(), ClingoError> {
let parts_size = parts.len();
let parts = parts
.iter()
.map(|arg| arg.from())
.collect::<Vec<clingo_part>>();
let handler = handler as *mut T;
if !unsafe {
clingo_control_ground(
self.ctl.as_ptr(),
parts.as_ptr(),
parts_size,
Some(T::unsafe_ground_callback::<T> as GroundCallback),
handler as *mut c_void,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_ground() failed",
));
}
Ok(())
}
pub fn solve(
&mut self,
mode: SolveMode,
assumptions: &[Literal],
) -> Result<SolveHandle, ClingoError> {
let mut handle = std::ptr::null_mut();
if !unsafe {
clingo_control_solve(
self.ctl.as_ptr(),
mode.bits(),
assumptions.as_ptr() as *const clingo_literal_t,
assumptions.len(),
None,
std::ptr::null_mut(),
&mut handle,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_solve() failed",
));
}
match unsafe { handle.as_mut() } {
Some(handle_ref) => Ok(SolveHandle { theref: handle_ref }),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut clingo_solve_handle.",
}),
}
}
pub fn all_models(&mut self) -> Result<AllModels, ClingoError> {
let mut handle = std::ptr::null_mut();
if !unsafe {
clingo_control_solve(
self.ctl.as_ptr(),
SolveMode::YIELD.bits(),
std::ptr::null() as *const clingo_literal_t,
0,
None,
std::ptr::null_mut(),
&mut handle,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_solve() failed",
));
}
match unsafe { handle.as_mut() } {
Some(handle_ref) => Ok(AllModels(SolveHandle { theref: handle_ref })),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut clingo_solve_handle.",
}),
}
}
pub fn optimal_models(&mut self) -> Result<OptimalModels, ClingoError> {
let mut handle = std::ptr::null_mut();
if !unsafe {
clingo_control_solve(
self.ctl.as_ptr(),
SolveMode::YIELD.bits(),
std::ptr::null() as *const clingo_literal_t,
0,
None,
std::ptr::null_mut(),
&mut handle,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_solve() failed",
));
}
match unsafe { handle.as_mut() } {
Some(handle_ref) => Ok(OptimalModels(SolveHandle { theref: handle_ref })),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut clingo_solve_handle.",
}),
}
}
pub fn solve_with_event_handler<T: SolveEventHandler>(
&mut self,
mode: SolveMode,
assumptions: &[Literal],
event_handler: &mut T,
) -> Result<SolveHandle, ClingoError> {
let mut handle = std::ptr::null_mut();
let event_handler = event_handler as *mut T;
if !unsafe {
clingo_control_solve(
self.ctl.as_ptr(),
mode.bits(),
assumptions.as_ptr() as *const clingo_literal_t,
assumptions.len(),
Some(T::unsafe_solve_callback::<T> as SolveEventCallback),
event_handler as *mut c_void,
&mut handle,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_solve() failed",
));
}
match unsafe { handle.as_mut() } {
Some(handle_ref) => Ok(SolveHandle { theref: handle_ref }),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut clingo_solve_handle.",
}),
}
}
pub fn cleanup(&mut self) -> Result<(), ClingoError> {
if !unsafe { clingo_control_cleanup(self.ctl.as_ptr()) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_cleanup() failed",
));
}
Ok(())
}
pub fn assign_external(
&mut self,
literal: Literal,
value: TruthValue,
) -> Result<(), ClingoError> {
if !unsafe {
clingo_control_assign_external(
self.ctl.as_ptr(),
literal.0,
value as clingo_truth_value_t,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_assign_external() failed",
));
}
Ok(())
}
pub fn release_external(&mut self, Literal(literal): Literal) -> Result<(), ClingoError> {
if !unsafe { clingo_control_release_external(self.ctl.as_ptr(), literal) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_release_external() failed",
));
}
Ok(())
}
pub fn register_propagator<T: Propagator>(
&mut self,
propagator: &mut T,
sequential: bool,
) -> Result<(), ClingoError> {
let propagator = propagator as *mut T;
let clingo_propagator = clingo_propagator_t {
init: Some(T::unsafe_init::<T>),
propagate: Some(T::unsafe_propagate::<T>),
undo: Some(T::unsafe_undo::<T>),
check: Some(T::unsafe_check::<T>),
decide: Some(T::unsafe_decide::<T>),
};
if !unsafe {
clingo_control_register_propagator(
self.ctl.as_ptr(),
&clingo_propagator,
propagator as *mut c_void,
sequential,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_control_register_propagator() failed",
));
}
Ok(())
}
pub fn clingo_control_is_conflicting(&self) -> bool {
unsafe { clingo_control_is_conflicting(self.ctl.as_ptr()) }
}
pub fn statistics<'a>(&'a self) -> Result<&'a Statistics, ClingoError> {
let mut stat = std::ptr::null();
if !unsafe { clingo_control_statistics(self.ctl.as_ptr(), &mut stat) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_statistics() failed",
));
}
match unsafe { (stat as *mut Statistics).as_ref() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &Statistics.",
}),
}
}
pub fn interrupt(&mut self) {
unsafe {
clingo_control_interrupt(self.ctl.as_ptr());
}
}
pub fn configuration_mut<'a>(&'a mut self) -> Result<&'a mut Configuration, ClingoError> {
let mut conf = std::ptr::null_mut();
if !unsafe { clingo_control_configuration(self.ctl.as_ptr(), &mut conf) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_configuration() failed",
));
}
match unsafe { (conf as *mut Configuration).as_mut() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut Configuration.",
}),
}
}
pub fn configuration<'a>(&'a self) -> Result<&'a Configuration, ClingoError> {
let mut conf = std::ptr::null_mut();
if !unsafe { clingo_control_configuration(self.ctl.as_ptr(), &mut conf) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_configuration() failed",
));
}
match unsafe { (conf as *const Configuration).as_ref() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &Configuration.",
}),
}
}
pub fn use_enumeration_assumption(&mut self, enable: bool) -> Result<(), ClingoError> {
if !unsafe { clingo_control_use_enumeration_assumption(self.ctl.as_ptr(), enable) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_use_enumeration_assumption() failed",
));
}
Ok(())
}
pub fn get_const(&self, name: &str) -> Result<Symbol, ClingoError> {
let name = CString::new(name)?;
let mut symbol = 0 as clingo_symbol_t;
if !unsafe { clingo_control_get_const(self.ctl.as_ptr(), name.as_ptr(), &mut symbol) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_get_const() failed",
));
}
Ok(Symbol(symbol))
}
pub fn has_const(&self, name: &str) -> Result<bool, ClingoError> {
let name = CString::new(name)?;
let mut exist = false;
if !unsafe { clingo_control_has_const(self.ctl.as_ptr(), name.as_ptr(), &mut exist) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_has_const() failed",
));
}
Ok(exist)
}
pub fn symbolic_atoms<'a>(&self) -> Result<&'a SymbolicAtoms, ClingoError> {
let mut atoms = std::ptr::null();
if !unsafe { clingo_control_symbolic_atoms(self.ctl.as_ptr(), &mut atoms) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_symbolic_atoms() failed",
));
}
match unsafe { (atoms as *const SymbolicAtoms).as_ref() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &SymbolicAtoms.",
}),
}
}
pub fn theory_atoms<'a>(&'a self) -> Result<&'a TheoryAtoms, ClingoError> {
let mut atoms = std::ptr::null();
if !unsafe { clingo_control_theory_atoms(self.ctl.as_ptr(), &mut atoms) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_theory_atoms() failed",
));
}
match unsafe { (atoms as *const TheoryAtoms).as_ref() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &TheoryAtoms.",
}),
}
}
pub fn register_observer<T: GroundProgramObserver>(
&mut self,
observer: &mut T,
replace: bool,
) -> bool {
let observer = observer as *mut T;
let gpo = clingo_ground_program_observer_t {
init_program: Some(T::unsafe_init_program::<T>),
begin_step: Some(T::unsafe_begin_step::<T>),
end_step: Some(T::unsafe_end_step::<T>),
rule: Some(T::unsafe_rule::<T>),
weight_rule: Some(T::unsafe_weight_rule::<T>),
minimize: Some(T::unsafe_minimize::<T>),
project: Some(T::unsafe_project::<T>),
output_atom: Some(T::unsafe_output_atom::<T>),
output_term: Some(T::unsafe_output_term::<T>),
output_csp: Some(T::unsafe_output_csp::<T>),
external: Some(T::unsafe_external::<T>),
assume: Some(T::unsafe_assume::<T>),
heuristic: Some(T::unsafe_heuristic::<T>),
acyc_edge: Some(T::unsafe_acyc_edge::<T>),
theory_term_number: Some(T::unsafe_theory_term_number::<T>),
theory_term_string: Some(T::unsafe_theory_term_string::<T>),
theory_term_compound: Some(T::unsafe_theory_term_compound::<T>),
theory_element: Some(T::unsafe_theory_element::<T>),
theory_atom: Some(T::unsafe_theory_atom::<T>),
theory_atom_with_guard: Some(T::unsafe_theory_atom_with_guard::<T>),
};
unsafe {
clingo_control_register_observer(
self.ctl.as_ptr(),
&gpo,
replace,
observer as *mut c_void,
)
}
}
pub fn backend<'a>(&'a mut self) -> Result<Backend<'a>, ClingoError> {
let mut backend = std::ptr::null_mut();
if !unsafe { clingo_control_backend(self.ctl.as_ptr(), &mut backend) } {
return Err(ClingoError::new_internal(
"Call to clingo_control_backend() failed",
));
}
if !unsafe { clingo_backend_begin(backend) } {
return Err(ClingoError::new_internal(
"Call to clingo_backend_begin() failed",
));
}
match unsafe { backend.as_mut() } {
Some(backend_ref) => Ok(Backend {
theref: backend_ref,
}),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut clingo_backend.",
}),
}
}
}
#[derive(Debug)]
pub struct Configuration(clingo_configuration_t);
impl Configuration {
pub fn root(&self) -> Result<Id, ClingoError> {
let mut root_key = 0 as clingo_id_t;
if !unsafe { clingo_configuration_root(&self.0, &mut root_key) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_root() failed",
));
}
Ok(Id(root_key))
}
pub fn configuration_type(&self, Id(key): Id) -> Result<ConfigurationType, ClingoError> {
let mut ctype = 0 as clingo_configuration_type_bitset_t;
if !unsafe { clingo_configuration_type(&self.0, key, &mut ctype) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_type() failed",
));
}
match ConfigurationType::from_bits(ctype) {
Some(x) => Ok(x),
None => {
eprintln!(
"Failed to match to clingo_configuration_type_bitset_t {}.",
ctype
);
Err(ClingoError::FFIError {
msg: "Failed to match to clingo_configuration_type_bitset_t.",
})
}
}
}
pub fn description<'a>(&'a self, Id(key): Id) -> Result<&'a str, ClingoError> {
let mut description_ptr = std::ptr::null();
if !unsafe { clingo_configuration_description(&self.0, key, &mut description_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_description() failed",
));
}
if description_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_configuration_description() returned a null pointer.",
});
}
let cstr = unsafe { CStr::from_ptr(description_ptr) };
Ok(cstr.to_str()?)
}
pub fn array_size(&self, Id(key): Id) -> Result<usize, ClingoError> {
let mut size = 0;
if !unsafe { clingo_configuration_array_size(&self.0, key, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_array_size() failed",
));
}
Ok(size)
}
pub fn array_at(&self, Id(key): Id, offset: usize) -> Result<Id, ClingoError> {
let mut nkey = 0 as clingo_id_t;
if !unsafe { clingo_configuration_array_at(&self.0, key, offset, &mut nkey) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_array_at() failed",
));
}
Ok(Id(nkey))
}
pub fn map_size(&self, Id(key): Id) -> Result<usize, ClingoError> {
let mut size = 0;
if !unsafe { clingo_configuration_map_size(&self.0, key, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_map_size() failed",
));
}
Ok(size)
}
pub fn map_has_subkey(&self, Id(key): Id, name: &str) -> Result<bool, ClingoError> {
let mut result = false;
let name = CString::new(name)?;
if !unsafe { clingo_configuration_map_has_subkey(&self.0, key, name.as_ptr(), &mut result) }
{
return Err(ClingoError::new_internal(
"Call to clingo_configuration_map_has_subkey() failed",
));
}
Ok(result)
}
pub fn map_subkey_name<'a>(
&'a self,
Id(key): Id,
offset: usize,
) -> Result<&'a str, ClingoError> {
let mut name_ptr = std::ptr::null();
if !unsafe { clingo_configuration_map_subkey_name(&self.0, key, offset, &mut name_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_map_subkey_name() failed",
));
}
if name_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_configuration_map_subkey_name() returned a null pointer.",
});
}
let cstr = unsafe { CStr::from_ptr(name_ptr) };
Ok(cstr.to_str()?)
}
pub fn map_at(&self, Id(key): Id, name: &str) -> Result<Id, ClingoError> {
let mut nkey = 0 as clingo_id_t;
let name = CString::new(name)?;
if !unsafe { clingo_configuration_map_at(&self.0, key, name.as_ptr(), &mut nkey) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_value_is_assigned() failed",
));
}
Ok(Id(nkey))
}
pub fn value_is_assigned(&self, Id(key): Id) -> Result<bool, ClingoError> {
let mut assigned = false;
if !unsafe { clingo_configuration_value_is_assigned(&self.0, key, &mut assigned) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_value_is_assigned() failed",
));
}
Ok(assigned)
}
pub fn value_get<'a>(&'a self, Id(key): Id) -> Result<String, ClingoError> {
let mut size = 0;
if !unsafe { clingo_configuration_value_get_size(&self.0, key, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_value_get_size() failed",
));
}
let mut string = Vec::with_capacity(size);
let string_ptr = string.as_mut_ptr();
if !unsafe { clingo_configuration_value_get(&self.0, key, string_ptr, size) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_value_get() failed",
));
}
let c_str: &CStr = unsafe { CStr::from_ptr(string_ptr) };
let str_slice: &str = c_str.to_str()?;
Ok(str_slice.to_owned())
}
pub fn value_set(&mut self, Id(key): Id, value: &str) -> Result<(), ClingoError> {
let value = CString::new(value)?;
if !unsafe { clingo_configuration_value_set(&mut self.0, key, value.as_ptr()) } {
return Err(ClingoError::new_internal(
"Call to clingo_configuration_value_set() failed",
));
}
Ok(())
}
}
#[derive(Debug)]
pub struct Backend<'a> {
theref: &'a mut clingo_backend_t,
}
impl<'a> Drop for Backend<'a> {
fn drop(&mut self) {
if !unsafe { clingo_backend_end(self.theref) } {
panic!("Call to clingo_backend_end() failed");
}
}
}
impl<'a> Backend<'a> {
pub fn rule(
&mut self,
choice: bool,
head: &[Atom],
body: &[Literal],
) -> Result<(), ClingoError> {
if !unsafe {
clingo_backend_rule(
self.theref,
choice,
head.as_ptr() as *const clingo_atom_t,
head.len(),
body.as_ptr() as *const clingo_literal_t,
body.len(),
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_backend_rule() failed",
));
}
Ok(())
}
pub fn weight_rule(
&mut self,
choice: bool,
head: &[Atom],
lower_bound: i32,
body: &[WeightedLiteral],
) -> Result<(), ClingoError> {
if !unsafe {
clingo_backend_weight_rule(
self.theref,
choice,
head.as_ptr() as *const clingo_atom_t,
head.len(),
lower_bound,
body.as_ptr() as *const clingo_weighted_literal_t,
body.len(),
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_backend_weight_rule() failed",
));
}
Ok(())
}
pub fn minimize(
&mut self,
priority: i32,
literals: &[WeightedLiteral],
) -> Result<(), ClingoError> {
if !unsafe {
clingo_backend_minimize(
self.theref,
priority,
literals.as_ptr() as *const clingo_weighted_literal_t,
literals.len(),
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_backend_minimize() failed",
));
}
Ok(())
}
pub fn project(&mut self, atoms: &[Atom]) -> Result<(), ClingoError> {
if !unsafe {
clingo_backend_project(
self.theref,
atoms.as_ptr() as *const clingo_atom_t,
atoms.len(),
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_backend_project() failed",
));
}
Ok(())
}
pub fn external(&mut self, atom: Atom, type_: ExternalType) -> Result<(), ClingoError> {
if !unsafe { clingo_backend_external(self.theref, atom.0, type_ as clingo_external_type_t) }
{
return Err(ClingoError::new_internal(
"Call to clingo_backend_external() failed",
));
}
Ok(())
}
pub fn assume(&mut self, literals: &[Literal]) -> Result<(), ClingoError> {
let size = literals.len();
if !unsafe {
clingo_backend_assume(
self.theref,
literals.as_ptr() as *const clingo_literal_t,
size,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_backend_assume() failed",
));
}
Ok(())
}
pub fn heuristic(
&mut self,
atom: Atom,
htype: HeuristicType,
bias: i32,
priority: u32,
condition: &[Literal],
) -> Result<(), ClingoError> {
let size = condition.len();
if !unsafe {
clingo_backend_heuristic(
self.theref,
atom.0,
htype as clingo_heuristic_type_t,
bias,
priority,
condition.as_ptr() as *const clingo_literal_t,
size,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_backend_heuristic() failed",
));
}
Ok(())
}
pub fn acyc_edge(
&mut self,
node_u: i32,
node_v: i32,
condition: &[Literal],
) -> Result<(), ClingoError> {
let size = condition.len();
if !unsafe {
clingo_backend_acyc_edge(
self.theref,
node_u,
node_v,
condition.as_ptr() as *const clingo_literal_t,
size,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_backend_acyc_edge() failed",
));
}
Ok(())
}
pub fn add_atom(&mut self, symbol: Option<Symbol>) -> Result<Atom, ClingoError> {
match symbol {
Some(Symbol(mut symbol)) => {
let mut atom = 0 as clingo_atom_t;
if unsafe { clingo_backend_add_atom(self.theref, &mut symbol, &mut atom) } {
Ok(Atom(atom))
} else {
Err(ClingoError::new_internal(
"Call to clingo_backend_add_atom() failed",
))
}
}
None => {
let mut atom = 0 as clingo_atom_t;
let null = std::ptr::null_mut();
if unsafe { clingo_backend_add_atom(self.theref, null, &mut atom) } {
Ok(Atom(atom))
} else {
Err(ClingoError::new_internal(
"Call to clingo_backend_add_atom() failed",
))
}
}
}
}
}
#[derive(Debug)]
pub struct Statistics(clingo_statistics_t);
impl Statistics {
pub fn root(&self) -> Result<u64, ClingoError> {
let mut root_key = 0 as u64;
if !unsafe { clingo_statistics_root(&self.0, &mut root_key) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_root() failed",
));
}
Ok(root_key)
}
pub fn statistics_type(&self, key: u64) -> Result<StatisticsType, ClingoError> {
let mut stype = 0 as clingo_statistics_type_t;
if !unsafe { clingo_statistics_type(&self.0, key, &mut stype) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_type() failed",
));
}
StatisticsType::try_from(stype)
}
pub fn array_size(&self, key: u64) -> Result<usize, ClingoError> {
let mut size = 0 as usize;
if !unsafe { clingo_statistics_array_size(&self.0, key, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_array_size() failed",
));
}
Ok(size)
}
pub fn array_at(&self, key: u64, offset: usize) -> Result<u64, ClingoError> {
let mut subkey = 0 as u64;
if !unsafe { clingo_statistics_array_at(&self.0, key, offset, &mut subkey) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_array_at() failed",
));
}
Ok(subkey)
}
pub fn array_push(&mut self, key: u64, stype: StatisticsType) -> Result<u64, ClingoError> {
let mut subkey = 0 as u64;
if !unsafe {
clingo_statistics_array_push(
&mut self.0,
key,
stype as clingo_statistics_type_t,
&mut subkey,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_array_push() failed",
));
}
Ok(subkey)
}
pub fn map_size(&self, key: u64) -> Result<usize, ClingoError> {
let mut size = 0 as usize;
if !unsafe { clingo_statistics_map_size(&self.0, key, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_map_size() failed",
));
}
Ok(size)
}
pub fn map_has_subkey(&self, key: u64, name: &str) -> Result<bool, ClingoError> {
let mut result = false;
let name = CString::new(name)?;
if !unsafe { clingo_statistics_map_has_subkey(&self.0, key, name.as_ptr(), &mut result) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_map_has_subkey() failed",
));
}
Ok(result)
}
pub fn map_subkey_name<'a>(&'a self, key: u64, offset: usize) -> Result<&'a str, ClingoError> {
let mut name = std::ptr::null();
if !unsafe { clingo_statistics_map_subkey_name(&self.0, key, offset, &mut name) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_map_subkey_name() failed",
));
}
if name.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_statistics_map_subkey_name() returned a null pointer.",
});
}
Ok(unsafe { CStr::from_ptr(name) }.to_str()?)
}
pub fn map_at(&self, key: u64, name: &str) -> Result<u64, ClingoError> {
let mut subkey = 0 as u64;
let name = CString::new(name)?;
if !unsafe { clingo_statistics_map_at(&self.0, key, name.as_ptr(), &mut subkey) } {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_map_at() failed",
));
}
Ok(subkey)
}
pub fn map_add_subkey(
&mut self,
key: u64,
name: &str,
stype: StatisticsType,
) -> Result<u64, ClingoError> {
let mut subkey = 0 as u64;
let name = CString::new(name)?;
if !unsafe {
clingo_statistics_map_add_subkey(
&mut self.0,
key,
name.as_ptr(),
stype as clingo_statistics_type_t,
&mut subkey,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_statistics_map_add_subkey() failed",
));
}
Ok(subkey)
}
pub fn value_get(&self, key: u64) -> Result<f64, ClingoError> {
let mut value = 0.0 as f64;
if !unsafe { clingo_statistics_value_get(&self.0, key, &mut value) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_size() failed",
));
}
Ok(value)
}
pub fn value_set(&mut self, key: u64, value: f64) -> bool {
unsafe { clingo_statistics_value_set(&mut self.0, key, value) }
}
}
#[derive(Debug)]
pub struct SymbolicAtoms(clingo_symbolic_atoms_t);
impl SymbolicAtoms {
pub fn size(&self) -> Result<usize, ClingoError> {
let mut size = 0 as usize;
if !unsafe { clingo_symbolic_atoms_size(&self.0, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_size() failed",
));
}
Ok(size)
}
pub fn iter(&self) -> Result<SymbolicAtomsIterator, ClingoError> {
let mut begin = 0 as clingo_symbolic_atom_iterator_t;
if !unsafe { clingo_symbolic_atoms_begin(&self.0, std::ptr::null(), &mut begin) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_begin() failed",
));
}
let mut end = 0 as clingo_symbolic_atom_iterator_t;
if !unsafe { clingo_symbolic_atoms_end(&self.0, &mut end) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_end() failed",
));
}
Ok(SymbolicAtomsIterator {
cur: begin,
end,
atoms: &self.0,
})
}
pub fn iter_with_signature(
&self,
sig: &Signature,
) -> Result<SymbolicAtomsIterator, ClingoError> {
let mut begin = 0 as clingo_symbolic_atom_iterator_t;
if !unsafe { clingo_symbolic_atoms_begin(&self.0, &sig.0, &mut begin) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_begin() failed",
));
}
let mut end = 0 as clingo_symbolic_atom_iterator_t;
if !unsafe { clingo_symbolic_atoms_end(&self.0, &mut end) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_end() failed",
));
}
Ok(SymbolicAtomsIterator {
cur: begin,
end,
atoms: &self.0,
})
}
pub fn signatures(&self) -> Result<Vec<Signature>, ClingoError> {
let mut size = 0;
if !unsafe { clingo_symbolic_atoms_signatures_size(&self.0, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_signatures_size() failed",
));
}
let mut signatures = vec![Signature(0); size];
if !unsafe {
clingo_symbolic_atoms_signatures(
&self.0,
signatures.as_mut_ptr() as *mut clingo_signature_t,
size,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_signatures() failed",
));
}
Ok(signatures)
}
}
pub struct SymbolicAtomsIterator<'a> {
cur: clingo_symbolic_atom_iterator_t,
end: clingo_symbolic_atom_iterator_t,
atoms: &'a clingo_symbolic_atoms_t,
}
impl<'a> Iterator for SymbolicAtomsIterator<'a> {
type Item = SymbolicAtom<'a>;
fn next(&mut self) -> Option<SymbolicAtom<'a>> {
let mut equal = false;
if !unsafe {
clingo_symbolic_atoms_iterator_is_equal_to(self.atoms, self.cur, self.end, &mut equal)
} {
return None;
}
if equal {
return None;
}
let ret = SymbolicAtom {
cur: self.cur,
atoms: self.atoms,
};
if !unsafe { clingo_symbolic_atoms_next(self.atoms, self.cur, &mut self.cur) } {
panic!(
"Call clingo_symbolic_atoms_next() failed {}{}{}.",
file!(),
line!(),
column!()
);
}
Some(ret)
}
}
pub struct SymbolicAtom<'a> {
cur: clingo_symbolic_atom_iterator_t,
atoms: &'a clingo_symbolic_atoms_t,
}
impl<'a> SymbolicAtom<'a> {
pub fn is_fact(&self) -> Result<bool, ClingoError> {
let mut fact = false;
if !unsafe { clingo_symbolic_atoms_is_fact(self.atoms, self.cur, &mut fact) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_is_fact() failed",
));
}
Ok(fact)
}
pub fn is_external(&self) -> Result<bool, ClingoError> {
let mut external = false;
if !unsafe { clingo_symbolic_atoms_is_external(self.atoms, self.cur, &mut external) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_is_external() failed",
));
}
Ok(external)
}
pub fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut symbol = 0 as clingo_symbol_t;
if !unsafe { clingo_symbolic_atoms_symbol(self.atoms, self.cur, &mut symbol) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_symbol() failed",
));
}
Ok(Symbol(symbol))
}
pub fn literal(&self) -> Result<Literal, ClingoError> {
let mut literal = 0 as clingo_literal_t;
if !unsafe { clingo_symbolic_atoms_literal(self.atoms, self.cur, &mut literal) } {
return Err(ClingoError::new_internal(
"Call to clingo_symbolic_atoms_literal() failed",
));
}
Ok(Literal(literal))
}
}
#[derive(Debug)]
pub struct TheoryAtoms(clingo_theory_atoms_t);
impl TheoryAtoms {
pub fn size(&self) -> Result<usize, ClingoError> {
let mut size = 0 as usize;
if !unsafe { clingo_theory_atoms_size(&self.0, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_size() failed",
));
}
Ok(size)
}
pub fn iter(&self) -> TheoryAtomsIterator {
TheoryAtomsIterator {
count: 0,
atoms: &self,
}
}
pub fn term_type(&self, Id(term): Id) -> Result<TheoryTermType, ClingoError> {
let mut ttype = 0 as clingo_theory_term_type_t;
if !unsafe { clingo_theory_atoms_term_type(&self.0, term, &mut ttype) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_term_type() failed",
));
}
TheoryTermType::try_from(ttype)
}
pub fn term_number(&self, Id(term): Id) -> Result<i32, ClingoError> {
let mut number = 0;
if !unsafe { clingo_theory_atoms_term_number(&self.0, term, &mut number) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_term_number() failed",
));
}
Ok(number)
}
pub fn term_name<'a>(&self, Id(term): Id) -> Result<&'a str, ClingoError> {
let mut char_ptr = std::ptr::null();
if !unsafe { clingo_theory_atoms_term_name(&self.0, term, &mut char_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_term_name() failed",
));
}
if char_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_theory_atoms_term_name() returned a null pointer.",
});
}
let c_str = unsafe { CStr::from_ptr(char_ptr) };
Ok(c_str.to_str()?)
}
pub fn term_arguments<'a>(&'a self, Id(term): Id) -> Result<&'a [Id], ClingoError> {
let mut size = 0;
let mut c_ptr = std::ptr::null();
if !unsafe { clingo_theory_atoms_term_arguments(&self.0, term, &mut c_ptr, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_term_arguments() failed",
));
}
let arguments_ref = unsafe { std::slice::from_raw_parts(c_ptr as *const Id, size) };
Ok(arguments_ref)
}
pub fn term_to_string(&self, Id(term): Id) -> Result<String, ClingoError> {
let mut size = 0;
if !unsafe { clingo_theory_atoms_term_to_string_size(&self.0, term, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_term_to_string_size() failed",
));
}
let mut string = Vec::with_capacity(size);
let string_ptr = string.as_mut_ptr();
if !unsafe { clingo_theory_atoms_term_to_string(&self.0, term, string_ptr, size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_term_to_string() failed",
));
}
let c_str: &CStr = unsafe { CStr::from_ptr(string_ptr) };
let str_slice: &str = c_str.to_str()?;
Ok(str_slice.to_owned())
}
pub fn element_tuple(&self, Id(element): Id) -> Result<&[Id], ClingoError> {
let mut size = 0;
let mut tuple_ptr = std::ptr::null();
if !unsafe {
clingo_theory_atoms_element_tuple(&self.0, element, &mut tuple_ptr, &mut size)
} {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_element_tuple() failed",
));
}
let tuple_ref = unsafe { std::slice::from_raw_parts(tuple_ptr as *const Id, size) };
Ok(tuple_ref)
}
pub fn element_condition(&self, Id(element): Id) -> Result<&[Literal], ClingoError> {
let mut size = 0;
let mut condition_ptr = std::ptr::null();
if !unsafe {
clingo_theory_atoms_element_condition(&self.0, element, &mut condition_ptr, &mut size)
} {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_element_condition() failed",
));
}
let condition_ref =
unsafe { std::slice::from_raw_parts(condition_ptr as *const Literal, size) };
Ok(condition_ref)
}
pub fn element_condition_id(&self, Id(element): Id) -> Result<Literal, ClingoError> {
let condition_ptr = std::ptr::null_mut();
if !unsafe { clingo_theory_atoms_element_condition_id(&self.0, element, condition_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_element_condition_id() failed",
));
}
if condition_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_theory_atoms_element_condition_id() returned a null pointer.",
});
}
Ok(Literal(unsafe { *condition_ptr }))
}
pub fn element_to_string(&self, Id(element): Id) -> Result<String, ClingoError> {
let mut size = 0;
if !unsafe { clingo_theory_atoms_element_to_string_size(&self.0, element, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_element_to_string_size() failed",
));
}
let mut string = Vec::with_capacity(size);
let string_ptr = string.as_mut_ptr();
if !unsafe { clingo_theory_atoms_element_to_string(&self.0, element, string_ptr, size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_element_to_string() failed",
));
}
let c_str: &CStr = unsafe { CStr::from_ptr(string_ptr) };
let str_slice: &str = c_str.to_str()?;
Ok(str_slice.to_owned())
}
pub fn atom_term(&self, Id(atom): Id) -> Result<Id, ClingoError> {
let mut term = 0 as clingo_id_t;
if !unsafe { clingo_theory_atoms_atom_term(&self.0, atom, &mut term) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_atom_term() failed",
));
}
Ok(Id(term))
}
pub fn atom_elements(&self, Id(atom): Id) -> Result<&[Id], ClingoError> {
let mut size = 0;
let mut elements_ptr = std::ptr::null() as *const clingo_id_t;
if !unsafe {
clingo_theory_atoms_atom_elements(&self.0, atom, &mut elements_ptr, &mut size)
} {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_atom_elements() failed",
));
}
let elements = unsafe { std::slice::from_raw_parts(elements_ptr as *const Id, size) };
Ok(elements)
}
pub fn atom_has_guard(&self, Id(atom): Id) -> Result<bool, ClingoError> {
let mut has_guard = false;
if !unsafe { clingo_theory_atoms_atom_has_guard(&self.0, atom, &mut has_guard) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_atom_has_guard() failed",
));
}
Ok(has_guard)
}
pub fn atom_guard(&self, Id(atom): Id) -> Result<(&str, Id), ClingoError> {
let mut c_ptr = std::ptr::null() as *const c_char;
let mut term = 0 as clingo_id_t;
if !unsafe { clingo_theory_atoms_atom_guard(&self.0, atom, &mut c_ptr, &mut term) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_atom_guard() failed",
));
}
if c_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_theory_atoms_atom_guard() returned a null pointer.",
});
}
let cstr = unsafe { CStr::from_ptr(c_ptr) };
Ok((cstr.to_str()?, Id(term)))
}
pub fn atom_literal(&self, Id(atom): Id) -> Result<Literal, ClingoError> {
let mut literal = 0 as clingo_literal_t;
if !unsafe { clingo_theory_atoms_atom_literal(&self.0, atom, &mut literal) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_atom_literal() failed",
));
}
Ok(Literal(literal))
}
pub fn atom_to_string(&self, Id(atom): Id) -> Result<String, ClingoError> {
let mut size = 0;
if !unsafe { clingo_theory_atoms_atom_to_string_size(&self.0, atom, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_atom_to_string_size() failed",
));
}
let mut string = Vec::with_capacity(size);
let string_ptr = string.as_mut_ptr();
if !unsafe { clingo_theory_atoms_atom_to_string(&self.0, atom, string_ptr, size) } {
return Err(ClingoError::new_internal(
"Call to clingo_theory_atoms_atom_to_string() failed",
));
}
let c_str: &CStr = unsafe { CStr::from_ptr(string_ptr) };
let str_slice: &str = c_str.to_str()?;
Ok(str_slice.to_owned())
}
}
pub struct TheoryAtomsIterator<'a> {
count: usize,
atoms: &'a TheoryAtoms,
}
impl<'a> Iterator for TheoryAtomsIterator<'a> {
type Item = Id;
fn next(&mut self) -> Option<Id> {
if self.count < self.atoms.size().unwrap() {
let ret = Id(self.count as clingo_id_t);
self.count += 1;
Some(ret)
} else {
None
}
}
}
#[derive(Debug)]
pub struct Model(clingo_model_t);
impl Model {
pub fn model_type(&self) -> Result<ModelType, ClingoError> {
let mut mtype = 0 as clingo_model_type_t;
if !unsafe { clingo_model_type(&self.0, &mut mtype) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_type() failed",
));
}
ModelType::try_from(mtype)
}
pub fn number(&self) -> Result<u64, ClingoError> {
let mut number = 0;
if !unsafe { clingo_model_number(&self.0, &mut number) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_number() failed",
));
}
Ok(number)
}
pub fn symbols(&self, show: ShowType) -> Result<Vec<Symbol>, ClingoError> {
let mut size: usize = 0;
if !unsafe { clingo_model_symbols_size(&self.0, show.bits(), &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_symbols_size() failed",
));
}
let symbols = vec![Symbol(0); size];
if !unsafe {
clingo_model_symbols(
&self.0,
show.bits(),
symbols.as_ptr() as *mut clingo_symbol_t,
size,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_model_symbols() failed",
));
}
Ok(symbols)
}
pub fn contains(&self, Symbol(atom): Symbol) -> Result<bool, ClingoError> {
let mut contained = false;
if !unsafe { clingo_model_contains(&self.0, atom, &mut contained) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_contains() failed",
));
}
Ok(contained)
}
pub fn is_true(&self, literal: Literal) -> Result<bool, ClingoError> {
let mut is_true = false;
if !unsafe { clingo_model_is_true(&self.0, literal.0, &mut is_true) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_is_true() failed",
));
}
Ok(is_true)
}
pub fn cost(&self) -> Result<Vec<i64>, ClingoError> {
let mut size: usize = 0;
if !unsafe { clingo_model_cost_size(&self.0, &mut size) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_cost_size() failed",
));
}
let mut cost = vec![0; size];
if !unsafe { clingo_model_cost(&self.0, cost.as_mut_ptr(), size) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_cost() failed",
));
}
Ok(cost)
}
pub fn optimality_proven(&self) -> Result<bool, ClingoError> {
let mut proven = false;
if !unsafe { clingo_model_optimality_proven(&self.0, &mut proven) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_optimality_proven() failed",
));
}
Ok(proven)
}
pub fn thread_id(&self) -> Result<Id, ClingoError> {
let mut id = 0 as clingo_id_t;
if !unsafe { clingo_model_thread_id(&self.0, &mut id) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_thread_id() failed",
));
}
Ok(Id(id))
}
pub fn extend(&mut self, symbols: &[Symbol]) -> bool {
unsafe {
clingo_model_extend(
&mut self.0,
symbols.as_ptr() as *const clingo_symbol_t,
symbols.len(),
)
}
}
pub fn context<'a>(&'a self) -> Result<&'a mut SolveControl, ClingoError> {
let control_ptr = std::ptr::null_mut();
if !unsafe { clingo_model_context(&self.0, control_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_model_context() failed",
));
}
if control_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_model_context() returned a null pointer.",
});
}
unsafe { Ok(&mut *(control_ptr as *mut SolveControl)) }
}
}
#[derive(Debug)]
pub struct SolveControl(clingo_solve_control_t);
impl SolveControl {
pub fn add_clause(&mut self, clause: &[Literal]) -> Result<(), ClingoError> {
if !unsafe {
clingo_solve_control_add_clause(
&mut self.0,
clause.as_ptr() as *const clingo_literal_t,
clause.len(),
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_solve_control_add_clause() failed",
));
}
Ok(())
}
pub fn symbolic_atoms(&self) -> Result<&SymbolicAtoms, ClingoError> {
let mut atoms = std::ptr::null() as *const clingo_symbolic_atoms_t;
if !unsafe { clingo_solve_control_symbolic_atoms(&self.0, &mut atoms) } {
return Err(ClingoError::new_internal(
"Call to clingo_assignment_level() failed",
));
}
match unsafe { (atoms as *const SymbolicAtoms).as_ref() } {
Some(stm) => Ok(stm),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &SymbolicAtoms.",
}),
}
}
}
#[derive(Debug)]
pub struct Assignment(clingo_assignment_t);
impl Assignment {
pub fn decision_level(&self) -> u32 {
unsafe { clingo_assignment_decision_level(&self.0) }
}
pub fn root_level(&self) -> u32 {
unsafe { clingo_assignment_root_level(&self.0) }
}
pub fn has_conflict(&self) -> bool {
unsafe { clingo_assignment_has_conflict(&self.0) }
}
pub fn has_literal(&self, literal: Literal) -> bool {
unsafe { clingo_assignment_has_literal(&self.0, literal.0) }
}
pub fn level(&self, literal: Literal) -> Result<u32, ClingoError> {
let mut level = 0;
if !unsafe { clingo_assignment_level(&self.0, literal.0, &mut level) } {
return Err(ClingoError::new_internal(
"Call to clingo_assignment_level() failed",
));
}
Ok(level)
}
pub fn decision(&self, level: u32) -> Result<Literal, ClingoError> {
let mut lit = 0 as clingo_literal_t;
if !unsafe { clingo_assignment_decision(&self.0, level, &mut lit) } {
return Err(ClingoError::new_internal(
"Call to clingo_assignment_decision() failed",
));
}
Ok(Literal(lit))
}
pub fn is_fixed(&self, literal: Literal) -> Result<bool, ClingoError> {
let mut is_fixed = false;
if !unsafe { clingo_assignment_is_fixed(&self.0, literal.0, &mut is_fixed) } {
return Err(ClingoError::new_internal(
"Call to clingo_assignment_is_fixed() failed",
));
}
Ok(is_fixed)
}
pub fn is_true(&self, literal: Literal) -> Result<bool, ClingoError> {
let mut is_true = false;
if !unsafe { clingo_assignment_is_true(&self.0, literal.0, &mut is_true) } {
return Err(ClingoError::new_internal(
"Call to clingo_assignment_is_true() failed",
));
}
Ok(is_true)
}
pub fn is_false(&self, literal: Literal) -> Result<bool, ClingoError> {
let mut is_false = false;
if !unsafe { clingo_assignment_is_false(&self.0, literal.0, &mut is_false) } {
return Err(ClingoError::new_internal(
"Call to clingo_assignment_is_false() failed",
));
}
Ok(is_false)
}
pub fn truth_value(&self, literal: Literal) -> Result<TruthValue, ClingoError> {
let mut value = 0;
if !unsafe { clingo_assignment_truth_value(&self.0, literal.0, &mut value) } {
return Err(ClingoError::new_internal(
"Call to clingo_assignment_truth_value() failed",
));
}
TruthValue::try_from(value)
}
pub fn size(&self) -> usize {
unsafe { clingo_assignment_size(&self.0) }
}
pub fn max_size(&self) -> usize {
unsafe { clingo_assignment_max_size(&self.0) }
}
pub fn is_total(&self) -> bool {
unsafe { clingo_assignment_is_total(&self.0) }
}
}
#[derive(Debug)]
pub struct PropagateControl(clingo_propagate_control_t);
impl PropagateControl {
pub fn thread_id(&self) -> u32 {
unsafe { clingo_propagate_control_thread_id(&self.0) }
}
pub fn assignment(&self) -> Result<&Assignment, ClingoError> {
match unsafe {
(clingo_propagate_control_assignment(&self.0) as *const Assignment).as_ref()
} {
Some(stm) => Ok(stm),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &Assignment.",
}),
}
}
pub fn assignment_mut(&self) -> Result<&mut Assignment, ClingoError> {
match unsafe { (clingo_propagate_control_assignment(&self.0) as *mut Assignment).as_mut() }
{
Some(stm) => Ok(stm),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut Assignment.",
}),
}
}
pub fn add_literal(&mut self, result: &mut Literal) -> Result<(), ClingoError> {
if !unsafe { clingo_propagate_control_add_literal(&mut self.0, &mut result.0) } {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_control_add_literal() failed",
));
}
Ok(())
}
pub fn add_watch(&mut self, literal: Literal) -> Result<(), ClingoError> {
if !unsafe { clingo_propagate_control_add_watch(&mut self.0, literal.0) } {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_control_add_watch() failed",
));
}
Ok(())
}
pub fn has_watch(&self, literal: Literal) -> bool {
unsafe { clingo_propagate_control_has_watch(&self.0, literal.0) }
}
pub fn remove_watch(&mut self, literal: Literal) {
unsafe { clingo_propagate_control_remove_watch(&mut self.0, literal.0) }
}
pub fn add_clause(
&mut self,
clause: &[Literal],
ctype: ClauseType,
) -> Result<bool, ClingoError> {
let mut result = false;
if !unsafe {
clingo_propagate_control_add_clause(
&mut self.0,
clause.as_ptr() as *const clingo_literal_t,
clause.len(),
ctype as clingo_clause_type_t,
&mut result,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_control_add_clause() failed",
));
}
Ok(result)
}
pub fn propagate(&mut self) -> Result<bool, ClingoError> {
let mut result = false;
if !unsafe { clingo_propagate_control_propagate(&mut self.0, &mut result) } {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_control_propagate() failed",
));
}
Ok(result)
}
}
#[derive(Debug)]
pub struct PropagateInit(clingo_propagate_init_t);
impl PropagateInit {
pub fn solver_literal(&self, Literal(aspif_literal): Literal) -> Result<Literal, ClingoError> {
let mut solver_literal = 0 as clingo_literal_t;
if !unsafe {
clingo_propagate_init_solver_literal(&self.0, aspif_literal, &mut solver_literal)
} {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_init_solver_literal() failed",
));
}
Ok(Literal(solver_literal))
}
pub fn add_watch(&mut self, Literal(solver_literal): Literal) -> Result<(), ClingoError> {
if !unsafe { clingo_propagate_init_add_watch(&mut self.0, solver_literal) } {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_init_add_watch() failed",
));
}
Ok(())
}
pub fn add_watch_to_thread(
&mut self,
Literal(solver_literal): Literal,
thread_id: u32,
) -> Result<(), ClingoError> {
if !unsafe {
clingo_propagate_init_add_watch_to_thread(&mut self.0, solver_literal, thread_id)
} {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_init_add_watch_to_thread() failed",
));
}
Ok(())
}
pub fn symbolic_atoms(&self) -> Result<&SymbolicAtoms, ClingoError> {
let mut atoms_ptr = std::ptr::null() as *const clingo_symbolic_atoms_t;
if !unsafe { clingo_propagate_init_symbolic_atoms(&self.0, &mut atoms_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_init_symbolic_atoms() failed",
));
}
match unsafe { (atoms_ptr as *const SymbolicAtoms).as_ref() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &SymbolicAtoms.",
}),
}
}
pub fn theory_atoms(&self) -> Result<&TheoryAtoms, ClingoError> {
let mut atoms_ptr = std::ptr::null() as *const clingo_theory_atoms_t;
if !unsafe { clingo_propagate_init_theory_atoms(&self.0, &mut atoms_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_init_symbolic_atoms() failed",
));
}
match unsafe { (atoms_ptr as *const TheoryAtoms).as_ref() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &TheoryAtoms.",
}),
}
}
pub fn number_of_threads(&self) -> usize {
(unsafe { clingo_propagate_init_number_of_threads(&self.0) } as usize)
}
pub fn set_check_mode(&mut self, mode: PropagatorCheckMode) {
unsafe {
clingo_propagate_init_set_check_mode(
&mut self.0,
mode as clingo_propagator_check_mode_t,
)
}
}
pub fn get_check_mode(&self) -> Result<PropagatorCheckMode, ClingoError> {
PropagatorCheckMode::try_from(unsafe { clingo_propagate_init_get_check_mode(&self.0) })
}
pub fn assignment(&self) -> Result<&Assignment, ClingoError> {
match unsafe { (clingo_propagate_init_assignment(&self.0) as *const Assignment).as_ref() } {
Some(stm) => Ok(stm),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut Assignment.",
}),
}
}
pub fn add_clause(&mut self, clause: &[Literal]) -> Result<bool, ClingoError> {
let mut result = false;
if !unsafe {
clingo_propagate_init_add_clause(
&mut self.0,
clause.as_ptr() as *const clingo_literal_t,
clause.len(),
&mut result,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_propagate_init_add_clause() failed",
));
}
Ok(result)
}
}
#[derive(Debug)]
pub struct SolveHandle<'a> {
theref: &'a mut clingo_solve_handle_t,
}
impl<'a> SolveHandle<'a> {
pub fn get(&mut self) -> Result<SolveResult, ClingoError> {
let mut result = 0;
if !unsafe { clingo_solve_handle_get(self.theref, &mut result) } {
return Err(ClingoError::new_internal(
"Call to clingo_solve_handle_get() failed",
));
}
if let Some(res) = SolveResult::from_bits(result) {
Ok(res)
} else {
eprintln!("Unknown bitflag in clingo_solve_result: {}.", result);
Err(ClingoError::FFIError {
msg: "Unknown bitflag in clingo_solve_result.",
})
}
}
pub fn wait(&mut self, timeout: f64) -> bool {
let mut result = false;
unsafe { clingo_solve_handle_wait(self.theref, timeout, &mut result) }
result
}
pub fn model(&mut self) -> Result<Option<&Model>, ClingoError> {
let mut model = std::ptr::null_mut() as *const clingo_model_t;
if !unsafe { clingo_solve_handle_model(self.theref, &mut model) } {
return Err(ClingoError::new_internal(
"Call to clingo_solve_handle_model() failed",
));
}
Ok(unsafe { (model as *const Model).as_ref() })
}
pub fn model_mut(&mut self) -> Result<&mut Model, ClingoError> {
let mut model = std::ptr::null_mut() as *const clingo_model_t;
if !unsafe { clingo_solve_handle_model(self.theref, &mut model) } {
return Err(ClingoError::new_internal(
"Call to clingo_solve_handle_model() failed",
));
}
match unsafe { (model as *mut Model).as_mut() } {
Some(x) => Ok(x),
None => Err(ClingoError::FFIError {
msg: "Tried casting a null pointer to &mut Model.",
}),
}
}
pub fn resume(&mut self) -> Result<(), ClingoError> {
if !unsafe { clingo_solve_handle_resume(self.theref) } {
return Err(ClingoError::new_internal(
"Call to clingo_solve_handle_resume() failed",
));
}
Ok(())
}
pub fn cancel(&mut self) -> Result<(), ClingoError> {
if !unsafe { clingo_solve_handle_cancel(self.theref) } {
return Err(ClingoError::new_internal(
"Call to clingo_solve_handle_cancel() failed",
));
}
Ok(())
}
pub fn close(self) -> Result<(), ClingoError> {
if !unsafe { clingo_solve_handle_close(self.theref) } {
return Err(ClingoError::new_internal(
"Call to clingo_solve_handle_close() failed",
));
}
Ok(())
}
}
pub struct OptimalModels<'a>(SolveHandle<'a>);
impl<'a, 'b> Iterator for OptimalModels<'a> {
type Item = MModel;
fn next(&mut self) -> Option<Self::Item> {
loop {
self.0.resume().expect("Failed resume on solve handle.");
match self.0.model() {
Ok(Some(model)) => {
if model.optimality_proven().unwrap() {
let symbols = model.symbols(ShowType::SHOWN).unwrap();
let cost = model.cost().unwrap();
return Some(MModel {
symbols,
cost,
model_type: model.model_type().unwrap(),
number: model.number().unwrap(),
});
}
}
Ok(None) => {
return None;
}
Err(e) => panic!(e),
}
}
}
}
pub struct AllModels<'a>(SolveHandle<'a>);
impl<'a, 'b> Iterator for AllModels<'a> {
type Item = MModel;
fn next(&mut self) -> Option<Self::Item> {
loop {
self.0.resume().expect("Failed resume on solve handle.");
match self.0.model() {
Ok(Some(model)) => {
let symbols = model.symbols(ShowType::SHOWN).unwrap();
let cost = model.cost().unwrap();
return Some(MModel {
symbols,
cost,
model_type: model.model_type().unwrap(),
number: model.number().unwrap(),
});
}
Ok(None) => {
return None;
}
Err(e) => panic!(e),
}
}
}
}
pub struct MModel {
pub symbols: Vec<Symbol>,
pub cost: Vec<i64>,
pub model_type: ModelType,
pub number: u64,
}
pub fn add_string(string: &str) -> Result<&'static str, ClingoError> {
let in_cstr = CString::new(string)?;
let mut out_ptr = std::ptr::null() as *const c_char;
if !unsafe { clingo_add_string(in_cstr.as_ptr(), &mut out_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_add_string() failed",
));
}
if out_ptr.is_null() {
return Err(ClingoError::FFIError {
msg: "clingo_add_string returned a null pointer.",
});
}
let out_cstr = unsafe { CStr::from_ptr(out_ptr) };
Ok(out_cstr.to_str()?)
}
fn internalize_string(string: &str) -> Result<*const c_char, ClingoError> {
let in_cstr = CString::new(string)?;
let mut out_ptr = std::ptr::null() as *const c_char;
if !unsafe { clingo_add_string(in_cstr.as_ptr(), &mut out_ptr) } {
return Err(ClingoError::new_internal(
"Call to clingo_add_string() failed",
));
}
if out_ptr.is_null() {
Err(ClingoError::FFIError {
msg: "clingo_add_string returned a null pointer.",
})?
}
Ok(out_ptr)
}
pub fn parse_term(string: &str) -> Result<Symbol, ClingoError> {
let c_str = CString::new(string)?;
let mut symbol = 0 as clingo_symbol_t;
if !unsafe { clingo_parse_term(c_str.as_ptr(), None, std::ptr::null_mut(), 0, &mut symbol) } {
return Err(ClingoError::new_internal(
"Call to clingo_parse_term() failed",
));
}
Ok(Symbol(symbol))
}
pub fn parse_term_with_logger<L: Logger>(
string: &str,
logger: &mut L,
message_limit: u32,
) -> Result<Symbol, ClingoError> {
let c_str = CString::new(string)?;
let logger = logger as *mut L;
let mut symbol = 0 as clingo_symbol_t;
if !unsafe {
clingo_parse_term(
c_str.as_ptr(),
Some(L::unsafe_logging_callback::<L> as LoggingCallback),
logger as *mut c_void,
message_limit,
&mut symbol,
)
} {
return Err(ClingoError::new_internal(
"Call to clingo_parse_term() failed",
));
}
Ok(Symbol(symbol))
}
pub trait GroundProgramObserver {
fn init_program(&mut self, incremental: bool) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_init_program<T: GroundProgramObserver>(
incremental: bool,
gpo: *mut c_void,
) -> bool {
if let Some(gpo) = (gpo as *mut T).as_mut() {
gpo.init_program(incremental)
} else {
set_internal_error(
ErrorType::Runtime,
"unsafe_init_program tried casting a null pointer to &mut GroundProgramObserver.",
);
false
}
}
fn begin_step(&mut self) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_begin_step<T: GroundProgramObserver>(gpo: *mut c_void) -> bool {
if let Some(gpo) = (gpo as *mut T).as_mut() {
gpo.begin_step()
} else {
set_internal_error(
ErrorType::Runtime,
"unsafe_begin_step tried casting a null pointer to &mut GroundProgramObserver.",
);
false
}
}
fn end_step(&mut self) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_end_step<T: GroundProgramObserver>(gpo: *mut c_void) -> bool {
if let Some(gpo) = (gpo as *mut T).as_mut() {
gpo.end_step()
} else {
set_internal_error(
ErrorType::Runtime,
"unsafe_end_step tried casting a null pointer to &mut GroundProgramObserver.",
);
false
}
}
fn rule(&mut self, choice: bool, head: &[Atom], body: &[Literal]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_rule<T: GroundProgramObserver>(
choice: bool,
head: *const clingo_atom_t,
head_size: usize,
body: *const clingo_literal_t,
body_size: usize,
gpo: *mut c_void,
) -> bool {
if (head_size > 0 && head.is_null()) | (body_size > 0 && body.is_null()) | gpo.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_rule() got a null pointer.");
return false;
}
let head = std::slice::from_raw_parts(head as *const Atom, head_size);
let body = std::slice::from_raw_parts(body as *const Literal, body_size);
let gpo = &mut *(gpo as *mut T);
gpo.rule(choice, head, body)
}
fn weight_rule(
&mut self,
choice: bool,
head: &[Atom],
lower_bound: i32,
body: &[WeightedLiteral],
) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_weight_rule<T: GroundProgramObserver>(
choice: bool,
head: *const clingo_atom_t,
head_size: usize,
lower_bound: clingo_weight_t,
body: *const clingo_weighted_literal_t,
body_size: usize,
gpo: *mut c_void,
) -> bool {
if (head_size > 0 && head.is_null()) | (body_size > 0 && body.is_null()) | gpo.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_weight_rule() got a null pointer.",
);
return false;
}
let head = std::slice::from_raw_parts(head as *const Atom, head_size);
let body = std::slice::from_raw_parts(body as *const WeightedLiteral, body_size);
let gpo = &mut *(gpo as *mut T);
gpo.weight_rule(choice, head, lower_bound, body)
}
fn minimize(&mut self, priority: i32, literals: &[WeightedLiteral]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_minimize<T: GroundProgramObserver>(
priority: clingo_weight_t,
literals: *const clingo_weighted_literal_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && literals.is_null()) | gpo.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_minimize() got a null pointer.");
return false;
}
let literals = std::slice::from_raw_parts(literals as *const WeightedLiteral, size);
let gpo = &mut *(gpo as *mut T);
gpo.minimize(priority, literals)
}
fn project(&mut self, atoms: &[Atom]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_project<T: GroundProgramObserver>(
atoms: *const clingo_atom_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && atoms.is_null()) | gpo.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_project() got a null pointer.");
return false;
}
let atoms = std::slice::from_raw_parts(atoms as *const Atom, size);
let gpo = &mut *(gpo as *mut T);
gpo.project(atoms)
}
fn output_atom(&mut self, symbol: Symbol, atom: Atom) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_output_atom<T: GroundProgramObserver>(
symbol: clingo_symbol_t,
atom: clingo_atom_t,
gpo: *mut c_void,
) -> bool {
if let Some(gpo) = (gpo as *mut T).as_mut() {
gpo.output_atom(Symbol(symbol), Atom(atom))
} else {
set_internal_error(
ErrorType::Runtime,
"unsafe_output_atom() tried casting a null pointer to &mut GroundProgramObserver.",
);
false
}
}
fn output_term(&mut self, symbol: Symbol, condition: &[Literal]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_output_term<T: GroundProgramObserver>(
symbol: clingo_symbol_t,
condition: *const clingo_literal_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && condition.is_null()) | gpo.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_output_term() got a null pointer.",
);
return false;
}
let condition = std::slice::from_raw_parts(condition as *const Literal, size);
let gpo = &mut *(gpo as *mut T);
gpo.output_term(Symbol(symbol), condition)
}
fn output_csp(&mut self, symbol: Symbol, value: i32, condition: &[Literal]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_output_csp<T: GroundProgramObserver>(
symbol: clingo_symbol_t,
value: ::std::os::raw::c_int,
condition: *const clingo_literal_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && condition.is_null()) | gpo.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_output_csp() got a null pointer.",
);
return false;
}
let condition = std::slice::from_raw_parts(condition as *const Literal, size);
let gpo = &mut *(gpo as *mut T);
gpo.output_csp(Symbol(symbol), value, condition)
}
fn external(&mut self, atom: Atom, type_: ExternalType) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_external<T: GroundProgramObserver>(
atom: clingo_atom_t,
etype: clingo_external_type_t,
gpo: *mut c_void,
) -> bool {
if gpo.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_external() got a null pointer.");
return false;
}
let gpo = &mut *(gpo as *mut T);
match ExternalType::try_from(etype) {
Err(e) => {
eprintln!("Error in unsafe_external(): {}.", e);
set_internal_error(ErrorType::Runtime, "Error in unsafe_external().");
false
}
Ok(etype) => gpo.external(Atom(atom), etype),
}
}
fn assume(&mut self, literals: &[Literal]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_assume<T: GroundProgramObserver>(
literals: *const clingo_literal_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && literals.is_null()) | gpo.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_assume() got a null pointer.");
return false;
}
let literals = std::slice::from_raw_parts(literals as *const Literal, size);
let gpo = &mut *(gpo as *mut T);
gpo.assume(literals)
}
fn heuristic(
&mut self,
atom: Atom,
type_: HeuristicType,
bias: i32,
priority: u32,
condition: &[Literal],
) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_heuristic<T: GroundProgramObserver>(
atom: clingo_atom_t,
htype: clingo_heuristic_type_t,
bias: ::std::os::raw::c_int,
priority: ::std::os::raw::c_uint,
condition: *const clingo_literal_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && condition.is_null()) | gpo.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_heuristic() got a null pointer.");
return false;
}
let condition = std::slice::from_raw_parts(condition as *const Literal, size);
let gpo = &mut *(gpo as *mut T);
match HeuristicType::try_from(htype) {
Err(e) => {
eprintln!("Error in unsafe_heuristic(): {}.", e);
set_internal_error(ErrorType::Runtime, "Error in unsafe_heuristic().");
false
}
Ok(htype) => gpo.heuristic(Atom(atom), htype, bias, priority, condition),
}
}
fn acyc_edge(&mut self, node_u: i32, node_v: i32, condition: &[Literal]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_acyc_edge<T: GroundProgramObserver>(
node_u: ::std::os::raw::c_int,
node_v: ::std::os::raw::c_int,
condition: *const clingo_literal_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && condition.is_null()) | gpo.is_null() {
set_internal_error(ErrorType::Runtime, "unsafe_heuristic() got a null pointer.");
return false;
}
let condition = std::slice::from_raw_parts(condition as *const Literal, size);
let gpo = &mut *(gpo as *mut T);
gpo.acyc_edge(node_u, node_v, condition)
}
fn theory_term_number(&mut self, term_id: Id, number: i32) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_theory_term_number<T: GroundProgramObserver>(
term_id: clingo_id_t,
number: ::std::os::raw::c_int,
gpo: *mut c_void,
) -> bool {
if let Some(gpo) = (gpo as *mut T).as_mut() {
gpo.theory_term_number(Id(term_id), number)
} else {
set_internal_error(
ErrorType::Runtime,
"unsafe_theory_term_number tried casting a null pointer to &mut GroundProgramObserver."
);
false
}
}
fn theory_term_string(&mut self, term_id: Id, name: &str) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_theory_term_string<T: GroundProgramObserver>(
term_id: clingo_id_t,
name: *const c_char,
gpo: *mut c_void,
) -> bool {
if name.is_null() | gpo.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_theory_term_string() got a null pointer.",
);
return false;
}
let name = CStr::from_ptr(name);
let gpo = &mut *(gpo as *mut T);
match name.to_str() {
Ok(name) => gpo.theory_term_string(Id(term_id), name),
Err(e) => {
eprintln!("Utf8Error in unsafe theory_term_string: {}", e);
set_internal_error(
ErrorType::Runtime,
"Utf8Error in unsafe theory_term_string.",
);
false
}
}
}
fn theory_term_compound(&mut self, term_id: Id, name_id_or_type: i32, arguments: &[Id])
-> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_theory_term_compound<T: GroundProgramObserver>(
term_id: clingo_id_t,
name_id_or_type: ::std::os::raw::c_int,
arguments: *const clingo_id_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && arguments.is_null()) | gpo.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_theory_term_compound() got a null pointer.",
);
return false;
}
let arguments = std::slice::from_raw_parts(arguments as *const Id, size);
let gpo = &mut *(gpo as *mut T);
gpo.theory_term_compound(Id(term_id), name_id_or_type, arguments)
}
fn theory_element(&mut self, element_id: Id, terms: &[Id], condition: &[Literal]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_theory_element<T: GroundProgramObserver>(
element_id: clingo_id_t,
terms: *const clingo_id_t,
terms_size: usize,
condition: *const clingo_literal_t,
condition_size: usize,
gpo: *mut c_void,
) -> bool {
if (terms_size > 0 && terms.is_null())
| (condition_size > 0 && condition.is_null())
| gpo.is_null()
{
set_internal_error(
ErrorType::Runtime,
"unsafe_theory_element() got a null pointer.",
);
return false;
}
let terms = std::slice::from_raw_parts(terms as *const Id, terms_size);
let condition = std::slice::from_raw_parts(condition as *const Literal, condition_size);
let gpo = &mut *(gpo as *mut T);
gpo.theory_element(Id(element_id), terms, condition)
}
fn theory_atom(&mut self, atom_id_or_zero: Id, term_id: Id, elements: &[Id]) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_theory_atom<T: GroundProgramObserver>(
atom_id_or_zero: clingo_id_t,
term_id: clingo_id_t,
elements: *const clingo_id_t,
size: usize,
gpo: *mut c_void,
) -> bool {
if (size > 0 && elements.is_null()) | gpo.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_theory_atom() got a null pointer.",
);
return false;
}
let elements = std::slice::from_raw_parts(elements as *const Id, size);
let gpo = &mut *(gpo as *mut T);
gpo.theory_atom(Id(atom_id_or_zero), Id(term_id), elements)
}
fn theory_atom_with_guard(
&mut self,
atom_id_or_zero: Id,
term_id: Id,
elements: &[Id],
operator_id: Id,
right_hand_side_id: Id,
) -> bool;
#[doc(hidden)]
unsafe extern "C" fn unsafe_theory_atom_with_guard<T: GroundProgramObserver>(
atom_id_or_zero: clingo_id_t,
term_id: clingo_id_t,
elements: *const clingo_id_t,
size: usize,
operator_id: clingo_id_t,
right_hand_side_id: clingo_id_t,
gpo: *mut c_void,
) -> bool {
if (size > 0 && elements.is_null()) | gpo.is_null() {
set_internal_error(
ErrorType::Runtime,
"unsafe_theory_atom_with_guard() got a null pointer.",
);
return false;
}
let elements = std::slice::from_raw_parts(elements as *const Id, size);
let gpo = &mut *(gpo as *mut T);
gpo.theory_atom_with_guard(
Id(atom_id_or_zero),
Id(term_id),
elements,
Id(operator_id),
Id(right_hand_side_id),
)
}
}
pub trait ToSymbol {
fn symbol(&self) -> Result<Symbol, ClingoError>;
}
impl ToSymbol for Symbol {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Ok(*self)
}
}
impl ToSymbol for () {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Symbol::create_function("", &[], true)
}
}
impl<A: ToSymbol, B: ToSymbol> ToSymbol for (A, B) {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Symbol::create_function("", &[self.0.symbol()?, self.1.symbol()?], true)
}
}
impl<A: ToSymbol, B: ToSymbol, C: ToSymbol> ToSymbol for (A, B, C) {
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<A: ToSymbol, B: ToSymbol, C: ToSymbol, D: ToSymbol> ToSymbol for (A, B, C, D) {
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<A: ToSymbol, B: ToSymbol, C: ToSymbol, D: ToSymbol, E: ToSymbol> ToSymbol for (A, B, C, D, E) {
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<A: ToSymbol, B: ToSymbol, C: ToSymbol, D: ToSymbol, E: ToSymbol, F: ToSymbol> ToSymbol
for (A, B, C, D, E, F)
{
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
tempvec.push(self.5.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<A: ToSymbol, B: ToSymbol, C: ToSymbol, D: ToSymbol, E: ToSymbol, F: ToSymbol, G: ToSymbol>
ToSymbol for (A, B, C, D, E, F, G)
{
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
tempvec.push(self.5.symbol()?);
tempvec.push(self.6.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<
A: ToSymbol,
B: ToSymbol,
C: ToSymbol,
D: ToSymbol,
E: ToSymbol,
F: ToSymbol,
G: ToSymbol,
H: ToSymbol,
> ToSymbol for (A, B, C, D, E, F, G, H)
{
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
tempvec.push(self.5.symbol()?);
tempvec.push(self.6.symbol()?);
tempvec.push(self.7.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<
A: ToSymbol,
B: ToSymbol,
C: ToSymbol,
D: ToSymbol,
E: ToSymbol,
F: ToSymbol,
G: ToSymbol,
H: ToSymbol,
I: ToSymbol,
> ToSymbol for (A, B, C, D, E, F, G, H, I)
{
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
tempvec.push(self.5.symbol()?);
tempvec.push(self.6.symbol()?);
tempvec.push(self.7.symbol()?);
tempvec.push(self.8.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<
A: ToSymbol,
B: ToSymbol,
C: ToSymbol,
D: ToSymbol,
E: ToSymbol,
F: ToSymbol,
G: ToSymbol,
H: ToSymbol,
I: ToSymbol,
J: ToSymbol,
> ToSymbol for (A, B, C, D, E, F, G, H, I, J)
{
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
tempvec.push(self.5.symbol()?);
tempvec.push(self.6.symbol()?);
tempvec.push(self.7.symbol()?);
tempvec.push(self.8.symbol()?);
tempvec.push(self.9.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<
A: ToSymbol,
B: ToSymbol,
C: ToSymbol,
D: ToSymbol,
E: ToSymbol,
F: ToSymbol,
G: ToSymbol,
H: ToSymbol,
I: ToSymbol,
J: ToSymbol,
K: ToSymbol,
> ToSymbol for (A, B, C, D, E, F, G, H, I, J, K)
{
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
tempvec.push(self.5.symbol()?);
tempvec.push(self.6.symbol()?);
tempvec.push(self.7.symbol()?);
tempvec.push(self.8.symbol()?);
tempvec.push(self.9.symbol()?);
tempvec.push(self.10.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl<
A: ToSymbol,
B: ToSymbol,
C: ToSymbol,
D: ToSymbol,
E: ToSymbol,
F: ToSymbol,
G: ToSymbol,
H: ToSymbol,
I: ToSymbol,
J: ToSymbol,
K: ToSymbol,
L: ToSymbol,
> ToSymbol for (A, B, C, D, E, F, G, H, I, J, K, L)
{
fn symbol(&self) -> Result<Symbol, ClingoError> {
let mut tempvec = vec![];
tempvec.push(self.0.symbol()?);
tempvec.push(self.1.symbol()?);
tempvec.push(self.2.symbol()?);
tempvec.push(self.3.symbol()?);
tempvec.push(self.4.symbol()?);
tempvec.push(self.5.symbol()?);
tempvec.push(self.6.symbol()?);
tempvec.push(self.7.symbol()?);
tempvec.push(self.8.symbol()?);
tempvec.push(self.9.symbol()?);
tempvec.push(self.10.symbol()?);
tempvec.push(self.11.symbol()?);
Symbol::create_function("", &tempvec, true)
}
}
impl ToSymbol for bool {
fn symbol(&self) -> Result<Symbol, ClingoError> {
if *self {
Symbol::create_id("true", true)
} else {
Symbol::create_id("false", true)
}
}
}
impl ToSymbol for u8 {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Ok(Symbol::create_number(i32::from(*self)))
}
}
impl ToSymbol for i8 {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Ok(Symbol::create_number(i32::from(*self)))
}
}
impl ToSymbol for u16 {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Ok(Symbol::create_number(i32::from(*self)))
}
}
impl ToSymbol for i16 {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Ok(Symbol::create_number(i32::from(*self)))
}
}
impl ToSymbol for u32 {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Ok(Symbol::create_number(*self as i32))
}
}
impl ToSymbol for i32 {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Ok(Symbol::create_number(*self))
}
}
impl ToSymbol for String {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Symbol::create_string(self)
}
}
impl ToSymbol for str {
fn symbol(&self) -> Result<Symbol, ClingoError> {
Symbol::create_string(self)
}
}
impl<T: ToSymbol> ToSymbol for &T {
fn symbol(&self) -> Result<Symbol, ClingoError> {
(*self).symbol()
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct FactBase {
facts: HashSet<Symbol>,
}
impl FactBase {
pub fn new() -> FactBase {
FactBase {
facts: HashSet::new(),
}
}
pub fn len(&self) -> usize {
self.facts.len()
}
pub fn is_empty(&self) -> bool {
self.facts.is_empty()
}
pub fn iter(&self) -> std::collections::hash_set::Iter<'_, Symbol> {
self.facts.iter()
}
pub fn insert(&mut self, fact: &dyn ToSymbol) {
self.facts.insert(fact.symbol().unwrap());
}
pub fn union(&mut self, facts: &FactBase) {
for s in &facts.facts {
self.facts.insert(s.clone());
}
}
pub fn print(&self) {
for fact in &self.facts {
print!("{}.", fact.to_string().unwrap());
}
println!();
}
}
#[cfg(feature = "derive")]
#[allow(unused_imports)]
pub use clingo_derive::*;