From 0755505e84ac8edc5cf3f6b3ce7a8d94e3945c93 Mon Sep 17 00:00:00 2001 From: Sven Thiele Date: Thu, 13 Dec 2018 11:20:52 +0100 Subject: [PATCH] SolveHandle::model() returns now Result, Error> to distinguish Errors and nomore models=None --- clingo-sys/build.rs | 1 + src/examples/ast.rs | 8 +++-- src/examples/backend.rs | 8 +++-- src/examples/configuration.rs | 10 +++--- src/examples/control.rs | 8 +++-- src/examples/inject-terms.rs | 5 +-- src/examples/model.rs | 65 ++++++++++++++++++++--------------- src/examples/propagator.rs | 16 ++++----- src/examples/solve-async.rs | 9 ++--- src/examples/statistics.rs | 8 +++-- src/examples/theory-atoms.rs | 11 +++--- src/lib.rs | 58 ++++++++++++++++--------------- 12 files changed, 118 insertions(+), 89 deletions(-) diff --git a/clingo-sys/build.rs b/clingo-sys/build.rs index 9a683ee..a49eac7 100644 --- a/clingo-sys/build.rs +++ b/clingo-sys/build.rs @@ -30,6 +30,7 @@ fn main() { gcc::Build::new() .cpp(true) .flag("-std=c++11") + .flag("-O3") .warnings(false) .define("NDEBUG", Some("1")) .file("clingo/clasp/libpotassco/src/application.cpp") diff --git a/src/examples/ast.rs b/src/examples/ast.rs index f883575..97e27ef 100644 --- a/src/examples/ast.rs +++ b/src/examples/ast.rs @@ -76,7 +76,8 @@ fn print_model(model: &Model) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed retrieving solve handle."); // loop over all models @@ -84,9 +85,10 @@ fn solve(ctl: &mut Control) { handle.resume().expect("Failed resume on solve handle."); match handle.model() { // print the model - Ok(model) => print_model(model), + Ok(Some(model)) => print_model(model), // stop if there are no more models - Err(_) => break, + Ok(None) => break, + Err(e) => panic!("Error: {}", e.as_fail()), } } diff --git a/src/examples/backend.rs b/src/examples/backend.rs index 8867873..b5d9968 100644 --- a/src/examples/backend.rs +++ b/src/examples/backend.rs @@ -20,7 +20,8 @@ fn print_model(model: &Model) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed retrieving solve handle."); // loop over all models @@ -28,9 +29,10 @@ fn solve(ctl: &mut Control) { handle.resume().expect("Failed resume on solve handle."); match handle.model() { // print the model - Ok(model) => print_model(model), + Ok(Some(model)) => print_model(model), // stop if there are no more models - Err(_) => break, + Ok(None) => break, + Err(e) => panic!("Error: {}", e.as_fail()), } } diff --git a/src/examples/configuration.rs b/src/examples/configuration.rs index ecf1a70..316371d 100644 --- a/src/examples/configuration.rs +++ b/src/examples/configuration.rs @@ -20,17 +20,19 @@ fn print_model(model: &Model) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed retrieving solve handle."); // loop over all models loop { handle.resume().expect("Failed resume on solve handle."); match handle.model() { - // stop if there are no more models - Err(_) => break, // print the model - Ok(model) => print_model(model), + Ok(Some(model)) => print_model(model), + // stop if there are no more models + Ok(None) => break, + Err(e) => panic!("Error: {}", e.as_fail()), } } diff --git a/src/examples/control.rs b/src/examples/control.rs index 6f50563..18bfd19 100644 --- a/src/examples/control.rs +++ b/src/examples/control.rs @@ -20,7 +20,8 @@ fn print_model(model: &Model) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed retrieving solve handle."); // loop over all models @@ -28,9 +29,10 @@ fn solve(ctl: &mut Control) { handle.resume().expect("Failed resume on solve handle."); match handle.model() { // print the model - Ok(model) => print_model(model), + Ok(Some(model)) => print_model(model), // stop if there are no more models - Err(_) => break, + Ok(None) => break, + Err(e) => panic!("Error: {}", e.as_fail()), } } diff --git a/src/examples/inject-terms.rs b/src/examples/inject-terms.rs index 877b8af..816650f 100644 --- a/src/examples/inject-terms.rs +++ b/src/examples/inject-terms.rs @@ -60,10 +60,11 @@ fn main() { }); // solve - let handle = ctl.solve(&SolveMode::YIELD, &[]) + let handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed to retrieve solve handle."); - print_model(handle.model().unwrap()); + print_model(handle.model().unwrap().unwrap()); handle.close().expect("Failed to close solve handle."); } diff --git a/src/examples/model.rs b/src/examples/model.rs index 1fabbde..68aeab6 100644 --- a/src/examples/model.rs +++ b/src/examples/model.rs @@ -20,41 +20,45 @@ fn print_model(model: &Model, label: &str, show: &ShowType) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed retrieving solve handle."); // loop over all models loop { handle.resume().expect("Failed resume on solve handle."); - if let Ok(model) = handle.model() { - // get model type - let model_type = model.model_type().unwrap(); - - let mut type_string = match model_type { - ModelType::StableModel => "Stable model", - ModelType::BraveConsequences => "Brave consequences", - ModelType::CautiousConsequences => "Cautious consequences", - }; - - // get running number of model - let number = model.number().unwrap(); - - println!("{}: {}", type_string, number); - - print_model(model, " shown", &ShowType::SHOWN); - print_model(model, " atoms", &ShowType::ATOMS); - print_model(model, " terms", &ShowType::TERMS); - print_model(model, " ~atoms", &(ShowType::COMPLEMENT | ShowType::ATOMS)); - } else { - // stop if there are no more models - break; + match handle.model() { + Ok(Some(model)) => { + // get model type + let model_type = model.model_type().unwrap(); + + let type_string = match model_type { + ModelType::StableModel => "Stable model", + ModelType::BraveConsequences => "Brave consequences", + ModelType::CautiousConsequences => "Cautious consequences", + }; + + // get running number of model + let number = model.number().unwrap(); + + println!("{}: {}", type_string, number); + + print_model(model, " shown", &ShowType::SHOWN); + print_model(model, " atoms", &ShowType::ATOMS); + print_model(model, " terms", &ShowType::TERMS); + print_model(model, " ~atoms", &(ShowType::COMPLEMENT | ShowType::ATOMS)); + } + Ok(None) => { + // stop if there are no more models + break; + } + Err(e) => { + panic!("Error: {}", e); + } } } // close the solve handle - handle - .get() - .expect("Failed to get result from solve handle."); handle.close().expect("Failed to close solve handle."); } @@ -66,8 +70,13 @@ fn main() { let mut ctl = Control::new(options).expect("Failed creating clingo_control."); // add a logic program to the base part - ctl.add("base", &[], "1 {a; b} 1. #show c : b. #show a/0.") - .expect("Failed to add a logic program."); + // ctl.add("base", &[], "1 {a; b} 1. #show c : b. #show a/0.") + ctl.add( + "base", + &[], + "a(1..100). 1{b(X):a(X)}1. #maximize { V@2 : b(V) }.", + ) + .expect("Failed to add a logic program."); // ground the base part let part = Part::new("base", &[]).unwrap(); diff --git a/src/examples/propagator.rs b/src/examples/propagator.rs index 143db1d..ba4d38d 100644 --- a/src/examples/propagator.rs +++ b/src/examples/propagator.rs @@ -23,7 +23,8 @@ fn print_model(model: &Model) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed to retrieve solve handle."); // loop over all models @@ -31,16 +32,14 @@ fn solve(ctl: &mut Control) { handle.resume().expect("Failed resume on solve handle."); match handle.model() { // print the model - Ok(model) => print_model(model), + Ok(Some(model)) => print_model(model), // stop if there are no more models - Err(_) => break, + Ok(None) => break, + Err(e) => panic!("Error: {}", e.as_fail()), } } // close the solve handle - handle - .get() - .expect("Failed to get result from solve handle."); handle.close().expect("Failed to close solve handle."); } @@ -249,7 +248,8 @@ fn main() { "pigeon", &vec!["h", "p"], "1 { place(P,H) : H = 1..h } 1 :- P = 1..p.", - ).expect("Failed to add a logic program."); + ) + .expect("Failed to add a logic program."); // ground the pigeon part @@ -270,7 +270,7 @@ fn main() { solve(&mut ctl); } Err(e) => { - println!("Error: {}", e.cause()); + panic!("Error: {}", e.as_fail()); } } } diff --git a/src/examples/solve-async.rs b/src/examples/solve-async.rs index 427fbbb..1a50781 100644 --- a/src/examples/solve-async.rs +++ b/src/examples/solve-async.rs @@ -33,7 +33,8 @@ fn main() { 1 { p(X); q(X) } 1 :- X = 1..n.\ :- not n+1 { p(1..n); \ q(1..n) }.", - ).expect("Failed to add a logic program."); + ) + .expect("Failed to add a logic program."); // ground the base part let part = Part::new("base", &[]).unwrap(); @@ -46,9 +47,9 @@ fn main() { }; // create a solve handle with an attached event handler - let mut handle = - ctl.solve_with_event_handler(&(SolveMode::ASYNC | SolveMode::YIELD), &[], &mut running) - .expect("Failed to retrieve solve handle."); + let mut handle = ctl + .solve_with_event_handler(&(SolveMode::ASYNC | SolveMode::YIELD), &[], &mut running) + .expect("Failed to retrieve solve handle."); // let's approximate pi let mut samples = 0.; diff --git a/src/examples/statistics.rs b/src/examples/statistics.rs index 0a0c339..d04fbe7 100644 --- a/src/examples/statistics.rs +++ b/src/examples/statistics.rs @@ -84,7 +84,8 @@ fn print_model(model: &Model) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed retrieving solve handle."); // loop over all models @@ -92,9 +93,10 @@ fn solve(ctl: &mut Control) { handle.resume().expect("Failed resume on solve handle."); match handle.model() { // print the model - Ok(model) => print_model(model), + Ok(Some(model)) => print_model(model), // stop if there are no more models - Err(_) => break, + Ok(None) => break, + Err(e) => panic!("Error: {}", e.as_fail()), } } diff --git a/src/examples/theory-atoms.rs b/src/examples/theory-atoms.rs index 1c29376..76feb05 100644 --- a/src/examples/theory-atoms.rs +++ b/src/examples/theory-atoms.rs @@ -20,7 +20,8 @@ fn print_model(model: &Model) { fn solve(ctl: &mut Control) { // get a solve handle - let mut handle = ctl.solve(&SolveMode::YIELD, &[]) + let mut handle = ctl + .solve(&SolveMode::YIELD, &[]) .expect("Failed retrieving solve handle."); // loop over all models @@ -28,9 +29,10 @@ fn solve(ctl: &mut Control) { handle.resume().expect("Failed resume on solve handle."); match handle.model() { // print the model - Ok(model) => print_model(model), + Ok(Some(model)) => print_model(model), // stop if there are no more models - Err(_) => break, + Ok(None) => break, + Err(e) => panic!("Error: {}", e.as_fail()), } } @@ -90,7 +92,8 @@ fn main() { }.\ x :- &a { 1+2 }.\ y :- &b(3) { } = 17.", - ).expect("Failed to add a logic program."); + ) + .expect("Failed to add a logic program."); // ground the base part let part = Part::new("base", &[]).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 0abcda2..84383ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -318,9 +318,10 @@ pub trait SolveEventHandler { } } -type AstCallback = - unsafe extern "C" fn(arg1: *const clingo_ast_statement_t, arg2: *mut ::std::os::raw::c_void) - -> bool; +type AstCallback = unsafe extern "C" fn( + arg1: *const clingo_ast_statement_t, + arg2: *mut ::std::os::raw::c_void, +) -> bool; pub trait AstStatementHandler { /// Callback function called on an ast statement while traversing the ast. /// @@ -439,7 +440,7 @@ pub trait ExternalFunctionHandler { /// **See:** [`Control::ground_with_event_handler()`](struct.Control.html#method.ground_with_event_handler) /// /// The following example implements the external function `@f()` returning 42. - /// ``` + /// ```ignore /// fn on_external_function( /// &mut self, /// _location: &Location, @@ -488,9 +489,8 @@ pub trait ExternalFunctionHandler { match event_handler.on_external_function(location, name, arguments) { Ok(symbols) => { if let Some(symbol_injector) = symbol_callback { - let mut v: Vec< - clingo_symbol_t, - > = symbols.iter().map(|symbol| symbol.clone().0).collect(); + let v: Vec = + symbols.iter().map(|symbol| symbol.clone().0).collect(); return symbol_injector( v.as_slice().as_ptr(), v.len(), @@ -896,6 +896,16 @@ impl Symbol { } } + // pub fn term(&self, Location(location): Location) -> ast::Term { + // let _bg_union_1 = clingo_ast_term__bindgen_ty_1 { symbol: self.0 }; + // let term = clingo_ast_term_t { + // location: location, + // type_: ast::TermType::Symbol as clingo_ast_term_type_t, + // __bindgen_anon_1: _bg_union_1, + // }; + // ast::Term(term) + // } + /// Get the number of a symbol. /// /// # Errors @@ -1020,7 +1030,10 @@ impl Symbol { let a1 = vec![1; size]; let cstring = unsafe { CString::from_vec_unchecked(a1) }; if unsafe { clingo_symbol_to_string(self.0, cstring.as_ptr() as *mut c_char, size) } { - Ok(cstring.into_string()?) + match cstring.into_string() { + Ok(string) => Ok(string.trim_matches(char::from(0)).to_string()), + Err(e) => Err(e)?, + } } else { Err(error())? } @@ -1272,8 +1285,8 @@ pub trait Propagator { /// within the callback. /// The important point is to return true (true to indicate there was no error) if the result of /// either of the methods is false. - /// ``` - /// let clause: &[ ... ]; + /// ```ignore + /// let clause= &[ ... ]; /// // add a clause /// if let Ok(x) = control.add_clause(clause, ClauseType::Learnt) { /// if !x { @@ -1462,7 +1475,8 @@ impl Control { } // convert the strings to raw pointers - let c_args = args.iter() + let c_args = args + .iter() .map(|arg| arg.as_ptr()) .collect::>(); @@ -1520,7 +1534,8 @@ impl Control { } // convert the strings to raw pointers - let c_args = args.iter() + let c_args = args + .iter() .map(|arg| arg.as_ptr()) .collect::>(); @@ -4077,29 +4092,22 @@ impl<'a> SolveHandle<'a> { result } - /// Get the next model (or zero if there are no more models). - /// (it is NULL if there are no more models) + /// Get the next model or None if there are no more models. /// /// # Errors /// /// - [`ErrorType::BadAlloc`](enum.ErrorType.html#variant.BadAlloc) /// - [`ErrorType::Runtime`](enum.ErrorType.html#variant.Runtime) if solving fails - pub fn model(&self) -> Result<&Model, Error> { + pub fn model(&self) -> Result, Error> { let mut model = std::ptr::null_mut() as *mut clingo_model_t; if unsafe { clingo_solve_handle_model(self.theref, &mut model) } { - match unsafe { (model as *const Model).as_ref() } { - Some(x) => Ok(x), - None => Err(WrapperError { - msg: "tried casting a null pointer to &Model.", - })?, - } + Ok(unsafe { (model as *const Model).as_ref() }) } else { Err(error())? } } - /// Get the next model (or zero if there are no more models). - /// (it is NULL if there are no more models) + /// Get the next model or None if there are no more models. /// /// # Errors /// @@ -4139,10 +4147,6 @@ impl<'a> SolveHandle<'a> { /// Stop the running search and block until done. /// - /// # Arguments - /// - /// * `handle` - the target - /// /// # Errors /// /// - [`ErrorType::BadAlloc`](enum.ErrorType.html#variant.BadAlloc)