1use std::fs::File;
6use std::io::{BufReader, BufWriter, Write};
7use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio};
8
9use crate::{
10 common::*,
11 conf::SmtConf,
12 parse::{ExprParser, IdentParser, ModelParser, RSmtParser, ValueParser},
13};
14
15#[allow(non_upper_case_globals)]
17pub static actlit_pref: &str = "|rsmt2 actlit ";
18#[allow(non_upper_case_globals)]
20pub static actlit_suff: &str = "|";
21
22#[derive(Debug)]
28pub struct Actlit {
29 id: usize,
31}
32impl Actlit {
33 pub fn uid(&self) -> usize {
35 self.id
36 }
37 pub fn write<W>(&self, w: &mut W) -> SmtRes<()>
39 where
40 W: Write,
41 {
42 write!(w, "{}{}{}", actlit_pref, self.id, actlit_suff)?;
43 Ok(())
44 }
45}
46impl Expr2Smt<()> for Actlit {
47 fn expr_to_smt2<Writer>(&self, w: &mut Writer, _: ()) -> SmtRes<()>
48 where
49 Writer: ::std::io::Write,
50 {
51 self.write(w)
52 }
53}
54impl ::std::ops::Deref for Actlit {
55 type Target = usize;
56 fn deref(&self) -> &usize {
57 &self.id
58 }
59}
60
61pub struct FutureCheckSat {
63 _nothing: (),
64}
65fn future_check_sat() -> FutureCheckSat {
66 FutureCheckSat { _nothing: () }
67}
68
69pub struct Solver<Parser> {
76 conf: SmtConf,
78 kid: Child,
80 stdin: BufWriter<ChildStdin>,
82 tee: Option<BufWriter<File>>,
84 smt_parser: RSmtParser,
86 parser: Parser,
88 actlit: usize,
90}
91
92impl<Parser> Write for Solver<Parser> {
93 fn write(&mut self, buf: &[u8]) -> ::std::io::Result<usize> {
94 if let Some(tee) = self.tee.as_mut() {
95 let _ = tee.write(buf);
96 }
97 self.stdin.write(buf)
98 }
99 fn flush(&mut self) -> ::std::io::Result<()> {
100 if let Some(tee) = self.tee.as_mut() {
101 let _ = tee.flush();
102 }
103 self.stdin.flush()
104 }
105}
106
107macro_rules! tee_write {
109 ($slf:expr, |$w:ident| $($tail:tt)*) => ({
110 if let Some(ref mut $w) = $slf.tee {
111 $($tail)* ;
112 writeln!($w) ? ;
113 $w.flush() ?
114 }
115 let $w = & mut $slf.stdin ;
116 $($tail)* ;
117 $w.flush() ?
118 }) ;
119}
120
121impl<Parser> ::std::ops::Drop for Solver<Parser> {
122 fn drop(&mut self) {
123 let _ = self.kill();
124 ()
125 }
126}
127
128impl<Parser> Solver<Parser> {
130 fn spawn(conf: &SmtConf) -> SmtRes<(Child, BufWriter<ChildStdin>, BufReader<ChildStdout>)> {
132 let mut kid = Command::new(
133 conf.get_cmd(),
135 )
136 .args(
137 conf.get_options(),
139 )
140 .stdin(Stdio::piped())
141 .stdout(Stdio::piped())
142 .stderr(Stdio::piped())
143 .spawn()
144 .chain_err::<_, ErrorKind>(|| {
145 format!(
146 "While spawning child process with {}",
147 conf.get_cmd().to_string()
148 )
149 .into()
150 })?;
151
152 let mut stdin_opt = None;
153 ::std::mem::swap(&mut stdin_opt, &mut kid.stdin);
154
155 let stdin = if let Some(inner) = stdin_opt {
156 BufWriter::new(inner)
157 } else {
158 bail!("could not retrieve solver's stdin")
159 };
160
161 let mut stdout_opt = None;
162 ::std::mem::swap(&mut stdout_opt, &mut kid.stdout);
163
164 let stdout = if let Some(inner) = stdout_opt {
165 BufReader::new(inner)
166 } else {
167 bail!("could not retrieve solver's stdout")
168 };
169
170 Ok((kid, stdin, stdout))
171 }
172
173 pub fn new(conf: SmtConf, parser: Parser) -> SmtRes<Self> {
175 let (kid, stdin, stdout) = Self::spawn(&conf)?;
177
178 let smt_parser = RSmtParser::new(stdout);
179
180 let tee = None;
181 let actlit = 0;
182
183 Ok(Solver {
184 kid,
185 stdin,
186 tee,
187 conf,
188 smt_parser,
189 parser,
190 actlit,
191 })
192 }
193 pub fn default(parser: Parser) -> SmtRes<Self> {
197 Self::new(SmtConf::z3(), parser)
198 }
199 pub fn default_z3(parser: Parser) -> SmtRes<Self> {
203 Self::new(SmtConf::z3(), parser)
204 }
205 pub fn default_cvc4(parser: Parser) -> SmtRes<Self> {
209 Self::new(SmtConf::cvc4(), parser)
210 }
211 pub fn default_yices_2(parser: Parser) -> SmtRes<Self> {
215 Self::new(SmtConf::yices_2(), parser)
216 }
217
218 pub fn conf(&self) -> &SmtConf {
220 &self.conf
221 }
222
223 pub fn tee(&mut self, file: File) -> SmtRes<()> {
227 if self.tee.is_some() {
228 bail!("Trying to tee a solver that's already tee-ed")
229 }
230 let mut tee = BufWriter::with_capacity(1000, file);
231 write!(tee, "; Command:\n; > {}", self.conf.get_cmd())?;
232 for option in self.conf.get_options() {
233 write!(tee, " {}", option)?
234 }
235 writeln!(tee, "\n")?;
236 self.tee = Some(tee);
237 Ok(())
238 }
239
240 pub fn path_tee<P>(&mut self, path: P) -> SmtRes<()>
244 where
245 P: AsRef<::std::path::Path>,
246 {
247 use std::fs::OpenOptions;
248
249 let path: &::std::path::Path = path.as_ref();
250 let file = OpenOptions::new()
251 .create(true)
252 .write(true)
253 .truncate(true)
254 .open(path)
255 .chain_err(|| format!("while opening tee file `{}`", path.to_string_lossy()))?;
256 self.tee(file)
257 }
258
259 pub fn is_teed(&self) -> bool {
261 self.tee.is_some()
262 }
263
264 #[cfg(windows)]
271 pub fn kill(&mut self) -> SmtRes<()> {
272 let _ = writeln!(self.stdin, "(exit)");
273 let _ = self.stdin.flush();
274 let _ = self.kid.kill();
275 Ok(())
276 }
277 #[cfg(not(windows))]
284 pub fn kill(&mut self) -> SmtRes<()> {
285 let _ = writeln!(self.stdin, "(exit)");
286 let _ = self.stdin.flush();
287 let _ = self.kid.kill();
288 let join = self
289 .kid
290 .try_wait()
291 .chain_err(|| "waiting for child process to exit")?;
292 if join.is_none() {
293 self.kid
294 .kill()
295 .chain_err::<_, ErrorKind>(|| "while killing child process".into())?
296 }
297 Ok(())
298 }
299
300 #[inline]
302 fn cmt(file: &mut BufWriter<File>, blah: &str) -> SmtRes<()> {
303 for line in blah.lines() {
304 writeln!(file, "; {}", line)?
305 }
306 file.flush()?;
307 Ok(())
308 }
309
310 #[inline]
312 pub fn comment_args(&mut self, args: ::std::fmt::Arguments) -> SmtRes<()> {
313 if let Some(ref mut file) = self.tee {
314 Self::cmt(file, &format!("{}", args))?
315 }
316 Ok(())
317 }
318
319 #[inline]
321 pub fn comment(&mut self, blah: &str) -> SmtRes<()> {
322 if let Some(ref mut file) = self.tee {
323 Self::cmt(file, blah)?
324 }
325 Ok(())
326 }
327}
328
329impl<Parser> Solver<Parser> {
331 #[inline]
341 pub fn assert<Expr>(&mut self, expr: &Expr) -> SmtRes<()>
342 where
343 Expr: ?Sized + Expr2Smt<()>,
344 {
345 self.assert_with(expr, ())
346 }
347
348 pub fn check_sat(&mut self) -> SmtRes<bool> {
388 let future = self.print_check_sat()?;
389 self.parse_check_sat(future)
390 }
391
392 pub fn check_sat_or_unk(&mut self) -> SmtRes<Option<bool>> {
421 let future = self.print_check_sat()?;
422 self.parse_check_sat_or_unk(future)
423 }
424
425 #[inline]
438 pub fn reset(&mut self) -> SmtRes<()> {
439 self.actlit = 0;
440 tee_write! {
441 self, |w| write_str(w, "(reset)\n") ?
442 }
443 Ok(())
444 }
445
446 #[inline]
456 pub fn declare_const<Sym, Sort>(&mut self, symbol: &Sym, out_sort: &Sort) -> SmtRes<()>
457 where
458 Sym: ?Sized + Sym2Smt<()>,
459 Sort: ?Sized + Sort2Smt,
460 {
461 self.declare_const_with(symbol, out_sort, ())
462 }
463
464 #[inline]
474 pub fn declare_fun<'a, FunSym, ArgSort, Args, OutSort>(
475 &mut self,
476 symbol: &FunSym,
477 args: Args,
478 out: &OutSort,
479 ) -> SmtRes<()>
480 where
481 FunSym: ?Sized + Sym2Smt<()>,
482 ArgSort: ?Sized + Sort2Smt + 'a,
483 OutSort: ?Sized + Sort2Smt,
484 Args: IntoIterator<Item = &'a ArgSort>,
485 {
486 self.declare_fun_with(symbol, args, out, ())
487 }
488
489 #[inline]
501 pub fn define_const<FunSym, OutSort, Body>(
502 &mut self,
503 symbol: &FunSym,
504 out: &OutSort,
505 body: &Body,
506 ) -> SmtRes<()>
507 where
508 OutSort: ?Sized + Sort2Smt,
509 FunSym: ?Sized + Sym2Smt<()>,
510 Body: ?Sized + Expr2Smt<()>,
511 {
512 self.define_const_with(symbol, out, body, ())
513 }
514
515 #[inline]
527 pub fn define_fun<'a, FunSym, ArgSym, ArgSort, Args, OutSort, Body>(
528 &mut self,
529 symbol: &FunSym,
530 args: Args,
531 out: &OutSort,
532 body: &Body,
533 ) -> SmtRes<()>
534 where
535 ArgSort: Sort2Smt + 'a,
536 OutSort: ?Sized + Sort2Smt,
537 FunSym: ?Sized + Sym2Smt<()>,
538 ArgSym: Sym2Smt<()> + 'a,
539 Body: ?Sized + Expr2Smt<()>,
540 Args: IntoIterator<Item = &'a (ArgSym, ArgSort)>,
541 {
542 self.define_fun_with(symbol, args, out, body, ())
543 }
544
545 #[inline]
568 pub fn push(&mut self, n: u8) -> SmtRes<()> {
569 tee_write! {
570 self, |w| writeln!(w, "(push {})", n) ?
571 }
572 Ok(())
573 }
574
575 #[inline]
582 pub fn pop(&mut self, n: u8) -> SmtRes<()> {
583 tee_write! {
584 self, |w| writeln!(w, "(pop {})", n) ?
585 }
586 Ok(())
587 }
588
589 pub fn check_sat_assuming<'a, Ident, Idents>(&mut self, idents: Idents) -> SmtRes<bool>
591 where
592 Ident: ?Sized + Sym2Smt<()> + 'a,
593 Idents: IntoIterator<Item = &'a Ident>,
594 {
595 self.check_sat_assuming_with(idents, ())
596 }
597
598 pub fn check_sat_assuming_or_unk<'a, Ident, Idents>(
600 &mut self,
601 idents: Idents,
602 ) -> SmtRes<Option<bool>>
603 where
604 Ident: ?Sized + Sym2Smt<()> + 'a,
605 Idents: IntoIterator<Item = &'a Ident>,
606 {
607 self.check_sat_assuming_or_unk_with(idents, ())
608 }
609
610 #[inline]
620 pub fn set_logic(&mut self, logic: Logic) -> SmtRes<()> {
621 tee_write! {
622 self, |w| {
623 write_str(w, "(set-logic ") ? ;
624 logic.to_smt2(w, ()) ? ;
625 write_str(w, ")\n") ?
626 }
627 }
628 Ok(())
629 }
630
631 #[inline]
643 pub fn define_fun_rec<'a, FunSym, ArgSym, ArgSort, Args, OutSort, Body>(
644 &mut self,
645 symbol: &FunSym,
646 args: Args,
647 out: &OutSort,
648 body: &Body,
649 ) -> SmtRes<()>
650 where
651 ArgSort: Sort2Smt + 'a,
652 OutSort: ?Sized + Sort2Smt,
653 FunSym: ?Sized + Sym2Smt<()>,
654 ArgSym: Sym2Smt<()> + 'a,
655 Body: ?Sized + Expr2Smt<()>,
656 Args: IntoIterator<Item = &'a (ArgSym, ArgSort)>,
657 {
658 self.define_fun_rec_with(symbol, args, out, body, ())
659 }
660
661 #[inline]
675 pub fn define_funs_rec<'a, FunSym, ArgSym, ArgSort, Args, ArgsRef, OutSort, Body, Funs>(
676 &mut self,
677 funs: Funs,
678 ) -> SmtRes<()>
679 where
680 FunSym: Sym2Smt<()> + 'a,
681 ArgSym: Sym2Smt<()> + 'a,
682 ArgSort: Sort2Smt + 'a,
683 OutSort: Sort2Smt + 'a,
684 Body: Expr2Smt<()> + 'a,
685 &'a Args: IntoIterator<Item = &'a (ArgSym, ArgSort)> + 'a,
686 Args: ?Sized,
687 ArgsRef: 'a + AsRef<Args>,
688 Funs: IntoIterator<Item = &'a (FunSym, ArgsRef, OutSort, Body)>,
689 Funs::IntoIter: Clone,
690 {
691 self.define_funs_rec_with(funs, ())
692 }
693
694 pub fn declare_datatypes<'a, Sort, Param, ParamList, Def, DefList, All>(
721 &mut self,
722 defs: All,
723 ) -> SmtRes<()>
724 where
725 Sort: Sort2Smt + 'a,
726
727 Param: Sort2Smt + 'a,
728 &'a ParamList: IntoIterator<Item = &'a Param> + 'a,
729
730 Def: Sort2Smt + 'a,
731 &'a DefList: IntoIterator<Item = &'a Def> + 'a,
732 All: IntoIterator<Item = &'a (Sort, usize, ParamList, DefList)> + 'a,
733 All::IntoIter: Clone,
734 {
735 tee_write! {
736 self, |w| write!(w, "(declare-datatypes (") ?
737 }
738
739 let def_iter = defs.into_iter();
740
741 for &(ref sort, arity, _, _) in def_iter.clone() {
742 tee_write! {
743 self, |w| {
744 write!(w, " (") ? ;
745 sort.sort_to_smt2(w) ? ;
746 write!(w, " {})", arity) ?
747 }
748 }
749 }
750
751 tee_write! {
752 self, |w| write!(w, " ) (") ?
753 }
754
755 for &(_, arity, ref params, ref defs) in def_iter {
756 tee_write! {
757 self, |w| {
758 write!(w, " (") ? ;
759
760 if arity > 0 {
761 write!(w, "par (") ? ;
762 for param in params {
763 write!(w, " ") ? ;
764 param.sort_to_smt2(w) ? ;
765 }
766 write!(w, " ) (") ?
767 }
768 }
769 }
770
771 for def in defs {
772 tee_write! {
773 self, |w| {
774 write!(w, " ") ? ;
775 def.sort_to_smt2(w) ?
776 }
777 }
778 }
779
780 tee_write! {
781 self, |w| {
782 write!(w, " )") ? ;
783
784 if arity > 0 {
785 write!(w, " )") ?
786 }
787 }
788 }
789 }
790
791 tee_write! {
792 self, |w| writeln!(w, " ) )") ?
793 }
794
795 Ok(())
796 }
797}
798
799impl<Parser> Solver<Parser> {
801 pub fn get_model<Ident, Type, Value>(&mut self) -> SmtRes<Model<Ident, Type, Value>>
803 where
804 Parser: for<'a> IdentParser<Ident, Type, &'a mut RSmtParser>
805 + for<'a> ModelParser<Ident, Type, Value, &'a mut RSmtParser>,
806 {
807 self.print_get_model()?;
808 self.parse_get_model()
809 }
810
811 pub fn get_model_const<Ident, Type, Value>(&mut self) -> SmtRes<Vec<(Ident, Type, Value)>>
813 where
814 Parser: for<'a> IdentParser<Ident, Type, &'a mut RSmtParser>
815 + for<'a> ModelParser<Ident, Type, Value, &'a mut RSmtParser>,
816 {
817 self.print_get_model()?;
818 self.parse_get_model_const()
819 }
820
821 pub fn get_values<'a, Expr, Exprs, PExpr, PValue>(
826 &mut self,
827 exprs: Exprs,
828 ) -> SmtRes<Vec<(PExpr, PValue)>>
829 where
830 Parser: for<'b> ExprParser<PExpr, (), &'b mut RSmtParser>
831 + for<'b> ValueParser<PValue, &'b mut RSmtParser>,
832 Expr: ?Sized + Expr2Smt<()> + 'a,
833 Exprs: IntoIterator<Item = &'a Expr>,
834 {
835 self.get_values_with(exprs, ())
836 .map_err(|e| self.conf.enrich_get_values_error(e))
837 }
838}
839
840impl<Parser> Solver<Parser> {
847 #[inline]
856 fn has_actlits(&self) -> bool {
857 self.actlit > 0
858 }
859
860 #[inline]
867 pub fn get_actlit(&mut self) -> SmtRes<Actlit> {
868 let id = self.actlit;
869 self.actlit += 1;
870 let next_actlit = Actlit { id };
871 tee_write! {
872 self, |w| writeln!(
873 w, "(declare-fun {}{}{} () Bool)",
874 actlit_pref, next_actlit.id, actlit_suff
875 ) ?
876 }
877 Ok(next_actlit)
878 }
879
880 #[inline]
887 pub fn de_actlit(&mut self, actlit: Actlit) -> SmtRes<()> {
888 self.set_actlit(actlit, false)
889 }
890
891 #[inline]
898 pub fn set_actlit(&mut self, actlit: Actlit, b: bool) -> SmtRes<()> {
899 tee_write! {
900 self, |w| {
901 if b {
902 write!(w, "(assert ") ?
903 } else {
904 write!(w, "(assert (not ") ?
905 }
906 actlit.write(w) ? ;
907 if b {
908 writeln!(w, ")") ?
909 } else {
910 writeln!(w, ") )") ?
911 }
912 }
913 }
914 ::std::mem::drop(actlit);
915 Ok(())
916 }
917
918 #[inline]
925 pub fn assert_act<Expr>(&mut self, actlit: &Actlit, expr: &Expr) -> SmtRes<()>
926 where
927 Expr: ?Sized + Expr2Smt<()>,
928 {
929 self.assert_act_with(actlit, expr, ())
930 }
931
932 pub fn check_sat_act<'a, Actlits>(&mut self, actlits: Actlits) -> SmtRes<bool>
935 where
936 Actlits: IntoIterator<Item = &'a Actlit>,
937 {
938 let future = self.print_check_sat_act(actlits)?;
939 self.parse_check_sat(future)
940 }
941
942 pub fn check_sat_act_or_unk<'a, Actlits>(&mut self, actlits: Actlits) -> SmtRes<Option<bool>>
945 where
946 Actlits: IntoIterator<Item = &'a Actlit>,
947 {
948 let future = self.print_check_sat_act(actlits)?;
949 self.parse_check_sat_or_unk(future)
950 }
951}
952
953impl<Parser> Solver<Parser> {
955 #[inline]
981 pub fn print_check_sat(&mut self) -> SmtRes<FutureCheckSat> {
982 tee_write! {
983 self, |w| write_str(w, "(check-sat)\n") ?
984 }
985 Ok(future_check_sat())
986 }
987
988 #[inline]
995 pub fn print_check_sat_act<'a, Actlits>(&mut self, actlits: Actlits) -> SmtRes<FutureCheckSat>
996 where
997 Actlits: IntoIterator<Item = &'a Actlit>,
998 {
999 match self.conf.get_check_sat_assuming() {
1000 Some(ref cmd) => {
1001 tee_write! {
1002 self, |w| write!(w, "({} (", cmd) ?
1003 }
1004 for actlit in actlits {
1005 tee_write! {
1006 self, |w| {
1007 write!(w, " ") ? ;
1008 actlit.write(w) ?
1009 }
1010 }
1011 }
1012 tee_write! {
1013 self, |w| write_str(w, ") )\n") ?
1014 }
1015 Ok(future_check_sat())
1016 }
1017 None => {
1018 let msg = format!("{} does not support check-sat-assuming", self.conf.desc());
1019 Err(msg.into())
1020 }
1021 }
1022 }
1023
1024 #[inline]
1026 pub fn parse_check_sat(&mut self, _: FutureCheckSat) -> SmtRes<bool> {
1027 if let Some(res) = self.smt_parser.check_sat()? {
1028 Ok(res)
1029 } else {
1030 Err(ErrorKind::Unknown.into())
1031 }
1032 }
1033
1034 #[inline]
1036 pub fn parse_check_sat_or_unk(&mut self, _: FutureCheckSat) -> SmtRes<Option<bool>> {
1037 self.smt_parser.check_sat()
1038 }
1039
1040 #[inline]
1042 fn print_get_model(&mut self) -> SmtRes<()> {
1043 tee_write! {
1044 self, |w| write_str(w, "(get-model)\n") ?
1045 }
1046 Ok(())
1047 }
1048
1049 #[allow(dead_code)]
1051 fn print_get_assertions(&mut self) -> SmtRes<()> {
1052 tee_write! {
1053 self, |w| write_str(w, "(get-assertions)\n") ?
1054 }
1055 Ok(())
1056 }
1057 #[allow(dead_code)]
1059 fn print_get_assignment(&mut self) -> SmtRes<()> {
1060 tee_write! {
1061 self, |w| write_str(w, "(get-assignment)\n") ?
1062 }
1063 Ok(())
1064 }
1065 #[allow(dead_code)]
1067 fn print_get_unsat_assumptions(&mut self) -> SmtRes<()> {
1068 tee_write! {
1069 self, |w| write_str(w, "(get-unsat-assumptions)\n") ?
1070 }
1071 Ok(())
1072 }
1073 #[allow(dead_code)]
1075 fn print_get_proof(&mut self) -> SmtRes<()> {
1076 tee_write! {
1077 self, |w| write_str(w, "(get-proof)\n") ?
1078 }
1079 Ok(())
1080 }
1081 #[allow(dead_code)]
1083 fn print_get_unsat_core(&mut self) -> SmtRes<()> {
1084 tee_write! {
1085 self, |w| write_str(w, "(get-unsat-core)\n") ?
1086 }
1087 Ok(())
1088 }
1089
1090 fn print_get_values_with<'a, Info, Expr, Exprs>(
1092 &mut self,
1093 exprs: Exprs,
1094 info: Info,
1095 ) -> SmtRes<()>
1096 where
1097 Info: Copy,
1098 Expr: ?Sized + Expr2Smt<Info> + 'a,
1099 Exprs: IntoIterator<Item = &'a Expr>,
1100 {
1101 tee_write! {
1102 self, |w| write!(w, "(get-value (") ?
1103 }
1104 for e in exprs {
1105 tee_write! {
1106 self, |w| {
1107 write_str(w, "\n ") ? ;
1108 e.expr_to_smt2(w, info) ?
1109 }
1110 }
1111 }
1112 tee_write! {
1113 self, |w| write_str(w, "\n) )\n") ?
1114 }
1115 Ok(())
1116 }
1117
1118 pub fn print_check_sat_assuming<'a, Ident, Idents>(
1120 &mut self,
1121 bool_vars: Idents,
1122 ) -> SmtRes<FutureCheckSat>
1123 where
1124 Ident: ?Sized + Sym2Smt<()> + 'a,
1125 Idents: IntoIterator<Item = &'a Ident>,
1126 {
1127 self.print_check_sat_assuming_with(bool_vars, ())
1128 }
1129
1130 pub fn print_check_sat_assuming_with<'a, Info, Ident, Idents>(
1132 &mut self,
1133 bool_vars: Idents,
1134 info: Info,
1135 ) -> SmtRes<FutureCheckSat>
1136 where
1137 Info: Copy,
1138 Ident: ?Sized + Sym2Smt<Info> + 'a,
1139 Idents: IntoIterator<Item = &'a Ident>,
1140 {
1141 match self.conf.get_check_sat_assuming() {
1142 Some(ref cmd) => {
1143 tee_write! {
1144 self, |w| write!(w, "({} (\n ", cmd) ?
1145 }
1146 for sym in bool_vars {
1147 tee_write! {
1148 self, |w| {
1149 write_str(w, " ") ? ;
1150 sym.sym_to_smt2(w, info) ?
1151 }
1152 }
1153 }
1154 tee_write! {
1155 self, |w| write_str(w, "\n))\n") ?
1156 }
1157 Ok(future_check_sat())
1158 }
1159 None => {
1160 let msg = format!("{} does not support check-sat-assuming", self.conf.desc());
1161 Err(msg.into())
1162 }
1163 }
1164 }
1165
1166 fn parse_get_model<Ident, Type, Value>(&mut self) -> SmtRes<Model<Ident, Type, Value>>
1168 where
1169 Parser: for<'a> IdentParser<Ident, Type, &'a mut RSmtParser>
1170 + for<'a> ModelParser<Ident, Type, Value, &'a mut RSmtParser>,
1171 {
1172 let has_actlits = self.has_actlits();
1173 let res = self.smt_parser.get_model(has_actlits, self.parser);
1174 if res.is_err() && !self.conf.get_models() {
1175 res.chain_err(|| {
1176 "\
1177 Note: model production is not active \
1178 for this SmtConf (`conf.models()`)\
1179 "
1180 })
1181 } else {
1182 res
1183 }
1184 }
1185
1186 fn parse_get_model_const<Ident, Type, Value>(&mut self) -> SmtRes<Vec<(Ident, Type, Value)>>
1188 where
1189 Parser: for<'a> IdentParser<Ident, Type, &'a mut RSmtParser>
1190 + for<'a> ModelParser<Ident, Type, Value, &'a mut RSmtParser>,
1191 {
1192 let has_actlits = self.has_actlits();
1193 let res = self.smt_parser.get_model_const(has_actlits, self.parser);
1194 if res.is_err() && !self.conf.get_models() {
1195 res.chain_err(|| {
1196 "\
1197 Note: model production is not active \
1198 for this SmtConf (`conf.models()`)\
1199 "
1200 })
1201 } else {
1202 res
1203 }
1204 }
1205
1206 fn parse_get_values_with<Info, Expr, Val>(&mut self, info: Info) -> SmtRes<Vec<(Expr, Val)>>
1208 where
1209 Info: Copy,
1210 Parser: for<'a> ExprParser<Expr, Info, &'a mut RSmtParser>
1211 + for<'a> ValueParser<Val, &'a mut RSmtParser>,
1212 {
1213 let res = self.smt_parser.get_values(self.parser, info);
1214 if res.is_err() && !self.conf.get_models() {
1215 res.chain_err(|| {
1216 "\
1217 Note: model production is not active \
1218 for this SmtConf (`conf.models()`)\
1219 "
1220 })
1221 } else {
1222 res
1223 }
1224 }
1225
1226 fn get_values_with<'a, Info, Expr, Exprs, PExpr, PValue>(
1230 &mut self,
1231 exprs: Exprs,
1232 info: Info,
1233 ) -> SmtRes<Vec<(PExpr, PValue)>>
1234 where
1235 Info: Copy,
1236 Parser: for<'b> ExprParser<PExpr, Info, &'b mut RSmtParser>
1237 + for<'b> ValueParser<PValue, &'b mut RSmtParser>,
1238 Expr: ?Sized + Expr2Smt<Info> + 'a,
1239 Exprs: IntoIterator<Item = &'a Expr>,
1240 {
1241 self.print_get_values_with(exprs, info)?;
1242 self.parse_get_values_with(info)
1243 }
1244}
1245
1246impl<Parser> Solver<Parser> {
1248 #[inline]
1265 pub fn declare_sort<Sort>(&mut self, sort: &Sort, arity: u8) -> SmtRes<()>
1266 where
1267 Sort: ?Sized + Sort2Smt,
1268 {
1269 tee_write! {
1270 self, |w| {
1271 write_str(w, "(declare-sort ") ? ;
1272 sort.sort_to_smt2(w) ? ;
1273 writeln!(w, " {})", arity) ?
1274 }
1275 }
1276 Ok(())
1277 }
1278
1279 #[inline]
1309 pub fn define_sort<'a, Sort, Arg, Args, Body>(
1310 &mut self,
1311 sort: &Sort,
1312 args: Args,
1313 body: &Body,
1314 ) -> SmtRes<()>
1315 where
1316 Sort: ?Sized + Sort2Smt,
1317 Arg: ?Sized + Sort2Smt + 'a,
1318 Body: ?Sized + Sort2Smt,
1319 Args: IntoIterator<Item = &'a Arg>,
1320 {
1321 tee_write! {
1322 self, |w| {
1323 write_str(w, "( define-sort ") ? ;
1324 sort.sort_to_smt2(w) ? ;
1325 write_str(w, "\n ( ") ? ;
1326 }
1327 }
1328 for arg in args {
1329 tee_write! {
1330 self, |w| {
1331 arg.sort_to_smt2(w) ? ;
1332 write_str(w, " ") ?
1333 }
1334 }
1335 }
1336 tee_write! {
1337 self, |w| {
1338 write_str(w, ")\n ") ? ;
1339 body.sort_to_smt2(w) ? ;
1340 write_str(w, "\n)\n") ?
1341 }
1342 }
1343 Ok(())
1344 }
1345
1346 #[inline]
1357 pub fn define_null_sort<Sort, Body>(&mut self, sort: &Sort, body: &Body) -> SmtRes<()>
1358 where
1359 Sort: ?Sized + Sort2Smt,
1360 Body: ?Sized + Sort2Smt,
1361 {
1362 self.define_sort::<Sort, Body, Option<&Body>, Body>(sort, None, body)
1363 }
1364}
1365
1366impl<Parser> Solver<Parser> {
1368 #[inline]
1370 pub fn declare_const_with<Info, Sym, Sort>(
1371 &mut self,
1372 symbol: &Sym,
1373 out_sort: &Sort,
1374 info: Info,
1375 ) -> SmtRes<()>
1376 where
1377 Info: Copy,
1378 Sym: ?Sized + Sym2Smt<Info>,
1379 Sort: ?Sized + Sort2Smt,
1380 {
1381 tee_write! {
1382 self, |w| {
1383 write_str(w, "(declare-const ") ? ;
1384 symbol.sym_to_smt2(w, info) ? ;
1385 write_str(w, " ") ? ;
1386 out_sort.sort_to_smt2(w) ? ;
1387 write_str(w, ")\n") ?
1388 }
1389 }
1390 Ok(())
1391 }
1392
1393 #[inline]
1395 pub fn declare_fun_with<'a, Info, FunSym, ArgSort, Args, OutSort>(
1396 &mut self,
1397 symbol: &FunSym,
1398 args: Args,
1399 out: &OutSort,
1400 info: Info,
1401 ) -> SmtRes<()>
1402 where
1403 Info: Copy,
1404 FunSym: ?Sized + Sym2Smt<Info>,
1405 ArgSort: ?Sized + Sort2Smt + 'a,
1406 OutSort: ?Sized + Sort2Smt,
1407 Args: IntoIterator<Item = &'a ArgSort>,
1408 {
1409 tee_write! {
1410 self, |w| {
1411 write_str(w, "(declare-fun ") ? ;
1412 symbol.sym_to_smt2(w, info) ? ;
1413 write_str(w, " ( ") ?
1414 }
1415 }
1416 for arg in args {
1417 tee_write! {
1418 self, |w| {
1419 arg.sort_to_smt2(w) ? ;
1420 write_str(w, " ") ?
1421 }
1422 }
1423 }
1424 tee_write! {
1425 self, |w| {
1426 write_str(w, ") ") ? ;
1427 out.sort_to_smt2(w) ? ;
1428 write_str(w, ")\n") ?
1429 }
1430 }
1431 Ok(())
1432 }
1433
1434 #[inline]
1436 pub fn define_const_with<Info, Sym, Sort, Body>(
1437 &mut self,
1438 symbol: &Sym,
1439 out_sort: &Sort,
1440 body: &Body,
1441 info: Info,
1442 ) -> SmtRes<()>
1443 where
1444 Info: Copy,
1445 Sym: ?Sized + Sym2Smt<Info>,
1446 Sort: ?Sized + Sort2Smt,
1447 Body: ?Sized + Expr2Smt<Info>,
1448 {
1449 tee_write! {
1450 self, |w| {
1451 write_str(w, "(define-const ") ? ;
1452 symbol.sym_to_smt2(w, info) ? ;
1453 write_str(w, " ") ? ;
1454 out_sort.sort_to_smt2(w) ? ;
1455 write_str(w, " ") ? ;
1456 body.expr_to_smt2(w, info) ? ;
1457 write_str(w, ")\n") ?
1458 }
1459 }
1460 Ok(())
1461 }
1462
1463 #[inline]
1465 pub fn define_fun_with<'a, Info, FunSym, ArgSym, ArgSort, Args, OutSort, Body>(
1466 &mut self,
1467 symbol: &FunSym,
1468 args: Args,
1469 out: &OutSort,
1470 body: &Body,
1471 info: Info,
1472 ) -> SmtRes<()>
1473 where
1474 Info: Copy,
1475 ArgSort: Sort2Smt + 'a,
1476 OutSort: ?Sized + Sort2Smt,
1477 FunSym: ?Sized + Sym2Smt<Info>,
1478 ArgSym: Sym2Smt<Info> + 'a,
1479 Body: ?Sized + Expr2Smt<Info>,
1480 Args: IntoIterator<Item = &'a (ArgSym, ArgSort)>,
1481 {
1482 tee_write! {
1483 self, |w| {
1484 write_str(w, "(define-fun ") ? ;
1485 symbol.sym_to_smt2(w, info) ? ;
1486 write_str(w, " ( ") ?
1487 }
1488 }
1489 for arg in args {
1490 let (ref sym, ref sort) = *arg;
1491 tee_write! {
1492 self, |w| {
1493 write_str(w, "(") ? ;
1494 sym.sym_to_smt2(w, info) ? ;
1495 write_str(w, " ") ? ;
1496 sort.sort_to_smt2(w) ? ;
1497 write_str(w, ") ") ?
1498 }
1499 }
1500 }
1501 tee_write! {
1502 self, |w| {
1503 write_str(w, ") ") ? ;
1504 out.sort_to_smt2(w) ? ;
1505 write_str(w, "\n ") ? ;
1506 body.expr_to_smt2(w, info) ? ;
1507 write_str(w, "\n)\n") ?
1508 }
1509 }
1510 Ok(())
1511 }
1512
1513 #[inline]
1515 pub fn define_funs_rec_with<
1516 'a,
1517 Info,
1518 FunSym,
1519 ArgSym,
1520 ArgSort,
1521 Args,
1522 ArgsRef,
1523 OutSort,
1524 Body,
1525 Funs,
1526 >(
1527 &mut self,
1528 funs: Funs,
1529 info: Info,
1530 ) -> SmtRes<()>
1531 where
1532 Info: Copy,
1533 FunSym: Sym2Smt<Info> + 'a,
1534 ArgSym: Sym2Smt<Info> + 'a,
1535 ArgSort: Sort2Smt + 'a,
1536 OutSort: Sort2Smt + 'a,
1537 Body: Expr2Smt<Info> + 'a,
1538 &'a Args: IntoIterator<Item = &'a (ArgSym, ArgSort)> + 'a,
1539 Args: ?Sized,
1540 ArgsRef: 'a + AsRef<Args>,
1541 Funs: IntoIterator<Item = &'a (FunSym, ArgsRef, OutSort, Body)>,
1542 Funs::IntoIter: Clone,
1543 {
1544 tee_write! {
1546 self, |w| write_str(w, "(define-funs-rec (\n") ?
1547 }
1548
1549 let fun_iter = funs.into_iter();
1550
1551 for fun in fun_iter.clone() {
1553 let (ref sym, ref args, ref out, _) = *fun;
1554
1555 tee_write! {
1556 self, |w| {
1557 write_str(w, " (") ? ;
1558 sym.sym_to_smt2(w, info) ? ;
1559 write_str(w, " ( ") ?
1560 }
1561 }
1562
1563 for arg in args.as_ref() {
1564 tee_write! {
1565 self, |w| {
1566 let (ref sym, ref sort) = * arg ;
1567 write_str(w, "(") ? ;
1568 sym.sym_to_smt2(w, info) ? ;
1569 write_str(w, " ") ? ;
1570 sort.sort_to_smt2(w) ? ;
1571 write_str(w, ") ") ?
1572 }
1573 }
1574 }
1575
1576 tee_write! {
1577 self, |w| {
1578 write_str(w, ") ") ? ;
1579 out.sort_to_smt2(w) ? ;
1580 write_str(w, ")\n") ?
1581 }
1582 }
1583 }
1584 tee_write! {
1585 self, |w| write_str(w, " ) (") ?
1586 }
1587
1588 for fun in fun_iter {
1590 let (_, _, _, ref body) = *fun;
1591 tee_write! {
1592 self, |w| {
1593 write_str(w, "\n ") ? ;
1594 body.expr_to_smt2(w, info) ?
1595 }
1596 }
1597 }
1598 tee_write! {
1599 self, |w| write_str(w, "\n )\n)\n") ?
1600 }
1601 Ok(())
1602 }
1603
1604 #[inline]
1606 pub fn define_fun_rec_with<'a, Info, FunSym, ArgSym, ArgSort, Args, OutSort, Body>(
1607 &mut self,
1608 symbol: &FunSym,
1609 args: Args,
1610 out: &OutSort,
1611 body: &Body,
1612 info: Info,
1613 ) -> SmtRes<()>
1614 where
1615 Info: Copy,
1616 ArgSort: Sort2Smt + 'a,
1617 OutSort: ?Sized + Sort2Smt,
1618 FunSym: ?Sized + Sym2Smt<Info>,
1619 ArgSym: Sym2Smt<Info> + 'a,
1620 Body: ?Sized + Expr2Smt<Info>,
1621 Args: IntoIterator<Item = &'a (ArgSym, ArgSort)>,
1622 {
1623 tee_write! {
1625 self, |w| write_str(w, "(define-fun-rec (\n") ?
1626 }
1627
1628 tee_write! {
1629 self, |w| {
1630 write_str(w, " (") ? ;
1632 symbol.sym_to_smt2(w, info) ? ;
1633 write_str(w, " ( ") ?
1634 }
1635 }
1636
1637 for arg in args {
1638 let (ref sym, ref sort) = *arg;
1639 tee_write! {
1640 self, |w| {
1641 write_str(w, "(") ? ;
1642 sym.sym_to_smt2(w, info) ? ;
1643 write_str(w, " ") ? ;
1644 sort.sort_to_smt2(w) ? ;
1645 write_str(w, ") ") ?
1646 }
1647 }
1648 }
1649
1650 tee_write! {
1651 self, |w| {
1652 write_str(w, ") ") ? ;
1653 out.sort_to_smt2(w) ? ;
1654 write_str(w, ")\n") ? ;
1655 write_str(w, " ) (") ? ;
1656
1657 write_str(w, "\n ") ? ;
1659 body.expr_to_smt2(w, info) ? ;
1660 write_str(w, "\n )\n)\n") ?
1661 }
1662 }
1663 Ok(())
1664 }
1665
1666 #[inline]
1672 pub fn assert_act_with<Info, Expr>(
1673 &mut self,
1674 actlit: &Actlit,
1675 expr: &Expr,
1676 info: Info,
1677 ) -> SmtRes<()>
1678 where
1679 Info: Copy,
1680 Expr: ?Sized + Expr2Smt<Info>,
1681 {
1682 tee_write! {
1683 self, |w| {
1684 write_str(w, "(assert\n (=>\n ") ? ;
1685 actlit.write(w) ? ;
1686 write_str(w, "\n ") ? ;
1687 expr.expr_to_smt2(w, info) ? ;
1688 write_str(w, "\n )\n)\n") ?
1689 }
1690 }
1691 Ok(())
1692 }
1693
1694 #[inline]
1696 pub fn assert_with<Info, Expr>(&mut self, expr: &Expr, info: Info) -> SmtRes<()>
1697 where
1698 Info: Copy,
1699 Expr: ?Sized + Expr2Smt<Info>,
1700 {
1701 tee_write! {
1702 self, |w| {
1703 write_str(w, "(assert\n ") ? ;
1704 expr.expr_to_smt2(w, info) ? ;
1705 write_str(w, "\n)\n") ?
1706 }
1707 }
1708 Ok(())
1709 }
1710
1711 pub fn check_sat_assuming_with<'a, Info, Ident, Idents>(
1713 &mut self,
1714 idents: Idents,
1715 info: Info,
1716 ) -> SmtRes<bool>
1717 where
1718 Info: Copy,
1719 Ident: ?Sized + Sym2Smt<Info> + 'a,
1720 Idents: IntoIterator<Item = &'a Ident>,
1721 {
1722 let future = self.print_check_sat_assuming_with(idents, info)?;
1723 self.parse_check_sat(future)
1724 }
1725
1726 pub fn check_sat_assuming_or_unk_with<'a, Info, Ident, Idents>(
1728 &mut self,
1729 idents: Idents,
1730 info: Info,
1731 ) -> SmtRes<Option<bool>>
1732 where
1733 Info: Copy,
1734 Ident: ?Sized + Sym2Smt<Info> + 'a,
1735 Idents: IntoIterator<Item = &'a Ident>,
1736 {
1737 let future = self.print_check_sat_assuming_with(idents, info)?;
1738 self.parse_check_sat_or_unk(future)
1739 }
1740}
1741
1742impl<Parser> Solver<Parser> {
1744 #[inline]
1746 pub fn set_option<Value: ::std::fmt::Display>(
1747 &mut self,
1748 option: &str,
1749 value: Value,
1750 ) -> SmtRes<()> {
1751 match option {
1752 ":interactive_mode" => return Err("illegal set-option on interactive mode".into()),
1753 ":print_success" => {
1754 return Err("illegal set-option on print success, \
1755 use `SmtConf` to activate it"
1756 .into())
1757 }
1758 _ => (),
1759 };
1760 tee_write! {
1761 self, |w| writeln!(
1762 w, "(set-option {} {})", option, value
1763 ) ?
1764 }
1765 Ok(())
1766 }
1767
1768 #[inline]
1770 pub fn produce_unsat_core(&mut self) -> SmtRes<()> {
1771 self.set_option(":produce-unsat-cores", "true")
1772 }
1773
1774 #[inline]
1776 pub fn reset_assertions(&mut self) -> SmtRes<()> {
1777 tee_write! {
1778 self, |w| write_str(w, "(reset-assertions)\n") ?
1779 }
1780 Ok(())
1781 }
1782
1783 #[inline]
1787 pub fn get_info(&mut self, flag: &str) -> SmtRes<()> {
1788 tee_write! {
1789 self, |w| writeln!(w, "(get-info {})", flag) ?
1790 }
1791 Ok(())
1792 }
1793 #[inline]
1795 pub fn get_option(&mut self, option: &str) -> SmtRes<()> {
1796 tee_write! {
1797 self, |w| writeln!(w, "(get-option {})", option) ?
1798 }
1799 Ok(())
1800 }
1801
1802 #[inline]
1806 pub fn set_info(&mut self, attribute: &str) -> SmtRes<()> {
1807 tee_write! {
1808 self, |w| writeln!(w, "(set-info {})", attribute) ?
1809 }
1810 Ok(())
1811 }
1812 #[inline]
1814 pub fn echo(&mut self, text: &str) -> SmtRes<()> {
1815 tee_write! {
1816 self, |w| writeln!(w, "(echo \"{}\")", text) ?
1817 }
1818 Ok(())
1819 }
1820}