1use super::syntax::{*, Term::*, Formula::*};
3use std::collections::HashMap;
4use std::cmp::Ordering::Equal;
5use itertools::Itertools;
6
7pub trait Substitution {
9 fn apply(&self, v: &V) -> Term;
13}
14
15impl<F> Substitution for F
20 where F: Fn(&V) -> Term {
21 fn apply(&self, v: &V) -> Term {
22 self(v)
23 }
24}
25
26impl Substitution for HashMap<&V, Term> {
31 fn apply(&self, v: &V) -> Term {
32 self.get(v)
33 .map(|t| t.clone())
34 .unwrap_or(v.clone().into())
35 }
36}
37
38pub trait VariableRenaming {
44 fn apply(&self, v: &V) -> V;
48}
49
50impl<F> VariableRenaming for F
55 where F: Fn(&V) -> V {
56 fn apply(&self, v: &V) -> V {
57 self(v)
58 }
59}
60
61impl VariableRenaming for HashMap<&V, V> {
66 fn apply(&self, v: &V) -> V {
67 self.get(v)
68 .map(|var| var.clone())
69 .unwrap_or(v.clone().into())
70 }
71}
72
73pub trait TermBased {
77 fn transform(&self, f: &impl Fn(&Term) -> Term) -> Self;
81
82 fn rename_vars(&self, renaming: &impl VariableRenaming) -> Self;
116
117 fn substitute(&self, sub: &impl Substitution) -> Self;
149}
150
151impl TermBased for Term {
152 fn transform(&self, f: &impl Fn(&Term) -> Term) -> Self {
153 f(self)
154 }
155
156 fn rename_vars(&self, renaming: &impl VariableRenaming) -> Self {
157 match self {
158 Const { .. } => self.clone(),
159 Var { variable: v } => Term::from(renaming.apply(v)),
160 App { function, terms } => {
161 let terms = terms.iter()
162 .map(|t| t.rename_vars(renaming))
163 .collect();
164 function.clone().app(terms)
165 }
166 }
167 }
168
169 fn substitute(&self, sub: &impl Substitution) -> Self {
170 match self {
171 Const { .. } => self.clone(),
172 Var { variable: v } => sub.apply(v),
173 App { function, terms } => {
174 let terms = terms.iter()
175 .map(|t| t.substitute(sub))
176 .collect();
177 function.clone().app(terms)
178 }
179 }
180 }
181}
182
183impl TermBased for Formula {
184 #[inline]
185 fn transform(&self, f: &impl Fn(&Term) -> Term) -> Self {
186 match self {
187 Top | Bottom => self.clone(),
188 Atom { predicate, terms } => predicate.clone()
189 .app(terms.iter()
190 .map(f)
191 .collect()
192 ),
193 Equals { left, right } => f(left).equals(f(right)),
194 Not { formula } => not(formula.transform(f)),
195 And { left, right } => left
196 .transform(f)
197 .and(right.transform(f)),
198 Or { left, right } => left
199 .transform(f)
200 .or(right.transform(f)),
201 Implies { left, right } => left
202 .transform(f)
203 .implies(right.transform(f)),
204 Iff { left, right } => left
205 .transform(f)
206 .iff(right.transform(f)),
207 Exists { variables, formula } => exists(
208 variables.clone(),
209 formula.transform(f),
210 ),
211 Forall { variables, formula } => forall(
212 variables.clone(),
213 formula.transform(f),
214 ),
215 }
216 }
217
218 fn rename_vars(&self, renaming: &impl VariableRenaming) -> Self {
223 self.transform(&|t: &Term| t.rename_vars(renaming))
225 }
226
227 fn substitute(&self, substitution: &impl Substitution) -> Self {
232 self.transform(&|t: &Term| t.substitute(substitution))
233 }
234}
235
236#[derive(PartialEq, Debug)]
242pub struct SkolemGenerator {
243 prefix: String,
245 index: i32,
247}
248
249impl SkolemGenerator {
250 pub fn new() -> Self {
252 Self {
253 prefix: "sk#".to_owned(),
254 index: 0,
255 }
256 }
257
258 pub fn next(&mut self) -> String {
260 let result = format!("{}{}", self.prefix, self.index);
261 self.index += 1;
262 result
263 }
264}
265
266impl From<&str> for SkolemGenerator {
267 fn from(prefix: &str) -> Self {
269 Self {
270 prefix: prefix.to_owned(),
271 index: 0,
272 }
273 }
274}
275
276impl Formula {
277 pub fn pnf(&self) -> Formula {
290 fn rename(variable: &V, no_collision_variables: &Vec<&V>) -> V {
293 let mut name = variable.0.clone();
294 let names: Vec<&String> = no_collision_variables
295 .into_iter()
296 .map(|v| &v.0)
297 .collect();
298 while names.contains(&&name) {
299 name.push_str("`")
300 }
301 return V::from(&name);
302 }
303
304 fn shared_variables<'a>(quantifier_vars: &'a Vec<V>, other_vars: &Vec<&V>) -> Vec<&'a V> {
306 quantifier_vars.iter()
307 .filter(|v| other_vars.contains(v))
308 .collect()
309 }
310
311 match self {
312 Top | Bottom | Atom { .. } | Equals { .. } => self.clone(),
313 Not { formula } => {
315 let formula = formula.pnf();
316 match formula {
317 Forall { variables, formula } => exists(
318 variables,
319 not(*formula).pnf(),
320 ),
321 Exists { variables, formula } => forall(
322 variables,
323 not(*formula).pnf(),
324 ),
325 _ => not(formula)
326 }
327 }
328 And { left, right } => {
330 let left = left.pnf();
331 let right = right.pnf();
332 let left_free_variables = left.free_vars();
333 let right_free_variables = right.free_vars();
334 let mut all_free_variables = right_free_variables.clone();
335 all_free_variables.append(&mut left_free_variables.clone());
336
337 if let Forall { ref variables, ref formula } = left {
338 let shared_vars = shared_variables(variables, &right_free_variables);
339 let mut all_vars: Vec<&V> = variables.iter().collect();
340 all_vars.append(&mut all_free_variables);
341
342 let renaming = |v: &V| if shared_vars.contains(&v) {
343 rename(v, &all_vars)
344 } else {
345 v.clone()
346 };
347 let variables: Vec<V> = variables.iter().map(&renaming).collect();
348 let formula = formula.rename_vars(&renaming);
349 forall(variables, formula.and(right)).pnf()
350 } else if let Exists { ref variables, ref formula } = left {
351 let shared_vars = shared_variables(variables, &right_free_variables);
352 let mut all_vars: Vec<&V> = variables.iter().collect();
353 all_vars.append(&mut all_free_variables);
354
355 let renaming = |v: &V| if shared_vars.contains(&v) {
356 rename(v, &all_vars)
357 } else {
358 v.clone()
359 };
360 let variables: Vec<V> = variables.iter().map(&renaming).collect();
361 let formula = formula.rename_vars(&renaming);
362 exists(variables, formula.and(right)).pnf()
363 } else if let Forall { ref variables, ref formula } = right {
364 let shared_vars = shared_variables(variables, &left_free_variables);
365 let mut all_vars: Vec<&V> = variables.iter().collect();
366 all_vars.append(&mut all_free_variables);
367
368 let renaming = |v: &V| if shared_vars.contains(&v) {
369 rename(v, &all_vars)
370 } else {
371 v.clone()
372 };
373 let variables: Vec<V> = variables.iter().map(&renaming).collect();
374 let formula = formula.rename_vars(&renaming);
375 forall(variables, left.and(formula)).pnf()
376 } else if let Exists { ref variables, ref formula } = right {
377 let shared_vars = shared_variables(variables, &left_free_variables);
378 let mut all_vars: Vec<&V> = variables.iter().collect();
379 all_vars.append(&mut all_free_variables);
380
381 let renaming = |v: &V| if shared_vars.contains(&v) {
382 rename(v, &all_vars)
383 } else {
384 v.clone()
385 };
386 let variables: Vec<V> = variables.iter().map(&renaming).collect();
387 let formula = formula.rename_vars(&renaming);
388 exists(variables, left.and(formula)).pnf()
389 } else {
390 And { left: Box::new(left), right: Box::new(right) }
391 }
392 }
393 Or { left, right } => {
395 let left = left.pnf();
396 let right = right.pnf();
397 let left_free_variables = left.free_vars();
398 let right_free_variables = right.free_vars();
399 let mut all_free_variables = right_free_variables.clone();
400 all_free_variables.append(&mut left_free_variables.clone());
401
402 if let Forall { ref variables, ref formula } = left {
403 let shared_vars = shared_variables(variables, &right_free_variables);
404 let mut all_vars: Vec<&V> = variables.iter().collect();
405 all_vars.append(&mut all_free_variables);
406
407 let renaming = |v: &V| if shared_vars.contains(&v) {
408 rename(v, &all_vars)
409 } else {
410 v.clone()
411 };
412 let variables: Vec<V> = variables.iter().map(&renaming).collect();
413 let formula = formula.rename_vars(&renaming);
414 forall(variables, formula.or(right)).pnf()
415 } else if let Exists { ref variables, ref formula } = left {
416 let shared_vars = shared_variables(variables, &right_free_variables);
417 let mut all_vars: Vec<&V> = variables.iter().collect();
418 all_vars.append(&mut all_free_variables);
419
420 let renaming = |v: &V| if shared_vars.contains(&v) {
421 rename(v, &all_vars)
422 } else {
423 v.clone()
424 };
425 let variables: Vec<V> = variables.iter().map(&renaming).collect();
426 let formula = formula.rename_vars(&renaming);
427 exists(variables, formula.or(right)).pnf()
428 } else if let Forall { ref variables, ref formula } = right {
429 let shared_vars = shared_variables(variables, &left_free_variables);
430 let mut all_vars: Vec<&V> = variables.iter().collect();
431 all_vars.append(&mut all_free_variables);
432
433 let renaming = |v: &V| if shared_vars.contains(&v) {
434 rename(v, &all_vars)
435 } else {
436 v.clone()
437 };
438 let variables: Vec<V> = variables.iter().map(&renaming).collect();
439 let formula = formula.rename_vars(&renaming);
440 forall(variables, left.or(formula)).pnf()
441 } else if let Exists { ref variables, ref formula } = right {
442 let shared_vars = shared_variables(variables, &left_free_variables);
443 let mut all_vars: Vec<&V> = variables.iter().collect();
444 all_vars.append(&mut all_free_variables);
445
446 let renaming = |v: &V| if shared_vars.contains(&v) {
447 rename(v, &all_vars)
448 } else {
449 v.clone()
450 };
451 let variables: Vec<V> = variables.iter().map(&renaming).collect();
452 let formula = formula.rename_vars(&renaming);
453 exists(variables, left.or(formula)).pnf()
454 } else {
455 Or { left: Box::new(left), right: Box::new(right) }
456 }
457 }
458 Implies { left, right } => {
460 let left = left.pnf();
461 let right = right.pnf();
462 let left_free_variables = left.free_vars();
463 let right_free_variables = right.free_vars();
464 let mut all_free_variables = right_free_variables.clone();
465 all_free_variables.append(&mut left_free_variables.clone());
466
467 if let Forall { ref variables, ref formula } = left {
468 let shared_vars = shared_variables(variables, &right_free_variables);
469 let mut all_vars: Vec<&V> = variables.iter().collect();
470 all_vars.append(&mut all_free_variables);
471
472 let renaming = |v: &V| if shared_vars.contains(&v) {
473 rename(v, &all_vars)
474 } else {
475 v.clone()
476 };
477 let variables: Vec<V> = variables.iter().map(&renaming).collect();
478 let formula = formula.rename_vars(&renaming);
479 exists(variables, formula.implies(right)).pnf()
480 } else if let Exists { ref variables, ref formula } = left {
481 let shared_vars = shared_variables(variables, &right_free_variables);
482 let mut all_vars: Vec<&V> = variables.iter().collect();
483 all_vars.append(&mut all_free_variables);
484
485 let renaming = |v: &V| if shared_vars.contains(&v) {
486 rename(v, &all_vars)
487 } else {
488 v.clone()
489 };
490 let variables: Vec<V> = variables.iter().map(&renaming).collect();
491 let formula = formula.rename_vars(&renaming);
492 forall(variables, formula.implies(right)).pnf()
493 } else if let Forall { ref variables, ref formula } = right {
494 let shared_vars = shared_variables(variables, &left_free_variables);
495 let mut all_vars: Vec<&V> = variables.iter().collect();
496 all_vars.append(&mut all_free_variables);
497
498 let renaming = |v: &V| if shared_vars.contains(&v) {
499 rename(v, &all_vars)
500 } else {
501 v.clone()
502 };
503 let variables: Vec<V> = variables.iter().map(&renaming).collect();
504 let formula = formula.rename_vars(&renaming);
505 forall(variables, left.implies(formula)).pnf()
506 } else if let Exists { ref variables, ref formula } = right {
507 let shared_vars = shared_variables(variables, &left_free_variables);
508 let mut all_vars: Vec<&V> = variables.iter().collect();
509 all_vars.append(&mut all_free_variables);
510
511 let renaming = |v: &V| if shared_vars.contains(&v) {
512 rename(v, &all_vars)
513 } else {
514 v.clone()
515 };
516 let variables: Vec<V> = variables.iter().map(&renaming).collect();
517 let formula = formula.rename_vars(&renaming);
518 exists(variables, left.implies(formula)).pnf()
519 } else {
520 Implies { left: Box::new(left), right: Box::new(right) }
521 }
522 }
523 Iff { left, right } => left.clone()
524 .implies(*right.clone())
525 .and(right.clone().implies(*left.clone())
526 ).pnf(),
527 Exists { variables, formula } => exists(
528 variables.clone(),
529 formula.pnf(),
530 ),
531 Forall { variables, formula } => forall(
532 variables.clone(),
533 formula.pnf(),
534 ),
535 }
536 }
537
538 pub fn snf(&self) -> Formula {
553 self.snf_with(&mut SkolemGenerator::new())
554 }
555
556 pub fn snf_with(&self, generator: &mut SkolemGenerator) -> Formula {
573 fn helper(formula: Formula, mut skolem_vars: Vec<V>, generator: &mut SkolemGenerator) -> Formula {
574 match formula {
575 Forall { variables, formula } => {
576 skolem_vars.append(&mut variables.clone());
577 forall(variables, helper(*formula, skolem_vars, generator))
578 }
579 Exists { variables, formula } => {
580 let mut map: HashMap<&V, Term> = HashMap::new();
581
582 variables.iter().for_each(|v| if skolem_vars.is_empty() {
583 map.insert(&v, C::from(&generator.next()).into());
584 } else {
585 let vars: Vec<Term> = skolem_vars
586 .iter()
587 .map(|v| v.clone().into())
588 .collect();
589 map.insert(&v, F::from(&generator.next()).app(vars));
590 });
591
592 let substituted = formula.substitute(&map);
593 helper(substituted, skolem_vars, generator)
594 }
595 _ => formula
596 }
597 }
598
599 let free_vars: Vec<V> = self.free_vars()
601 .into_iter()
602 .map(|v| v.clone())
603 .collect();
604 helper(self.pnf(), free_vars, generator)
605 }
606
607 pub fn nnf(&self) -> Formula {
620 match self {
621 Top | Bottom | Atom { .. } | Equals { .. } => self.clone(),
622 Not { ref formula } => {
623 match **formula {
624 Top => Bottom,
625 Bottom => Top,
626 Atom { .. } | Equals { .. } => self.clone(),
627 Not { ref formula } => *formula.clone(),
628 And { ref left, ref right } => not(*left.clone())
629 .nnf()
630 .or(not(*right.clone())
631 .nnf()),
632 Or { ref left, ref right } => not(*left.clone())
633 .nnf()
634 .and(not(*right.clone())
635 .nnf()),
636 Implies { ref left, ref right } => left.nnf()
637 .and(not(*right.clone())
638 .nnf()),
639 Iff { ref left, ref right } => left.nnf()
640 .and(not(*right.clone())
641 .nnf())
642 .or(not(*left.clone())
643 .nnf()
644 .and(right.nnf())),
645 Exists { ref variables, ref formula } => forall(
646 variables.clone(),
647 not(*formula.clone()).nnf(),
648 ),
649 Forall { ref variables, ref formula } => exists(
650 variables.clone(),
651 not(*formula.clone()).nnf(),
652 ),
653 }
654 }
655 And { left, right } => left.nnf().and(right.nnf()),
656 Or { left, right } => left.nnf().or(right.nnf()),
657 Implies { left, right } => not(*left.clone())
658 .nnf()
659 .or(right.nnf()),
660 Iff { left, right } => not(*left.clone())
661 .nnf()
662 .or(right.nnf())
663 .and(left.nnf()
664 .or(not(*right.clone())
665 .nnf())),
666 Exists { variables, formula } => exists(
667 variables.clone(),
668 formula.nnf(),
669 ),
670 Forall { variables, formula } => forall(
671 variables.clone(),
672 formula.nnf(),
673 ),
674 }
675 }
676
677 pub fn cnf(&self) -> Formula {
692 self.cnf_with(&mut SkolemGenerator::new())
693 }
694
695 pub fn cnf_with(&self, generator: &mut SkolemGenerator) -> Formula {
714 fn distribute_or(formula: &Formula) -> Formula {
717 match formula {
718 Top | Bottom | Atom { .. } | Equals { .. } | Not { .. } => formula.clone(),
719 And { left, right } => distribute_or(left)
720 .and(distribute_or(right)),
721 Or { left, right } => {
722 let left = distribute_or(left);
723 let right = distribute_or(right);
724 if let And { left: l, right: r } = left {
725 distribute_or(&l.or(right.clone()))
726 .and(distribute_or(&r.or(right)))
727 } else if let And { left: l, right: r } = right {
728 distribute_or(&left.clone().or(*l)).and(
729 distribute_or(&left.or(*r)))
730 } else {
731 left.or(right)
732 }
733 }
734 Forall { variables, formula } => forall(
735 variables.clone(),
736 distribute_or(formula),
737 ),
738 _ => panic!("something is wrong: expecting a formula in negation normal form")
739 }
740 }
741
742 fn remove_forall(formula: Formula) -> Formula {
744 if let Forall { formula, .. } = formula {
745 remove_forall(*formula)
746 } else {
747 formula
748 }
749 }
750
751 let nnf = self.snf_with(generator).nnf();
752 remove_forall(distribute_or(&nnf))
753 }
754
755 pub fn dnf(&self) -> Formula {
771 self.dnf_with(&mut SkolemGenerator::new())
772 }
773
774 pub fn dnf_with(&self, generator: &mut SkolemGenerator) -> Formula {
793 fn distribute_and(formula: &Formula) -> Formula {
796 match formula {
797 Top | Bottom | Atom { .. } | Equals { .. } | Not { .. } => formula.clone(),
798 Or { left, right } => distribute_and(left)
799 .or(distribute_and(right)),
800 And { left, right } => {
801 let left = distribute_and(left);
802 let right = distribute_and(right);
803 if let Or { left: l, right: r } = left {
804 distribute_and(&l.and(right.clone()))
805 .or(distribute_and(&r.and(right)))
806 } else if let Or { left: l, right: r } = right {
807 distribute_and(&left.clone().and(*l))
808 .or(distribute_and(&left.and(*r)))
809 } else {
810 And { left: Box::new(left), right: Box::new(right) }
811 }
812 }
813 Forall { variables, formula } => forall(
814 variables.clone(),
815 distribute_and(formula),
816 ),
817 _ => panic!("Something is wrong: expecting a formula in negation normal form.")
818 }
819 }
820
821 fn remove_forall(formula: Formula) -> Formula {
823 if let Forall { formula, .. } = formula {
824 remove_forall(*formula)
825 } else {
826 formula
827 }
828 }
829
830 let nnf = self.snf_with(generator).nnf();
831 remove_forall(distribute_and(&nnf))
832 }
833
834 pub fn simplify(&self) -> Formula {
847 match self {
848 Top | Bottom | Atom { .. } | Equals { .. } => self.clone(),
849 Not { formula } => {
850 let formula = formula.simplify();
851 match formula {
852 Top => Bottom,
853 Bottom => Top,
854 Not { formula } => formula.simplify(),
855 _ => not(formula)
856 }
857 }
858 And { left, right } => {
859 let left = left.simplify();
860 let right = right.simplify();
861 if let Bottom = left {
862 Bottom
863 } else if let Bottom = right {
864 Bottom
865 } else if let Top = left {
866 right
867 } else if let Top = right {
868 left
869 } else {
870 left.and(right)
871 }
872 }
873 Or { left, right } => {
874 let left = left.simplify();
875 let right = right.simplify();
876 if let Top = left {
877 Top
878 } else if let Top = right {
879 Top
880 } else if let Bottom = left {
881 right
882 } else if let Bottom = right {
883 left
884 } else {
885 left.or(right)
886 }
887 }
888 Implies { left, right } => {
889 let left = left.simplify();
890 let right = right.simplify();
891 if let Bottom = left {
892 Top
893 } else if let Top = right {
894 Top
895 } else if let Top = left {
896 right
897 } else if let Bottom = right {
898 not(left).simplify()
899 } else {
900 left.implies(right)
901 }
902 }
903 Iff { left, right } => {
904 let left = left.simplify();
905 let right = right.simplify();
906 if let Top = left {
907 right
908 } else if let Top = right {
909 left
910 } else if let Bottom = left {
911 not(right).simplify()
912 } else if let Bottom = right {
913 not(left).simplify()
914 } else {
915 left.iff(right)
916 }
917 }
918 Exists { variables, formula } => {
919 let formula = formula.simplify();
920 let free_vars = formula.free_vars();
921 let vs: Vec<V> = free_vars.iter()
922 .filter(|v| variables.contains(v))
923 .map(|v| (*v).clone())
924 .collect();
925 if vs.is_empty() {
926 formula
927 } else {
928 exists(vs, formula)
929 }
930 }
931 Forall { variables, formula } => {
932 let formula = formula.simplify();
933 let free_vars = formula.free_vars();
934 let vs: Vec<V> = free_vars.iter()
935 .filter(|v| variables.contains(v))
936 .map(|v| (*v).clone())
937 .collect();
938 if vs.is_empty() {
939 formula
940 } else {
941 forall(vs, formula)
942 }
943 }
944 }
945 }
946
947 pub fn gnf(&self) -> Vec<Formula> {
966 self.gnf_with(&mut SkolemGenerator::new())
967 }
968
969 pub fn gnf_with(&self, generator: &mut SkolemGenerator) -> Vec<Formula> {
988 fn split_sides(disjunct: Formula) -> (Vec<Formula>, Vec<Formula>) {
991 match disjunct {
992 Or { left, right } => {
993 let (mut left_body, mut left_head) = split_sides(*left);
994 let (mut right_body, mut right_head) = split_sides(*right);
995
996 left_body.append(&mut right_body);
997 let body: Vec<Formula> = left_body.into_iter().unique().collect();
998
999 left_head.append(&mut right_head);
1000 let head: Vec<Formula> = left_head.into_iter().unique().collect();
1001
1002 (body, head)
1003 }
1004 Not { formula } => (vec![*formula], vec![]),
1005 _ => (vec![], vec![disjunct])
1006 }
1007 }
1008
1009 fn to_implication(disjunct: Formula) -> Formula {
1011 let (body, head) = split_sides(disjunct);
1012 let body = body
1013 .into_iter()
1014 .fold(Top, |x, y| x.and(y))
1015 .simplify();
1016 let head = head
1017 .into_iter()
1018 .fold(Bottom, |x, y| x.or(y))
1019 .simplify();
1020 body.implies(head)
1021 }
1022
1023 fn get_disjuncts(cnf: Formula) -> Vec<Formula> {
1025 match cnf {
1026 And { left, right } => {
1027 let mut left = get_disjuncts(*left);
1028 let mut right = get_disjuncts(*right);
1029 left.append(&mut right);
1030 left.into_iter().unique().collect()
1031 }
1032 _ => vec![cnf]
1033 }
1034 }
1035
1036 get_disjuncts(self.cnf_with(generator))
1037 .into_iter()
1038 .map(to_implication)
1039 .collect()
1040 }
1041}
1042
1043impl Theory {
1044 pub fn gnf(&self) -> Theory {
1066 let mut generator = SkolemGenerator::new();
1067 let formulae: Vec<Formula> = self.formulae
1068 .iter()
1069 .flat_map(|f| f.gnf_with(&mut generator))
1070 .collect();
1071 Theory::from(compress_geometric(formulae))
1072 }
1073}
1074
1075fn compress_geometric(formulae: Vec<Formula>) -> Vec<Formula> {
1077 formulae.into_iter().sorted_by(|f1, f2| { match (f1, f2) {
1079 (Implies { left: f1, .. }, Implies { left: f2, .. }) => f1.cmp(f2),
1080 _ => Equal
1081 }
1082 }).into_iter().coalesce(|f1, f2| { match f1 {
1084 Implies { left: ref l1, right: ref r1 } => {
1085 let l_vars = l1.free_vars();
1086 let r_vars = r1.free_vars();
1087 if r_vars.iter().all(|rv| l_vars
1089 .iter()
1090 .any(|lv| lv == rv)) {
1091 match f2 {
1092 Implies { left: ref l2, right: ref r2 } => {
1093 let l_vars = l2.free_vars();
1094 let r_vars = r2.free_vars();
1095 if r_vars.iter().all(|rv| l_vars
1096 .iter()
1097 .any(|lv| lv == rv)) {
1098 if l1 == l2 {
1099 Ok(l2.clone().implies(r1.clone().and(*r2.clone())))
1100 } else {
1101 Err((f1, f2))
1102 }
1103 } else {
1104 Err((f2, f1))
1105 }
1106 }
1107 _ => Err((f2, f1))
1108 }
1109 } else {
1110 Err((f1, f2))
1111 }
1112 }
1113 _ => Err((f1, f2))
1114 }
1115 }).map(|f| { match f {
1117 Implies { left, right: r } => left.implies(simplify_dnf(r.dnf())),
1118 _ => f
1119 }
1120 }).collect()
1121}
1122
1123fn simplify_dnf(formula: Formula) -> Formula {
1125 fn disjunct_list(formula: Formula) -> Vec<Formula> {
1126 match formula {
1127 Or { left, right } => {
1128 let mut lefts = disjunct_list(*left);
1129 let mut rights = disjunct_list(*right);
1130 lefts.append(&mut rights);
1131 lefts
1132 }
1133 _ => vec![formula],
1134 }
1135 }
1136
1137 fn conjunct_list(formula: Formula) -> Vec<Formula> {
1138 match formula {
1139 And { left, right } => {
1140 let mut lefts = conjunct_list(*left);
1141 let mut rights = conjunct_list(*right);
1142 lefts.append(&mut rights);
1143 lefts
1144 }
1145 _ => vec![formula],
1146 }
1147 }
1148
1149 let disjuncts: Vec<Vec<Formula>> = disjunct_list(formula)
1150 .into_iter()
1151 .map(|d| conjunct_list(d)
1152 .into_iter()
1153 .unique()
1154 .collect())
1155 .collect();
1156
1157 let disjuncts: Vec<Vec<Formula>> = disjuncts
1158 .iter()
1159 .filter(|d| !disjuncts
1160 .iter()
1161 .any(|dd| (dd.len() < d.len() || (dd.len() == d.len() && dd < d))
1162 && dd
1163 .iter()
1164 .all(|cc| d
1165 .iter()
1166 .any(|c| cc == c)
1167 )
1168 )
1169 ).map(|d| d.clone())
1170 .unique()
1171 .collect();
1172
1173 disjuncts
1174 .into_iter()
1175 .map(|d| d
1176 .into_iter()
1177 .fold1(|f1, f2| f1.and(f2))
1178 .unwrap())
1179 .fold1(|f1, f2| f1.or(f2))
1180 .unwrap()
1181}
1182
1183#[cfg(test)]
1184mod test_transform {
1185 use super::*;
1186 use crate::test_prelude::*;
1187 use std::collections::HashMap;
1188
1189 #[test]
1190 fn test_substitution_map() {
1191 {
1192 let map: HashMap<&V, Term> = HashMap::new();
1193 assert_eq!(x(), x().substitute(&map));
1194 }
1195 {
1196 let mut map: HashMap<&V, Term> = HashMap::new();
1197 let x_v = &_x();
1198 let y_var = y();
1199
1200 map.insert(x_v, y_var);
1201 assert_eq!(y(), x().substitute(&map));
1202 }
1203 {
1204 let mut map: HashMap<&V, Term> = HashMap::new();
1205 let x_v = &_x();
1206 let y_v = &_y();
1207 let term_1 = g().app1(z());
1208 let term_2 = h().app2(z(), y());
1209
1210 map.insert(x_v, term_1);
1211 map.insert(y_v, term_2);
1212 assert_eq!(f().app2(g().app1(z()), h().app2(z(), y())),
1213 f().app2(x(), y()).substitute(&map));
1214 }
1215 }
1216
1217 #[test]
1218 fn test_rename_term() {
1219 assert_eq!(x(), x().rename_vars(&|v: &V| v.clone()));
1220 assert_eq!(y(), x().rename_vars(&|v: &V| {
1221 if *v == _x() {
1222 _y()
1223 } else {
1224 v.clone()
1225 }
1226 }));
1227 assert_eq!(x(), x().rename_vars(&|v: &V| {
1228 if *v == _y() {
1229 _z()
1230 } else {
1231 v.clone()
1232 }
1233 }));
1234 assert_eq!(f().app1(y()), f().app1(x()).rename_vars(&|v: &V| {
1235 if *v == _x() {
1236 _y()
1237 } else {
1238 v.clone()
1239 }
1240 }));
1241 assert_eq!(f().app1(x()), f().app1(x()).rename_vars(&|v: &V| {
1242 if *v == _z() {
1243 _y()
1244 } else {
1245 v.clone()
1246 }
1247 }));
1248 assert_eq!(f().app2(z(), z()), f().app2(x(), y()).rename_vars(&|v: &V| {
1249 if *v == _x() {
1250 _z()
1251 } else if *v == _y() {
1252 _z()
1253 } else {
1254 v.clone()
1255 }
1256 }));
1257 assert_eq!(f().app2(y(), g().app2(y(), h().app1(z()))),
1258 f().app2(x(), g().app2(x(), h().app1(y()))).rename_vars(&|v: &V| {
1259 if *v == _x() {
1260 _y()
1261 } else if *v == _y() {
1262 _z()
1263 } else {
1264 v.clone()
1265 }
1266 }));
1267 }
1268
1269 #[test]
1270 fn test_substitute_term() {
1271 assert_eq!(x(), x().substitute(&|v: &V| v.clone().into()));
1272 assert_eq!(a(), a().substitute(&|v: &V| {
1273 if *v == _x() {
1274 y()
1275 } else {
1276 v.clone().into()
1277 }
1278 }));
1279 assert_eq!(y(), x().substitute(&|v: &V| {
1280 if *v == _x() {
1281 y()
1282 } else {
1283 v.clone().into()
1284 }
1285 }));
1286 assert_eq!(a(), x().substitute(&|v: &V| {
1287 if *v == _x() {
1288 a()
1289 } else {
1290 v.clone().into()
1291 }
1292 }));
1293 assert_eq!(f().app1(z()), x().substitute(&|v: &V| {
1294 if *v == _x() {
1295 f().app1(z())
1296 } else {
1297 v.clone().into()
1298 }
1299 }));
1300 assert_eq!(x(), x().substitute(&|v: &V| {
1301 if *v == _y() {
1302 z()
1303 } else {
1304 v.clone().into()
1305 }
1306 }));
1307 assert_eq!(f().app1(y()), f().app1(x()).substitute(&|v: &V| {
1308 if *v == _x() {
1309 y()
1310 } else {
1311 v.clone().into()
1312 }
1313 }));
1314 assert_eq!(f().app1(g().app1(h().app2(y(), z()))), f().app1(x()).substitute(&|v: &V| {
1315 if *v == _x() {
1316 g().app1(h().app2(y(), z()))
1317 } else {
1318 v.clone().into()
1319 }
1320 }));
1321 assert_eq!(f().app1(x()), f().app1(x()).substitute(&|v: &V| {
1322 if *v == _y() {
1323 z()
1324 } else {
1325 v.clone().into()
1326 }
1327 }));
1328 assert_eq!(f().app2(g().app1(z()), h().app2(z(), y())),
1329 f().app2(x(), y()).substitute(&|v: &V| {
1330 if *v == _x() {
1331 g().app1(z())
1332 } else if *v == _y() {
1333 h().app2(z(), y())
1334 } else {
1335 v.clone().into()
1336 }
1337 }));
1338 assert_eq!(f().app2(f().app1(f().app0()), g().app2(f().app1(f().app0()), h().app1(z()))),
1339 f().app2(x(), g().app2(x(), h().app1(y()))).substitute(&|v: &V| {
1340 if *v == _x() {
1341 f().app1(f().app0())
1342 } else if *v == _y() {
1343 z()
1344 } else {
1345 v.clone().into()
1346 }
1347 }));
1348 assert_eq!(f().app2(f().app1(a()), g().app2(f().app1(a()), h().app1(z()))),
1349 f().app2(x(), g().app2(x(), h().app1(y()))).substitute(&|v: &V| {
1350 if *v == _x() {
1351 f().app1(a())
1352 } else if *v == _y() {
1353 z()
1354 } else {
1355 v.clone().into()
1356 }
1357 }));
1358 }
1359
1360 #[test]
1361 fn test_skolem_generator() {
1362 assert_eq!(SkolemGenerator { prefix: "sk#".to_owned(), index: 0 }, SkolemGenerator::new());
1363 {
1364 let mut gen = SkolemGenerator::new();
1365 assert_eq!("sk#0", gen.next());
1366 assert_eq!("sk#1", gen.next());
1367 assert_eq!("sk#2", gen.next());
1368 }
1369 {
1370 let mut gen = SkolemGenerator::from("razor");
1371 assert_eq!("razor0", gen.next());
1372 assert_eq!("razor1", gen.next());
1373 assert_eq!("razor2", gen.next());
1374 }
1375 }
1376
1377 #[test]
1378 fn test_rename_formula() {
1379 assert_eq!(Top, Top.rename_vars(&|v: &V| {
1380 if *v == _x() {
1381 _y()
1382 } else {
1383 v.clone()
1384 }
1385 }));
1386 assert_eq!(Bottom, Bottom.rename_vars(&|v: &V| {
1387 if *v == _x() {
1388 _y()
1389 } else {
1390 v.clone()
1391 }
1392 }));
1393 assert_eq!(z().equals(z()), x().equals(y()).rename_vars(&|v: &V| {
1394 if *v == _x() {
1395 _z()
1396 } else if *v == _y() {
1397 _z()
1398 } else {
1399 v.clone()
1400 }
1401 }));
1402 assert_eq!(P().app1(x()), P().app1(x()).rename_vars(&|v: &V| {
1403 if *v == _x() {
1404 _x()
1405 } else {
1406 v.clone()
1407 }
1408 }));
1409 assert_eq!(P().app1(y()), P().app1(x()).rename_vars(&|v: &V| {
1410 if *v == _x() {
1411 _y()
1412 } else {
1413 v.clone()
1414 }
1415 }));
1416 assert_eq!(P().app3(y(), z(), y()), P().app3(x(), y(), x()).rename_vars(&|v: &V| {
1417 if *v == _x() {
1418 _y()
1419 } else if *v == _y() {
1420 _z()
1421 } else {
1422 v.clone()
1423 }
1424 }));
1425 assert_eq!(not(P().app3(y(), z(), y())), not(P().app3(x(), y(), x())).rename_vars(&|v: &V| {
1426 if *v == _x() {
1427 _y()
1428 } else if *v == _y() {
1429 _z()
1430 } else {
1431 v.clone()
1432 }
1433 }));
1434 assert_eq!(P().app1(z()).and(Q().app1(z())), P().app1(x()).and(Q().app1(y())).rename_vars(&|v: &V| {
1435 if *v == _x() {
1436 _z()
1437 } else if *v == _y() {
1438 _z()
1439 } else {
1440 v.clone()
1441 }
1442 }));
1443 assert_eq!(P().app1(z()).or(Q().app1(z())), P().app1(x()).or(Q().app1(y())).rename_vars(&|v: &V| {
1444 if *v == _x() {
1445 _z()
1446 } else if *v == _y() {
1447 _z()
1448 } else {
1449 v.clone()
1450 }
1451 }));
1452 assert_eq!(P().app1(z()).implies(Q().app1(z())), P().app1(x()).implies(Q().app1(y())).rename_vars(&|v: &V| {
1453 if *v == _x() {
1454 _z()
1455 } else if *v == _y() {
1456 _z()
1457 } else {
1458 v.clone()
1459 }
1460 }));
1461 assert_eq!(P().app1(z()).iff(Q().app1(z())), P().app1(x()).iff(Q().app1(y())).rename_vars(&|v: &V| {
1462 if *v == _x() {
1463 _z()
1464 } else if *v == _y() {
1465 _z()
1466 } else {
1467 v.clone()
1468 }
1469 }));
1470 assert_eq!(exists2(_x(), _y(), P().app3(y(), y(), y())),
1471 exists2(_x(), _y(), P().app3(x(), y(), z())).rename_vars(&|v: &V| {
1472 if *v == _x() {
1473 _y()
1474 } else if *v == _z() {
1475 _y()
1476 } else {
1477 v.clone()
1478 }
1479 }));
1480 assert_eq!(forall2(_x(), _y(), P().app3(y(), y(), y())),
1481 forall2(_x(), _y(), P().app3(x(), y(), z())).rename_vars(&|v: &V| {
1482 if *v == _x() {
1483 _y()
1484 } else if *v == _z() {
1485 _y()
1486 } else {
1487 v.clone()
1488 }
1489 }));
1490 assert_eq!(
1491 exists1(_x(),
1492 forall1(_y(),
1493 P().app1(y()).or(Q().app1(z()).and(R().app1(z()))),
1494 ).and(not(z().equals(z())))),
1495 exists1(_x(),
1496 forall1(_y(),
1497 P().app1(x()).or(Q().app1(y()).and(R().app1(z()))),
1498 ).and(not(y().equals(y()))),
1499 ).rename_vars(&|v: &V| {
1500 if *v == _x() {
1501 _y()
1502 } else if *v == _y() {
1503 _z()
1504 } else {
1505 v.clone()
1506 }
1507 }));
1508 }
1509
1510
1511 #[test]
1512 fn test_substitute_formula() {
1513 assert_eq!(Top, Top.substitute(&|v: &V| {
1514 if *v == _x() {
1515 y()
1516 } else {
1517 v.clone().into()
1518 }
1519 }));
1520 assert_eq!(Bottom, Bottom.substitute(&|v: &V| {
1521 if *v == _x() {
1522 y()
1523 } else {
1524 v.clone().into()
1525 }
1526 }));
1527 assert_eq!(f().app1(g().app1(z())).equals(g().app1(f().app1(z()))), x().equals(y()).substitute(&|v: &V| {
1528 if *v == _x() {
1529 f().app1(g().app1(z()))
1530 } else if *v == _y() {
1531 g().app1(f().app1(z()))
1532 } else {
1533 v.clone().into()
1534 }
1535 }));
1536 assert_eq!(P().app1(h().app1(y())), P().app1(x()).substitute(&|v: &V| {
1537 if *v == _x() {
1538 h().app1(y())
1539 } else {
1540 v.clone().into()
1541 }
1542 }));
1543 assert_eq!(P().app1(g().app1(g().app1(x()))), P().app1(x()).substitute(&|v: &V| {
1544 if *v == _x() {
1545 g().app1(g().app1(x()))
1546 } else {
1547 v.clone().into()
1548 }
1549 }));
1550 assert_eq!(P().app3(y(), f().app1(z()), y()),
1551 P().app3(x(), y(), x()).substitute(&|v: &V| {
1552 if *v == _x() {
1553 y()
1554 } else if *v == _y() {
1555 f().app1(z())
1556 } else {
1557 v.clone().into()
1558 }
1559 }));
1560 assert_eq!(not(P().app3(h().app0(), z(), h().app0())),
1561 not(P().app3(x(), y(), x())).substitute(&|v: &V| {
1562 if *v == _x() {
1563 h().app0()
1564 } else if *v == _y() {
1565 z()
1566 } else {
1567 v.clone().into()
1568 }
1569 }));
1570 assert_eq!(P().app1(f().app1(g().app0())).and(Q().app1(h().app1(z()))),
1571 P().app1(x()).and(Q().app1(y())).substitute(&|v: &V| {
1572 if *v == _x() {
1573 f().app1(g().app0())
1574 } else if *v == _y() {
1575 h().app1(z())
1576 } else {
1577 v.clone().into()
1578 }
1579 }));
1580 assert_eq!(P().app1(f().app1(g().app0())).or(Q().app1(h().app1(z()))),
1581 P().app1(x()).or(Q().app1(y())).substitute(&|v: &V| {
1582 if *v == _x() {
1583 f().app1(g().app0())
1584 } else if *v == _y() {
1585 h().app1(z())
1586 } else {
1587 v.clone().into()
1588 }
1589 }));
1590 assert_eq!(P().app1(f().app0()).implies(Q().app1(g().app0())),
1591 P().app1(x()).implies(Q().app1(y())).substitute(&|v: &V| {
1592 if *v == _x() {
1593 f().app0()
1594 } else if *v == _y() {
1595 g().app0()
1596 } else {
1597 v.clone().into()
1598 }
1599 }));
1600 assert_eq!(P().app1(a()).implies(Q().app1(b())),
1601 P().app1(x()).implies(Q().app1(y())).substitute(&|v: &V| {
1602 if *v == _x() {
1603 a()
1604 } else if *v == _y() {
1605 b()
1606 } else {
1607 v.clone().into()
1608 }
1609 }));
1610 assert_eq!(P().app1(f().app0()).iff(Q().app1(g().app0())),
1611 P().app1(x()).iff(Q().app1(y())).substitute(&|v: &V| {
1612 if *v == _x() {
1613 f().app0()
1614 } else if *v == _y() {
1615 g().app0()
1616 } else {
1617 v.clone().into()
1618 }
1619 }));
1620 assert_eq!(P().app1(a()).iff(Q().app1(b())),
1621 P().app1(x()).iff(Q().app1(y())).substitute(&|v: &V| {
1622 if *v == _x() {
1623 a()
1624 } else if *v == _y() {
1625 b()
1626 } else {
1627 v.clone().into()
1628 }
1629 }));
1630 assert_eq!(exists2(_x(), _y(), P().app3(f().app1(g().app1(y())), y(), y())),
1631 exists2(_x(), _y(), P().app3(x(), y(), z())).substitute(&|v: &V| {
1632 if *v == _x() {
1633 f().app1(g().app1(y()))
1634 } else if *v == _z() {
1635 y()
1636 } else {
1637 v.clone().into()
1638 }
1639 }));
1640 assert_eq!(forall2(_x(), _y(), P().app3(f().app1(g().app1(y())), y(), y())),
1641 forall2(_x(), _y(), P().app3(x(), y(), z())).substitute(&|v: &V| {
1642 if *v == _x() {
1643 f().app1(g().app1(y()))
1644 } else if *v == _z() {
1645 y()
1646 } else {
1647 v.clone().into()
1648 }
1649 }));
1650 assert_eq!(
1651 exists1(_x(),
1652 forall1(_y(),
1653 P().app1(y()).or(Q().app1(z()).and(R().app1(z()))),
1654 ).and(not(z().equals(z())))),
1655 exists1(_x(),
1656 forall1(_y(),
1657 P().app1(x()).or(Q().app1(y()).and(R().app1(z()))),
1658 ).and(not(y().equals(y()))),
1659 ).substitute(&|v: &V| {
1660 if *v == _x() {
1661 y()
1662 } else if *v == _y() {
1663 z()
1664 } else {
1665 v.clone().into()
1666 }
1667 }));
1668 }
1669
1670 #[test]
1671 fn test_pnf() {
1672 {
1673 let formula: Formula = "true".parse().unwrap();
1674 assert_debug_string("true", formula.pnf());
1675 }
1676 {
1677 let formula: Formula = "false".parse().unwrap();
1678 assert_debug_string("false", formula.pnf());
1679 }
1680 {
1681 let formula: Formula = "P(x)".parse().unwrap();
1682 assert_debug_string("P(x)", formula.pnf());
1683 }
1684 {
1685 let formula: Formula = "x = y".parse().unwrap();
1686 assert_debug_string("x = y", formula.pnf());
1687 }
1688 {
1689 let formula: Formula = "~P(x)".parse().unwrap();
1690 assert_debug_string("~P(x)", formula.pnf());
1691 }
1692 {
1693 let formula: Formula = "P(x) & Q(y)".parse().unwrap();
1694 assert_debug_string("P(x) & Q(y)", formula.pnf());
1695 }
1696 {
1697 let formula: Formula = "P(x) | Q(y)".parse().unwrap();
1698 assert_debug_string("P(x) | Q(y)", formula.pnf());
1699 }
1700 {
1701 let formula: Formula = "P(x) -> Q(y)".parse().unwrap();
1702 assert_debug_string("P(x) -> Q(y)", formula.pnf());
1703 }
1704 {
1705 let formula: Formula = "P(x) <=> Q(y)".parse().unwrap();
1706 assert_debug_string("(P(x) -> Q(y)) & (Q(y) -> P(x))", formula.pnf());
1707 }
1708 {
1709 let formula: Formula = "? x. P(x) & ~Q(y) | R(z)".parse().unwrap();
1710 assert_debug_string("? x. ((P(x) & (~Q(y))) | R(z))", formula.pnf());
1711 }
1712 {
1713 let formula: Formula = "! x. P(x) & ~Q(y) | R(z)".parse().unwrap();
1714 assert_debug_string("! x. ((P(x) & (~Q(y))) | R(z))", formula.pnf());
1715 }
1716 {
1718 let formula: Formula = "~? x. P(x)".parse().unwrap();
1719 assert_debug_string("! x. (~P(x))", formula.pnf());
1720 }
1721 {
1722 let formula: Formula = "(! x. P(x)) & Q(y)".parse().unwrap();
1723 assert_debug_string("! x. (P(x) & Q(y))", formula.pnf());
1724 }
1725 {
1726 let formula: Formula = "(? x. P(x)) & Q(y)".parse().unwrap();
1727 assert_debug_string("? x. (P(x) & Q(y))", formula.pnf());
1728 }
1729 {
1730 let formula: Formula = "(! x. P(x)) & Q(x)".parse().unwrap();
1731 assert_debug_string("! x`. (P(x`) & Q(x))", formula.pnf());
1732 }
1733 {
1734 let formula: Formula = "(? x. P(x)) & Q(x)".parse().unwrap();
1735 assert_debug_string("? x`. (P(x`) & Q(x))", formula.pnf());
1736 }
1737 {
1738 let formula: Formula = "(! x, y. P(x, y)) & Q(x, y)".parse().unwrap();
1739 assert_debug_string("! x`, y`. (P(x`, y`) & Q(x, y))", formula.pnf());
1740 }
1741 {
1742 let formula: Formula = "(? x, y. P(x, y)) & Q(x, y)".parse().unwrap();
1743 assert_debug_string("? x`, y`. (P(x`, y`) & Q(x, y))", formula.pnf());
1744 }
1745 {
1746 let formula: Formula = "Q(y) & ! x. P(x)".parse().unwrap();
1747 assert_debug_string("! x. (Q(y) & P(x))", formula.pnf());
1748 }
1749 {
1750 let formula: Formula = "Q(y) & ? x. P(x)".parse().unwrap();
1751 assert_debug_string("? x. (Q(y) & P(x))", formula.pnf());
1752 }
1753 {
1754 let formula: Formula = "Q(x) & ! x. P(x)".parse().unwrap();
1755 assert_debug_string("! x`. (Q(x) & P(x`))", formula.pnf());
1756 }
1757 {
1758 let formula: Formula = "Q(x) & ? x. P(x)".parse().unwrap();
1759 assert_debug_string("? x`. (Q(x) & P(x`))", formula.pnf());
1760 }
1761 {
1762 let formula: Formula = "Q(x, y) & ! x, y. P(x, y)".parse().unwrap();
1763 assert_debug_string("! x`, y`. (Q(x, y) & P(x`, y`))", formula.pnf());
1764 }
1765 {
1766 let formula: Formula = "Q(x, y) & ? x, y. P(x, y)".parse().unwrap();
1767 assert_debug_string("? x`, y`. (Q(x, y) & P(x`, y`))", formula.pnf());
1768 }
1769 {
1770 let formula: Formula = "(! x. P(x)) | Q(y)".parse().unwrap();
1771 assert_debug_string("! x. (P(x) | Q(y))", formula.pnf());
1772 }
1773 {
1774 let formula: Formula = "(? x. P(x)) | Q(y)".parse().unwrap();
1775 assert_debug_string("? x. (P(x) | Q(y))", formula.pnf());
1776 }
1777 {
1778 let formula: Formula = "(! x. P(x)) | Q(x)".parse().unwrap();
1779 assert_debug_string("! x`. (P(x`) | Q(x))", formula.pnf());
1780 }
1781 {
1782 let formula: Formula = "(? x. P(x)) | Q(x)".parse().unwrap();
1783 assert_debug_string("? x`. (P(x`) | Q(x))", formula.pnf());
1784 }
1785 {
1786 let formula: Formula = "(! x, y. P(x, y)) | Q(x, y)".parse().unwrap();
1787 assert_debug_string("! x`, y`. (P(x`, y`) | Q(x, y))", formula.pnf());
1788 }
1789 {
1790 let formula: Formula = "(? x, y. P(x, y)) | Q(x, y)".parse().unwrap();
1791 assert_debug_string("? x`, y`. (P(x`, y`) | Q(x, y))", formula.pnf());
1792 }
1793 {
1794 let formula: Formula = "Q(y) | ! x. P(x)".parse().unwrap();
1795 assert_debug_string("! x. (Q(y) | P(x))", formula.pnf());
1796 }
1797 {
1798 let formula: Formula = "Q(y) | ? x. P(x)".parse().unwrap();
1799 assert_debug_string("? x. (Q(y) | P(x))", formula.pnf());
1800 }
1801 {
1802 let formula: Formula = "Q(x) | ! x. P(x)".parse().unwrap();
1803 assert_debug_string("! x`. (Q(x) | P(x`))", formula.pnf());
1804 }
1805 {
1806 let formula: Formula = "Q(x) | ? x. P(x)".parse().unwrap();
1807 assert_debug_string("? x`. (Q(x) | P(x`))", formula.pnf());
1808 }
1809 {
1810 let formula: Formula = "Q(x, y) | ! x, y. P(x, y)".parse().unwrap();
1811 assert_debug_string("! x`, y`. (Q(x, y) | P(x`, y`))", formula.pnf());
1812 }
1813 {
1814 let formula: Formula = "Q(x, y) | ? x, y. P(x, y)".parse().unwrap();
1815 assert_debug_string("? x`, y`. (Q(x, y) | P(x`, y`))", formula.pnf());
1816 }
1817 {
1818 let formula: Formula = "(! x. P(x)) -> Q(y)".parse().unwrap();
1819 assert_debug_string("? x. (P(x) -> Q(y))", formula.pnf());
1820 }
1821 {
1822 let formula: Formula = "(? x. P(x)) -> Q(y)".parse().unwrap();
1823 assert_debug_string("! x. (P(x) -> Q(y))", formula.pnf());
1824 }
1825 {
1826 let formula: Formula = "(! x. P(x)) -> Q(x)".parse().unwrap();
1827 assert_debug_string("? x`. (P(x`) -> Q(x))", formula.pnf());
1828 }
1829 {
1830 let formula: Formula = "(? x. P(x)) -> Q(x)".parse().unwrap();
1831 assert_debug_string("! x`. (P(x`) -> Q(x))", formula.pnf());
1832 }
1833 {
1834 let formula: Formula = "(! x, y. P(x, y)) -> Q(x, y)".parse().unwrap();
1835 assert_debug_string("? x`, y`. (P(x`, y`) -> Q(x, y))", formula.pnf());
1836 }
1837 {
1838 let formula: Formula = "(? x, y. P(x, y)) -> Q(x, y)".parse().unwrap();
1839 assert_debug_string("! x`, y`. (P(x`, y`) -> Q(x, y))", formula.pnf());
1840 }
1841 {
1842 let formula: Formula = "Q(y) -> ! x. P(x)".parse().unwrap();
1843 assert_debug_string("! x. (Q(y) -> P(x))", formula.pnf());
1844 }
1845 {
1846 let formula: Formula = "Q(y) -> ? x. P(x)".parse().unwrap();
1847 assert_debug_string("? x. (Q(y) -> P(x))", formula.pnf());
1848 }
1849 {
1850 let formula: Formula = "Q(x) -> ! x. P(x)".parse().unwrap();
1851 assert_debug_string("! x`. (Q(x) -> P(x`))", formula.pnf());
1852 }
1853 {
1854 let formula: Formula = "Q(x) -> ? x. P(x)".parse().unwrap();
1855 assert_debug_string("? x`. (Q(x) -> P(x`))", formula.pnf());
1856 }
1857 {
1858 let formula: Formula = "Q(x, y) -> ! x, y. P(x, y)".parse().unwrap();
1859 assert_debug_string("! x`, y`. (Q(x, y) -> P(x`, y`))", formula.pnf());
1860 }
1861 {
1862 let formula: Formula = "Q(x, y) -> ? x, y. P(x, y)".parse().unwrap();
1863 assert_debug_string("? x`, y`. (Q(x, y) -> P(x`, y`))", formula.pnf());
1864 }
1865
1866 {
1867 let formula: Formula = "(! x. P(x)) <=> Q(y)".parse().unwrap();
1868 assert_debug_string("? x. (! x`. ((P(x) -> Q(y)) & (Q(y) -> P(x`))))",
1869 formula.pnf());
1870 }
1871 {
1872 let formula: Formula = "(? x. P(x)) <=> Q(y)".parse().unwrap();
1873 assert_debug_string("! x. (? x`. ((P(x) -> Q(y)) & (Q(y) -> P(x`))))",
1874 formula.pnf());
1875 }
1876 {
1877 let formula: Formula = "(! x. P(x)) <=> Q(x)".parse().unwrap();
1878 assert_debug_string("? x`. (! x``. ((P(x`) -> Q(x)) & (Q(x) -> P(x``))))",
1879 formula.pnf());
1880 }
1881 {
1882 let formula: Formula = "(? x. P(x)) <=> Q(x)".parse().unwrap();
1883 assert_debug_string("! x`. (? x``. ((P(x`) -> Q(x)) & (Q(x) -> P(x``))))",
1884 formula.pnf());
1885 }
1886 {
1887 let formula: Formula = "(! x, y. P(x, y)) <=> Q(x, y)".parse().unwrap();
1888 assert_debug_string("? x`, y`. (! x``, y``. ((P(x`, y`) -> Q(x, y)) & (Q(x, y) -> P(x``, y``))))",
1889 formula.pnf());
1890 }
1891 {
1892 let formula: Formula = "(? x, y. P(x, y)) <=> Q(x, y)".parse().unwrap();
1893 assert_debug_string("! x`, y`. (? x``, y``. ((P(x`, y`) -> Q(x, y)) & (Q(x, y) -> P(x``, y``))))",
1894 formula.pnf());
1895 }
1896 {
1897 let formula: Formula = "Q(y) <=> ! x. P(x)".parse().unwrap();
1898 assert_debug_string("! x. (? x`. ((Q(y) -> P(x)) & (P(x`) -> Q(y))))",
1899 formula.pnf());
1900 }
1901 {
1902 let formula: Formula = "Q(y) <=> ? x. P(x)".parse().unwrap();
1903 assert_debug_string("? x. (! x`. ((Q(y) -> P(x)) & (P(x`) -> Q(y))))",
1904 formula.pnf());
1905 }
1906 {
1907 let formula: Formula = "Q(x) <=> ! x. P(x)".parse().unwrap();
1908 assert_debug_string("! x`. (? x``. ((Q(x) -> P(x`)) & (P(x``) -> Q(x))))",
1909 formula.pnf());
1910 }
1911 {
1912 let formula: Formula = "Q(x) <=> ? x. P(x)".parse().unwrap();
1913 assert_debug_string("? x`. (! x``. ((Q(x) -> P(x`)) & (P(x``) -> Q(x))))",
1914 formula.pnf());
1915 }
1916 {
1917 let formula: Formula = "Q(x, y) <=> ! x, y. P(x, y)".parse().unwrap();
1918 assert_debug_string("! x`, y`. (? x``, y``. ((Q(x, y) -> P(x`, y`)) & (P(x``, y``) -> Q(x, y))))",
1919 formula.pnf());
1920 }
1921 {
1922 let formula: Formula = "Q(x, y) <=> ? x, y. P(x, y)".parse().unwrap();
1923 assert_debug_string("? x`, y`. (! x``, y``. ((Q(x, y) -> P(x`, y`)) & (P(x``, y``) -> Q(x, y))))",
1924 formula.pnf());
1925 }
1926 assert_debug_string("! x``, x`. (P(x``) & Q(x))",
1928 forall2(_x(), _x_1(), P().app1(x())).and(Q().app1(x())).pnf());
1929 assert_debug_string("? x``, x`. (P(x``) & Q(x))",
1930 exists2(_x(), _x_1(), P().app1(x())).and(Q().app1(x())).pnf());
1931 assert_debug_string("? x``. (P(x``) & Q(x, x`))",
1932 exists1(_x(), P().app1(x())).and(Q().app2(x(), x_1())).pnf());
1933 assert_debug_string("? x``. (P(x``, x`) & Q(x))",
1934 exists1(_x(), P().app2(x(), x_1())).and(Q().app1(x())).pnf());
1935 assert_debug_string("! x``, x`. (Q(x) & P(x``))",
1936 Q().app1(x()).and(forall2(_x(), _x_1(), P().app1(x()))).pnf());
1937 assert_debug_string("? x``, x`. (Q(x) & P(x``))",
1938 Q().app1(x()).and(exists2(_x(), _x_1(), P().app1(x()))).pnf());
1939 assert_debug_string("? x``. (Q(x, x`) & P(x``))",
1940 Q().app2(x(), x_1()).and(exists1(_x(), P().app1(x()))).pnf());
1941 assert_debug_string("? x``. (Q(x) & P(x``, x`))",
1942 Q().app1(x()).and(exists1(_x(), P().app2(x(), x_1()))).pnf());
1943
1944 assert_debug_string("! x``, x`. (P(x``) | Q(x))",
1945 forall2(_x(), _x_1(), P().app1(x())).or(Q().app1(x())).pnf());
1946 assert_debug_string("? x``, x`. (P(x``) | Q(x))",
1947 exists2(_x(), _x_1(), P().app1(x())).or(Q().app1(x())).pnf());
1948 assert_debug_string("? x``. (P(x``) | Q(x, x`))",
1949 exists1(_x(), P().app1(x())).or(Q().app2(x(), x_1())).pnf());
1950 assert_debug_string("? x``. (P(x``, x`) | Q(x))",
1951 exists1(_x(), P().app2(x(), x_1())).or(Q().app1(x())).pnf());
1952 assert_debug_string("! x``, x`. (Q(x) | P(x``))",
1953 Q().app1(x()).or(forall2(_x(), _x_1(), P().app1(x()))).pnf());
1954 assert_debug_string("? x``, x`. (Q(x) | P(x``))",
1955 Q().app1(x()).or(exists2(_x(), _x_1(), P().app1(x()))).pnf());
1956 assert_debug_string("? x``. (Q(x, x`) | P(x``))",
1957 Q().app2(x(), x_1()).or(exists1(_x(), P().app1(x()))).pnf());
1958 assert_debug_string("? x``. (Q(x) | P(x``, x`))",
1959 Q().app1(x()).or(exists1(_x(), P().app2(x(), x_1()))).pnf());
1960
1961 assert_debug_string("? x``, x`. (P(x``) -> Q(x))",
1962 forall2(_x(), _x_1(), P().app1(x())).implies(Q().app1(x())).pnf());
1963 assert_debug_string("! x``, x`. (P(x``) -> Q(x))",
1964 exists2(_x(), _x_1(), P().app1(x())).implies(Q().app1(x())).pnf());
1965 assert_debug_string("! x``. (P(x``) -> Q(x, x`))",
1966 exists1(_x(), P().app1(x())).implies(Q().app2(x(), x_1())).pnf());
1967 assert_debug_string("! x``. (P(x``, x`) -> Q(x))",
1968 exists1(_x(), P().app2(x(), x_1())).implies(Q().app1(x())).pnf());
1969 assert_debug_string("! x``, x`. (Q(x) -> P(x``))",
1970 Q().app1(x()).implies(forall2(_x(), _x_1(), P().app1(x()))).pnf());
1971 assert_debug_string("? x``, x`. (Q(x) -> P(x``))",
1972 Q().app1(x()).implies(exists2(_x(), _x_1(), P().app1(x()))).pnf());
1973 assert_debug_string("? x``. (Q(x, x`) -> P(x``))",
1974 Q().app2(x(), x_1()).implies(exists1(_x(), P().app1(x()))).pnf());
1975 assert_debug_string("? x``. (Q(x) -> P(x``, x`))",
1976 Q().app1(x()).implies(exists1(_x(), P().app2(x(), x_1()))).pnf());
1977
1978 assert_debug_string("? x``, x`. (! x```, x`. ((P(x``) -> Q(x)) & (Q(x) -> P(x```))))",
1979 forall2(_x(), _x_1(), P().app1(x())).iff(Q().app1(x())).pnf());
1980 assert_debug_string("! x``, x`. (? x```, x`. ((P(x``) -> Q(x)) & (Q(x) -> P(x```))))",
1981 exists2(_x(), _x_1(), P().app1(x())).iff(Q().app1(x())).pnf());
1982 assert_debug_string("! x``. (? x```. ((P(x``) -> Q(x, x`)) & (Q(x, x`) -> P(x```))))",
1983 exists1(_x(), P().app1(x())).iff(Q().app2(x(), x_1())).pnf());
1984 assert_debug_string("! x``. (? x```. ((P(x``, x`) -> Q(x)) & (Q(x) -> P(x```, x`))))",
1985 exists1(_x(), P().app2(x(), x_1())).iff(Q().app1(x())).pnf());
1986 assert_debug_string("! x``, x`. (? x```, x`. ((Q(x) -> P(x``)) & (P(x```) -> Q(x))))",
1987 Q().app1(x()).iff(forall2(_x(), _x_1(), P().app1(x()))).pnf());
1988 assert_debug_string("? x``, x`. (! x```, x`. ((Q(x) -> P(x``)) & (P(x```) -> Q(x))))",
1989 Q().app1(x()).iff(exists2(_x(), _x_1(), P().app1(x()))).pnf());
1990 assert_debug_string("? x``. (! x```. ((Q(x, x`) -> P(x``)) & (P(x```) -> Q(x, x`))))",
1991 Q().app2(x(), x_1()).iff(exists1(_x(), P().app1(x()))).pnf());
1992 assert_debug_string("? x``. (! x```. ((Q(x) -> P(x``, x`)) & (P(x```, x`) -> Q(x))))",
1993 Q().app1(x()).iff(exists1(_x(), P().app2(x(), x_1()))).pnf());
1994 {
1996 let formula: Formula = "(! x. P(x)) & (! x. Q(x))".parse().unwrap();
1997 assert_debug_string("! x. (! x`. (P(x) & Q(x`)))", formula.pnf());
1998 }
1999 {
2000 let formula: Formula = "(! x. P(x)) & (? x. Q(x))".parse().unwrap();
2001 assert_debug_string("! x. (? x`. (P(x) & Q(x`)))", formula.pnf());
2002 }
2003 {
2004 let formula: Formula = "(? x. P(x)) & (! x. Q(x))".parse().unwrap();
2005 assert_debug_string("? x. (! x`. (P(x) & Q(x`)))", formula.pnf());
2006 }
2007 {
2008 let formula: Formula = "(? x. P(x)) & (? x. Q(x))".parse().unwrap();
2009 assert_debug_string("? x. (? x`. (P(x) & Q(x`)))", formula.pnf());
2010 }
2011 {
2012 let formula: Formula = "(! x. P(x)) | (! x. Q(x))".parse().unwrap();
2013 assert_debug_string("! x. (! x`. (P(x) | Q(x`)))", formula.pnf());
2014 }
2015 {
2016 let formula: Formula = "(! x. P(x)) | (? x. Q(x))".parse().unwrap();
2017 assert_debug_string("! x. (? x`. (P(x) | Q(x`)))", formula.pnf());
2018 }
2019 {
2020 let formula: Formula = "(? x. P(x)) | (! x. Q(x))".parse().unwrap();
2021 assert_debug_string("? x. (! x`. (P(x) | Q(x`)))", formula.pnf());
2022 }
2023 {
2024 let formula: Formula = "(? x. P(x)) | (? x. Q(x))".parse().unwrap();
2025 assert_debug_string("? x. (? x`. (P(x) | Q(x`)))", formula.pnf());
2026 }
2027 {
2028 let formula: Formula = "(! x. P(x)) -> (! x. Q(x))".parse().unwrap();
2029 assert_debug_string("? x. (! x`. (P(x) -> Q(x`)))", formula.pnf());
2030 }
2031 {
2032 let formula: Formula = "(! x. P(x)) -> (? x. Q(x))".parse().unwrap();
2033 assert_debug_string("? x. (? x`. (P(x) -> Q(x`)))", formula.pnf());
2034 }
2035 {
2036 let formula: Formula = "(? x. P(x)) -> (! x. Q(x))".parse().unwrap();
2037 assert_debug_string("! x. (! x`. (P(x) -> Q(x`)))", formula.pnf());
2038 }
2039 {
2040 let formula: Formula = "(? x. P(x)) -> (? x. Q(x))".parse().unwrap();
2041 assert_debug_string("! x. (? x`. (P(x) -> Q(x`)))", formula.pnf());
2042 }
2043 {
2044 let formula: Formula = "(! x. P(x)) <=> (! x. Q(x))".parse().unwrap();
2045 assert_debug_string("? x. (! x`. (? x``. (! x```. ((P(x) -> Q(x`)) & (Q(x``) -> P(x```))))))",
2046 formula.pnf());
2047 }
2048 {
2049 let formula: Formula = "(! x. P(x)) <=> (? x. Q(x))".parse().unwrap();
2050 assert_debug_string("? x. (? x`. (! x``. (! x```. ((P(x) -> Q(x`)) & (Q(x``) -> P(x```))))))",
2051 formula.pnf());
2052 }
2053 {
2054 let formula: Formula = "(? x. P(x)) <=> (! x. Q(x))".parse().unwrap();
2055 assert_debug_string("! x. (! x`. (? x``. (? x```. ((P(x) -> Q(x`)) & (Q(x``) -> P(x```))))))",
2056 formula.pnf());
2057 }
2058 {
2059 let formula: Formula = "(? x. P(x)) <=> (? x. Q(x))".parse().unwrap();
2060 assert_debug_string("! x. (? x`. (! x``. (? x```. ((P(x) -> Q(x`)) & (Q(x``) -> P(x```))))))",
2061 formula.pnf());
2062 }
2063 {
2065 let formula: Formula = "~~?x.P(x)".parse().unwrap();
2066 assert_debug_string("? x. (~(~P(x)))", formula.pnf());
2067 }
2068 {
2069 let formula: Formula = "~~!x.P(x)".parse().unwrap();
2070 assert_debug_string("! x. (~(~P(x)))", formula.pnf());
2071 }
2072 {
2073 let formula: Formula = "P(x) & ((! x. Q(x)) & R(x))".parse().unwrap();
2074 assert_debug_string("! x`. (P(x) & (Q(x`) & R(x)))", formula.pnf());
2075 }
2076 {
2077 let formula: Formula = "P(x) & ((? x. Q(x)) & R(x))".parse().unwrap();
2078 assert_debug_string("? x`. (P(x) & (Q(x`) & R(x)))", formula.pnf());
2079 }
2080 {
2081 let formula: Formula = "P(x) | ((! x. Q(x)) | R(x))".parse().unwrap();
2082 assert_debug_string("! x`. (P(x) | (Q(x`) | R(x)))", formula.pnf());
2083 }
2084 {
2085 let formula: Formula = "P(x) | ((? x. Q(x)) | R(x))".parse().unwrap();
2086 assert_debug_string("? x`. (P(x) | (Q(x`) | R(x)))", formula.pnf());
2087 }
2088 {
2089 let formula: Formula = "P(x) -> ((! x. Q(x)) -> R(x))".parse().unwrap();
2090 assert_debug_string("? x`. (P(x) -> (Q(x`) -> R(x)))", formula.pnf());
2091 }
2092 {
2093 let formula: Formula = "P(x) -> ((? x. Q(x)) -> R(x))".parse().unwrap();
2094 assert_debug_string("! x`. (P(x) -> (Q(x`) -> R(x)))", formula.pnf());
2095 }
2096 {
2097 let formula: Formula = "P(x) <=> ((! x. Q(x)) <=> R(x))".parse().unwrap();
2098 assert_debug_string("? x`. (! x``. (! x```. (? x````. ((P(x) -> ((Q(x`) -> R(x)) & (R(x) -> Q(x``)))) & (((Q(x```) -> R(x)) & (R(x) -> Q(x````))) -> P(x))))))", formula.pnf());
2099 }
2100 {
2101 let formula: Formula = "P(x) <=> ((? x. Q(x)) <=> R(x))".parse().unwrap();
2102 assert_debug_string("! x`. (? x``. (? x```. (! x````. ((P(x) -> ((Q(x`) -> R(x)) & (R(x) -> Q(x``)))) & (((Q(x```) -> R(x)) & (R(x) -> Q(x````))) -> P(x))))))", formula.pnf());
2103 }
2104 {
2106 let formula: Formula = "!x . (P(x) -> ?y . (P(y) & Q(x, y)))".parse().unwrap();
2107 assert_debug_string("! x. (? y. (P(x) -> (P(y) & Q(x, y))))", formula.pnf());
2108 }
2109 {
2110 let formula: Formula = "?x . (P(x) & !y . (P(y) -> Q(x, y)))".parse().unwrap();
2111 assert_debug_string("? x. (! y. (P(x) & (P(y) -> Q(x, y))))", formula.pnf());
2112 }
2113 {
2114 let formula: Formula = "!x. (P(x) -> ~(!y . (P(y) -> Q(x, y))))".parse().unwrap();
2115 assert_debug_string("! x. (? y. (P(x) -> (~(P(y) -> Q(x, y)))))", formula.pnf());
2116 }
2117 {
2118 let formula: Formula = "(P() | ? x. Q(x)) -> !z. R(z)".parse().unwrap();
2119 assert_debug_string("! x. (! z. ((P() | Q(x)) -> R(z)))", formula.pnf());
2120 }
2121 {
2122 let formula: Formula = "!x.?y.(!z.Q(x) & ~?x.R(x)) | (~Q(y) -> !w. R(y))".parse().unwrap();
2123 assert_debug_string("! x. (? y. (! z. (! x`. (! w. ((Q(x) & (~R(x`))) | ((~Q(y)) -> R(y)))))))", formula.pnf());
2124 }
2125 {
2126 let formula: Formula = "!x. (!y. P(x, y) -> ?y. Q(x, y))".parse().unwrap();
2127 assert_debug_string("! x. (? y. (? y`. (P(x, y) -> Q(x, y`))))", formula.pnf());
2128 }
2129 }
2130
2131 #[test]
2132 fn test_snf() {
2133 assert_debug_string("P('sk#0)"
2134 , exists1(_x(), P().app1(x())).snf());
2135 assert_debug_string("! x. P(x, sk#0(x))"
2136 , forall1(_x()
2137 , exists1(_y(), P().app2(x(), y()))).snf());
2138 assert_debug_string("P(x, sk#0(x))"
2139 , exists1(_y(), P().app2(x(), y())).snf());
2140 assert_debug_string("! x. P(x, f(g(sk#0(x)), h(sk#0(x))))"
2141 , forall1(_x()
2142 , exists1(_y()
2143 , P().app2(x(), f().app2(g().app1(y()), h().app1(y()))))).snf());
2144 assert_debug_string("('sk#0 = 'sk#1) & ('sk#1 = 'sk#2)",
2145 exists3(_x(), _y(), _z(), x().equals(y()).and(y().equals(z()))).snf());
2146 assert_debug_string("! y. (Q('sk#0, y) | P(sk#1(y), y, sk#2(y)))"
2147 , exists1(_x()
2148 , forall1(_y()
2149 , Q().app2(x(), y())
2150 .or(exists2(_x(), _z(), P().app3(x(), y(), z()))))).snf());
2151 assert_debug_string("! x. (! z. P(x, sk#0(x), z))",
2152 forall1(_x()
2153 , exists1(_y()
2154 , forall1(_z()
2155 , P().app3(x(), y(), z())))).snf());
2156 assert_debug_string("! x. (R(g(x)) | R(x, sk#0(x)))"
2157 , forall1(_x(),
2158 R().app1(g().app1(x()))
2159 .or(exists1(_y(), R().app2(x(), y())))).snf());
2160 assert_debug_string("! y. (! z. (! v. P('sk#0, y, z, sk#1(y, z), v, sk#2(y, z, v))))"
2161 , exists1(_x()
2162 , forall1(_y()
2163 , forall1(_z()
2164 , exists1(_u()
2165 , forall1(_v()
2166 , exists1(_w()
2167 , P().app(vec![x(), y(), z(), u(), v(), w()]))))))).snf());
2168 {
2169 let mut generator = SkolemGenerator::new();
2170 assert_debug_string("P('sk#0)", exists1(_x(), P().app1(x())).snf_with(&mut generator));
2171 assert_debug_string("Q('sk#1)", exists1(_x(), Q().app1(x())).snf_with(&mut generator));
2172 }
2173 }
2174
2175 #[test]
2176 fn test_nnf() {
2177 {
2178 let formula: Formula = "true".parse().unwrap();
2179 assert_debug_string("true", formula.nnf());
2180 }
2181 {
2182 let formula: Formula = "false".parse().unwrap();
2183 assert_debug_string("false", formula.nnf());
2184 }
2185 {
2186 let formula: Formula = "P(x)".parse().unwrap();
2187 assert_debug_string("P(x)", formula.nnf());
2188 }
2189 {
2190 let formula: Formula = "x = y".parse().unwrap();
2191 assert_debug_string("x = y", formula.nnf());
2192 }
2193 {
2194 let formula: Formula = "~P(x)".parse().unwrap();
2195 assert_debug_string("~P(x)", formula.nnf());
2196 }
2197 {
2198 let formula: Formula = "P(x) & Q(y)".parse().unwrap();
2199 assert_debug_string("P(x) & Q(y)", formula.nnf());
2200 }
2201 {
2202 let formula: Formula = "P(x) | Q(y)".parse().unwrap();
2203 assert_debug_string("P(x) | Q(y)", formula.nnf());
2204 }
2205 {
2206 let formula: Formula = "P(x) -> Q(y)".parse().unwrap();
2207 assert_debug_string("(~P(x)) | Q(y)", formula.nnf());
2208 }
2209 {
2210 let formula: Formula = "P(x) <=> Q(y)".parse().unwrap();
2211 assert_debug_string("((~P(x)) | Q(y)) & (P(x) | (~Q(y)))", formula.nnf());
2212 }
2213 {
2214 let formula: Formula = "?x. P(x)".parse().unwrap();
2215 assert_debug_string("? x. P(x)", formula.nnf());
2216 }
2217 {
2218 let formula: Formula = "!x. P(x)".parse().unwrap();
2219 assert_debug_string("! x. P(x)", formula.nnf());
2220 }
2221 {
2223 let formula: Formula = "~true".parse().unwrap();
2224 assert_debug_string("false", formula.nnf());
2225 }
2226 {
2227 let formula: Formula = "~false".parse().unwrap();
2228 assert_debug_string("true", formula.nnf());
2229 }
2230 {
2231 let formula: Formula = "~~P(x)".parse().unwrap();
2232 assert_debug_string("P(x)", formula.nnf());
2233 }
2234 {
2235 let formula: Formula = "~~x = y".parse().unwrap();
2236 assert_debug_string("x = y", formula.nnf());
2237 }
2238 {
2239 let formula: Formula = "~(P(x) & Q(y))".parse().unwrap();
2240 assert_debug_string("(~P(x)) | (~Q(y))", formula.nnf());
2241 }
2242 {
2243 let formula: Formula = "~(P(x) | Q(y))".parse().unwrap();
2244 assert_debug_string("(~P(x)) & (~Q(y))", formula.nnf());
2245 }
2246 {
2247 let formula: Formula = "~(P(x) -> Q(y))".parse().unwrap();
2248 assert_debug_string("P(x) & (~Q(y))", formula.nnf());
2249 }
2250 {
2251 let formula: Formula = "~(P(x) <=> Q(y))".parse().unwrap();
2252 assert_debug_string("(P(x) & (~Q(y))) | ((~P(x)) & Q(y))", formula.nnf());
2253 }
2254 {
2255 let formula: Formula = "(P(x) | Q(y)) -> R(z)".parse().unwrap();
2256 assert_debug_string("((~P(x)) & (~Q(y))) | R(z)", formula.nnf());
2257 }
2258 {
2259 let formula: Formula = "(P(x) | Q(y)) <=> R(z)".parse().unwrap();
2260 assert_debug_string("(((~P(x)) & (~Q(y))) | R(z)) & ((P(x) | Q(y)) | (~R(z)))", formula.nnf());
2261 }
2262 {
2263 let formula: Formula = "~?x. P(x)".parse().unwrap();
2264 assert_debug_string("! x. (~P(x))", formula.nnf());
2265 }
2266 {
2267 let formula: Formula = "~!x. P(x)".parse().unwrap();
2268 assert_debug_string("? x. (~P(x))", formula.nnf());
2269 }
2270 {
2272 let formula: Formula = "~~P(x) & ~~Q(y)".parse().unwrap();
2273 assert_debug_string("P(x) & Q(y)", formula.nnf());
2274 }
2275 {
2276 let formula: Formula = "~~P(x) | ~~Q(y)".parse().unwrap();
2277 assert_debug_string("P(x) | Q(y)", formula.nnf());
2278 }
2279 {
2280 let formula: Formula = "~~P(x) -> ~~Q(y)".parse().unwrap();
2281 assert_debug_string("(~P(x)) | Q(y)", formula.nnf());
2282 }
2283 {
2284 let formula: Formula = "~~P(x) <=> ~~Q(y)".parse().unwrap();
2285 assert_debug_string("((~P(x)) | Q(y)) & (P(x) | (~Q(y)))", formula.nnf());
2286 }
2287 {
2288 let formula: Formula = "?x. ~~P(x)".parse().unwrap();
2289 assert_debug_string("? x. P(x)", formula.nnf());
2290 }
2291 {
2292 let formula: Formula = "!x. ~~P(x)".parse().unwrap();
2293 assert_debug_string("! x. P(x)", formula.nnf());
2294 }
2295 {
2296 let formula: Formula = "~~~P(x)".parse().unwrap();
2297 assert_debug_string("~P(x)", formula.nnf());
2298 }
2299 {
2300 let formula: Formula = "~(~P(x) & ~Q(y))".parse().unwrap();
2301 assert_debug_string("P(x) | Q(y)", formula.nnf());
2302 }
2303 {
2304 let formula: Formula = "~(~P(x) | ~Q(y))".parse().unwrap();
2305 assert_debug_string("P(x) & Q(y)", formula.nnf());
2306 }
2307 {
2308 let formula: Formula = "~(~P(x) -> ~Q(y))".parse().unwrap();
2309 assert_debug_string("(~P(x)) & Q(y)", formula.nnf());
2310 }
2311 {
2312 let formula: Formula = "~(~(P(x) & Q(x)) & ~(P(y) & Q(y)))".parse().unwrap();
2313 assert_debug_string("(P(x) & Q(x)) | (P(y) & Q(y))", formula.nnf());
2314 }
2315 {
2316 let formula: Formula = "~(~(P(x) & Q(x)) | ~(P(y) & Q(y)))".parse().unwrap();
2317 assert_debug_string("(P(x) & Q(x)) & (P(y) & Q(y))", formula.nnf());
2318 }
2319 {
2320 let formula: Formula = "~(~(P(x) & Q(x)) -> ~(P(y) & Q(y)))".parse().unwrap();
2321 assert_debug_string("((~P(x)) | (~Q(x))) & (P(y) & Q(y))", formula.nnf());
2322 }
2323 {
2324 let formula: Formula = "~(~(P(x) & Q(x)) <=> ~(P(y) & Q(y)))".parse().unwrap();
2325 assert_debug_string("(((~P(x)) | (~Q(x))) & (P(y) & Q(y))) | ((P(x) & Q(x)) & ((~P(y)) | (~Q(y))))",
2326 formula.nnf());
2327 }
2328 {
2329 let formula: Formula = "~?x. !y. (P(x) -> Q(y))".parse().unwrap();
2330 assert_debug_string("! x. (? y. (P(x) & (~Q(y))))", formula.nnf());
2331 }
2332 {
2333 let formula: Formula = "~((?x. P(x)) & (!y. Q(y)))".parse().unwrap();
2334 assert_debug_string("(! x. (~P(x))) | (? y. (~Q(y)))", formula.nnf());
2335 }
2336 }
2337
2338 #[test]
2339 fn test_cnf() {
2340 {
2341 let formula: Formula = "true".parse().unwrap();
2342 assert_debug_string("true", formula.cnf());
2343 }
2344 {
2345 let formula: Formula = "false".parse().unwrap();
2346 assert_debug_string("false", formula.cnf());
2347 }
2348 {
2349 let formula: Formula = "P(f(), g(f(), f()))".parse().unwrap();
2350 assert_debug_string("P(f(), g(f(), f()))", formula.cnf());
2351 }
2352 {
2353 let formula: Formula = "P(x)".parse().unwrap();
2354 assert_debug_string("P(x)", formula.cnf());
2355 }
2356 {
2357 let formula: Formula = "x=y".parse().unwrap();
2358 assert_debug_string("x = y", formula.cnf());
2359 }
2360 {
2361 let formula: Formula = "P(x) & Q(y)".parse().unwrap();
2362 assert_debug_string("P(x) & Q(y)", formula.cnf());
2363 }
2364 {
2365 let formula: Formula = "P(x) | Q(y)".parse().unwrap();
2366 assert_debug_string("P(x) | Q(y)", formula.cnf());
2367 }
2368 {
2369 let formula: Formula = "P(x) -> Q(y)".parse().unwrap();
2370 assert_debug_string("(~P(x)) | Q(y)", formula.cnf());
2371 }
2372 {
2373 let formula: Formula = "P(x) <=> Q(y)".parse().unwrap();
2374 assert_debug_string("((~P(x)) | Q(y)) & ((~Q(y)) | P(x))", formula.cnf());
2375 }
2376 {
2377 let formula: Formula = "!x. P(x)".parse().unwrap();
2378 assert_debug_string("P(x)", formula.cnf());
2379 }
2380 {
2381 let formula: Formula = "!x. P(f(), g(f(), x))".parse().unwrap();
2382 assert_debug_string("P(f(), g(f(), x))", formula.cnf());
2383 }
2384 {
2386 let formula: Formula = "~((P(x1) | P(x2)) and Q(y))".parse().unwrap();
2387 assert_debug_string("((~P(x1)) | (~Q(y))) & ((~P(x2)) | (~Q(y)))", formula.cnf());
2388 }
2389 {
2390 let formula: Formula = "P(x) | ~(Q(x) -> Q(y))".parse().unwrap();
2391 assert_debug_string("(P(x) | Q(x)) & (P(x) | (~Q(y)))", formula.cnf());
2392 }
2393 {
2394 let formula: Formula = "(P(x) | Q(y)) -> R(z)".parse().unwrap();
2395 assert_debug_string("((~P(x)) | R(z)) & ((~Q(y)) | R(z))", formula.cnf());
2396 }
2397 {
2398 let formula: Formula = "P(x) | ~(Q(x) <=> Q(y))".parse().unwrap();
2399 assert_debug_string("((P(x) | (Q(x) | Q(y))) & (P(x) | (Q(x) | (~Q(x))))) & ((P(x) | ((~Q(y)) | Q(y))) & (P(x) | ((~Q(y)) | (~Q(x)))))",
2400 formula.cnf());
2401 }
2402 {
2403 let formula: Formula = "(P(x) | Q(y)) <=> R(z)".parse().unwrap();
2404 assert_debug_string("(((~P(x)) | R(z)) & ((~Q(y)) | R(z))) & ((~R(z)) | (P(x) | Q(y)))",
2405 formula.cnf());
2406 }
2407 {
2408 let formula: Formula = "P(x) | (Q(x) | (R(y) & R(z)))".parse().unwrap();
2409 assert_debug_string("(P(x) | (Q(x) | R(y))) & (P(x) | (Q(x) | R(z)))",
2410 formula.cnf());
2411 }
2412 {
2413 let formula: Formula = "(P(x1) & P(x2)) | (Q(x1) & Q(x2))".parse().unwrap();
2414 assert_debug_string("((P(x1) | Q(x1)) & (P(x1) | Q(x2))) & ((P(x2) | Q(x1)) & (P(x2) | Q(x2)))",
2415 formula.cnf());
2416 }
2417 {
2419 let formula: Formula = "?x. P(x)".parse().unwrap();
2420 assert_debug_string("P('sk#0)", formula.cnf());
2421 }
2422 {
2423 let formula: Formula = "?x. (P(x) & Q(f(), x))".parse().unwrap();
2424 assert_debug_string("P('sk#0) & Q(f(), 'sk#0)", formula.cnf());
2425 }
2426 {
2427 let formula: Formula = "!x. ((? y. P(y) & Q(x, y)) -> R(x))".parse().unwrap();
2428 assert_debug_string("((~P(y)) | (~Q(x, y))) | R(x)", formula.cnf());
2429 }
2430 {
2431 let formula: Formula = "!x. (P(x) -> !y. (Q(y) -> ~R(x, y)))".parse().unwrap();
2432 assert_debug_string("(~P(x)) | ((~Q(y)) | (~R(x, y)))", formula.cnf());
2433 }
2434 {
2435 let formula: Formula = "!y. (!x. (P(y, x) | Q(x)) -> Q(y))".parse().unwrap();
2436 assert_debug_string("((~P(y, sk#0(y))) | Q(y)) & ((~Q(sk#0(y))) | Q(y))", formula.cnf());
2437 }
2438 {
2439 let formula: Formula = "?x. ?y. P(x, y)".parse().unwrap();
2440 assert_debug_string("P('sk#0, 'sk#1)", formula.cnf());
2441 }
2442 {
2443 let formula: Formula = "?x, y. P(x, y)".parse().unwrap();
2444 assert_debug_string("P('sk#0, 'sk#1)", formula.cnf());
2445 }
2446 {
2447 let formula: Formula = "!x. ?y. P(x, y)".parse().unwrap();
2448 assert_debug_string("P(x, sk#0(x))", formula.cnf());
2449 }
2450 {
2451 let formula: Formula = "R(z) -> ?u. (!x, y. (P(u, x) & ~? u, x, w. (Q(u, x, y) | (w = f(u)))))".parse().unwrap();
2452 assert_debug_string("((~R(z)) | P(sk#0(z), x)) & (((~R(z)) | (~Q(u`, x`, y))) & ((~R(z)) | (~(w = f(u`)))))",
2453 formula.cnf());
2454 }
2455 {
2456 let formula: Formula = "!x. (!y. (P(y) -> Q(x, y)) -> ?y. Q(y, x))".parse().unwrap();
2457 assert_debug_string("(P(sk#0(x)) | Q(sk#1(x), x)) & ((~Q(x, sk#0(x))) | Q(sk#1(x), x))",
2458 formula.cnf());
2459 }
2460 {
2461 let formula: Formula = "?x. (!y, z. (P(x) & ((Q(x, y) & ~(y = z)) -> ~Q(x, z))))".parse().unwrap();
2462 assert_debug_string("P('sk#0) & (((~Q('sk#0, y)) | (y = z)) | (~Q('sk#0, z)))",
2463 formula.cnf());
2464 }
2465 {
2466 let formula: Formula = "!x. (P(x) -> (!y. (P(y) -> P(f(x, y))) & ~!y. (Q(x, y) -> P(y))))".parse().unwrap();
2467 assert_debug_string("((~P(x)) | ((~P(y)) | P(f(x, y)))) & (((~P(x)) | Q(x, sk#0(x, y))) & ((~P(x)) | (~P(sk#0(x, y)))))",
2468 formula.cnf());
2469 }
2470 }
2471
2472 #[test]
2473 fn test_dnf() {
2474 {
2475 let formula: Formula = "true".parse().unwrap();
2476 assert_debug_string("true", formula.dnf());
2477 }
2478 {
2479 let formula: Formula = "false".parse().unwrap();
2480 assert_debug_string("false", formula.dnf());
2481 }
2482 {
2483 let formula: Formula = "P(f(), g(f(), f()))".parse().unwrap();
2484 assert_debug_string("P(f(), g(f(), f()))", formula.dnf());
2485 }
2486 {
2487 let formula: Formula = "P(x)".parse().unwrap();
2488 assert_debug_string("P(x)", formula.dnf());
2489 }
2490 {
2491 let formula: Formula = "x=y".parse().unwrap();
2492 assert_debug_string("x = y", formula.dnf());
2493 }
2494 {
2495 let formula: Formula = "P(x) & Q(y)".parse().unwrap();
2496 assert_debug_string("P(x) & Q(y)", formula.dnf());
2497 }
2498 {
2499 let formula: Formula = "P(x) | Q(y)".parse().unwrap();
2500 assert_debug_string("P(x) | Q(y)", formula.dnf());
2501 }
2502 {
2503 let formula: Formula = "P(x) -> Q(y)".parse().unwrap();
2504 assert_debug_string("(~P(x)) | Q(y)", formula.dnf());
2505 }
2506 {
2507 let formula: Formula = "P(x) <=> Q(y)".parse().unwrap();
2508 assert_debug_string("(((~P(x)) & (~Q(y))) | ((~P(x)) & P(x))) | ((Q(y) & (~Q(y))) | (Q(y) & P(x)))",
2509 formula.dnf());
2510 }
2511 {
2512 let formula: Formula = "!x. P(x)".parse().unwrap();
2513 assert_debug_string("P(x)", formula.dnf());
2514 }
2515 {
2516 let formula: Formula = "!x. P(f(), g(f(), x))".parse().unwrap();
2517 assert_debug_string("P(f(), g(f(), x))", formula.dnf());
2518 }
2519 {
2521 let formula: Formula = "~((P(x1) | P(x2)) and Q(y))".parse().unwrap();
2522 assert_debug_string("((~P(x1)) & (~P(x2))) | (~Q(y))", formula.dnf());
2523 }
2524 {
2525 let formula: Formula = "P(x) | ~(Q(x) -> Q(y))".parse().unwrap();
2526 assert_debug_string("P(x) | (Q(x) & (~Q(y)))", formula.dnf());
2527 }
2528 {
2529 let formula: Formula = "(P(x) | Q(y)) -> R(z)".parse().unwrap();
2530 assert_debug_string("((~P(x)) & (~Q(y))) | R(z)", formula.dnf());
2531 }
2532 {
2533 let formula: Formula = "P(x) | ~(Q(x) <=> Q(y))".parse().unwrap();
2534 assert_debug_string("P(x) | ((Q(x) & (~Q(y))) | (Q(y) & (~Q(x))))", formula.dnf());
2535 }
2536 {
2537 let formula: Formula = "(P(x) | Q(y)) <=> R(z)".parse().unwrap();
2538 assert_debug_string("((((~P(x)) & (~Q(y))) & (~R(z))) | ((((~P(x)) & (~Q(y))) & P(x)) | (((~P(x)) & (~Q(y))) & Q(y)))) | ((R(z) & (~R(z))) | ((R(z) & P(x)) | (R(z) & Q(y))))",
2539 formula.dnf());
2540 }
2541 {
2542 let formula: Formula = "P(x) | (Q(x) | (R(y) & R(z)))".parse().unwrap();
2543 assert_debug_string("P(x) | (Q(x) | (R(y) & R(z)))", formula.dnf());
2544 }
2545 {
2546 let formula: Formula = "(P(x1) & P(x2)) | (Q(x1) & Q(x2))".parse().unwrap();
2547 assert_debug_string("(P(x1) & P(x2)) | (Q(x1) & Q(x2))", formula.dnf());
2548 }
2549
2550 {
2552 let formula: Formula = "?x. P(x)".parse().unwrap();
2553 assert_debug_string("P('sk#0)", formula.dnf());
2554 }
2555 {
2556 let formula: Formula = "?x. (P(x) & Q(f(), x))".parse().unwrap();
2557 assert_debug_string("P('sk#0) & Q(f(), 'sk#0)", formula.dnf());
2558 }
2559 {
2560 let formula: Formula = "!x. ((? y. P(y) & Q(x, y)) -> R(x))".parse().unwrap();
2561 assert_debug_string("((~P(y)) | (~Q(x, y))) | R(x)", formula.dnf());
2562 }
2563 {
2564 let formula: Formula = "!x. (P(x) -> !y. (Q(y) -> ~R(x, y)))".parse().unwrap();
2565 assert_debug_string("(~P(x)) | ((~Q(y)) | (~R(x, y)))", formula.dnf());
2566 }
2567 {
2568 let formula: Formula = "!y. (!x. (P(y, x) | Q(x)) -> Q(y))".parse().unwrap();
2569 assert_debug_string("((~P(y, sk#0(y))) & (~Q(sk#0(y)))) | Q(y)", formula.dnf());
2570 }
2571 {
2572 let formula: Formula = "?x. ?y. P(x, y)".parse().unwrap();
2573 assert_debug_string("P('sk#0, 'sk#1)", formula.dnf());
2574 }
2575 {
2576 let formula: Formula = "?x, y. P(x, y)".parse().unwrap();
2577 assert_debug_string("P('sk#0, 'sk#1)", formula.dnf());
2578 }
2579 {
2580 let formula: Formula = "!x. ?y. P(x, y)".parse().unwrap();
2581 assert_debug_string("P(x, sk#0(x))", formula.dnf());
2582 }
2583 {
2584 let formula: Formula = "R(z) -> ?u. (!x, y. (P(u, x) & ~? u, x, w. (Q(u, x, y) | (w = f(u)))))".parse().unwrap();
2585 assert_debug_string("(~R(z)) | (P(sk#0(z), x) & ((~Q(u`, x`, y)) & (~(w = f(u`)))))",
2586 formula.dnf());
2587 }
2588 {
2589 let formula: Formula = "!x. (!y. (P(y) -> Q(x, y)) -> ?y. Q(y, x))".parse().unwrap();
2590 assert_debug_string("(P(sk#0(x)) & (~Q(x, sk#0(x)))) | Q(sk#1(x), x)",
2591 formula.dnf());
2592 }
2593 {
2594 let formula: Formula = "?x. (!y, z. (P(x) & ((Q(x, y) & ~(y = z)) -> ~Q(x, z))))".parse().unwrap();
2595 assert_debug_string("((P('sk#0) & (~Q('sk#0, y))) | (P('sk#0) & (y = z))) | (P('sk#0) & (~Q('sk#0, z)))",
2596 formula.dnf());
2597 }
2598 {
2599 let formula: Formula = "!x. (P(x) -> (!y. (P(y) -> P(f(x, y))) & ~!y. (Q(x, y) -> P(y))))".parse().unwrap();
2600 assert_debug_string("(~P(x)) | (((~P(y)) & (Q(x, sk#0(x, y)) & (~P(sk#0(x, y))))) | (P(f(x, y)) & (Q(x, sk#0(x, y)) & (~P(sk#0(x, y))))))",
2601 formula.dnf());
2602 }
2603 }
2604
2605 #[test]
2606 fn test_simplify() {
2607 {
2608 let formula: Formula = "~true".parse().unwrap();
2609 assert_debug_string("false", formula.simplify());
2610 }
2611 {
2612 let formula: Formula = "~false".parse().unwrap();
2613 assert_debug_string("true", formula.simplify());
2614 }
2615 {
2616 let formula: Formula = "~P(x)".parse().unwrap();
2617 assert_debug_string("~P(x)", formula.simplify());
2618 }
2619 {
2620 let formula: Formula = "true & true".parse().unwrap();
2621 assert_debug_string("true", formula.simplify());
2622 }
2623 {
2624 let formula: Formula = "false & false".parse().unwrap();
2625 assert_debug_string("false", formula.simplify());
2626 }
2627 {
2628 let formula: Formula = "false & true".parse().unwrap();
2629 assert_debug_string("false", formula.simplify());
2630 }
2631 {
2632 let formula: Formula = "true & false".parse().unwrap();
2633 assert_debug_string("false", formula.simplify());
2634 }
2635 {
2636 let formula: Formula = "P(x) & true".parse().unwrap();
2637 assert_debug_string("P(x)", formula.simplify());
2638 }
2639 {
2640 let formula: Formula = "false & P(x)".parse().unwrap();
2641 assert_debug_string("false", formula.simplify());
2642 }
2643 {
2644 let formula: Formula = "P(x) & false".parse().unwrap();
2645 assert_debug_string("false", formula.simplify());
2646 }
2647 {
2648 let formula: Formula = "true & P(x)".parse().unwrap();
2649 assert_debug_string("P(x)", formula.simplify());
2650 }
2651 {
2652 let formula: Formula = "P(x) & Q(x)".parse().unwrap();
2653 assert_debug_string("P(x) & Q(x)", formula.simplify());
2654 }
2655 {
2656 let formula: Formula = "true | true".parse().unwrap();
2657 assert_debug_string("true", formula.simplify());
2658 }
2659 {
2660 let formula: Formula = "false | false".parse().unwrap();
2661 assert_debug_string("false", formula.simplify());
2662 }
2663 {
2664 let formula: Formula = "false | true".parse().unwrap();
2665 assert_debug_string("true", formula.simplify());
2666 }
2667 {
2668 let formula: Formula = "true | false".parse().unwrap();
2669 assert_debug_string("true", formula.simplify());
2670 }
2671 {
2672 let formula: Formula = "P(x) | true".parse().unwrap();
2673 assert_debug_string("true", formula.simplify());
2674 }
2675 {
2676 let formula: Formula = "false | P(x)".parse().unwrap();
2677 assert_debug_string("P(x)", formula.simplify());
2678 }
2679 {
2680 let formula: Formula = "P(x) | false".parse().unwrap();
2681 assert_debug_string("P(x)", formula.simplify());
2682 }
2683 {
2684 let formula: Formula = "true | P(x)".parse().unwrap();
2685 assert_debug_string("true", formula.simplify());
2686 }
2687 {
2688 let formula: Formula = "P(x) | Q(x)".parse().unwrap();
2689 assert_debug_string("P(x) | Q(x)", formula.simplify());
2690 }
2691 {
2692 let formula: Formula = "true -> true".parse().unwrap();
2693 assert_debug_string("true", formula.simplify());
2694 }
2695 {
2696 let formula: Formula = "false -> false".parse().unwrap();
2697 assert_debug_string("true", formula.simplify());
2698 }
2699 {
2700 let formula: Formula = "false -> true".parse().unwrap();
2701 assert_debug_string("true", formula.simplify());
2702 }
2703 {
2704 let formula: Formula = "true -> false".parse().unwrap();
2705 assert_debug_string("false", formula.simplify());
2706 }
2707 {
2708 let formula: Formula = "P(x) -> true".parse().unwrap();
2709 assert_debug_string("true", formula.simplify());
2710 }
2711 {
2712 let formula: Formula = "false -> P(x)".parse().unwrap();
2713 assert_debug_string("true", formula.simplify());
2714 }
2715 {
2716 let formula: Formula = "P(x) -> false".parse().unwrap();
2717 assert_debug_string("~P(x)", formula.simplify());
2718 }
2719 {
2720 let formula: Formula = "true -> P(x)".parse().unwrap();
2721 assert_debug_string("P(x)", formula.simplify());
2722 }
2723 {
2724 let formula: Formula = "P(x) -> Q(x)".parse().unwrap();
2725 assert_debug_string("P(x) -> Q(x)", formula.simplify());
2726 }
2727 {
2728 let formula: Formula = "true <=> true".parse().unwrap();
2729 assert_debug_string("true", formula.simplify());
2730 }
2731 {
2732 let formula: Formula = "false <=> false".parse().unwrap();
2733 assert_debug_string("true", formula.simplify());
2734 }
2735 {
2736 let formula: Formula = "false <=> true".parse().unwrap();
2737 assert_debug_string("false", formula.simplify());
2738 }
2739 {
2740 let formula: Formula = "true <=> false".parse().unwrap();
2741 assert_debug_string("false", formula.simplify());
2742 }
2743 {
2744 let formula: Formula = "P(x) <=> true".parse().unwrap();
2745 assert_debug_string("P(x)", formula.simplify());
2746 }
2747 {
2748 let formula: Formula = "false <=> P(x)".parse().unwrap();
2749 assert_debug_string("~P(x)", formula.simplify());
2750 }
2751 {
2752 let formula: Formula = "P(x) <=> false".parse().unwrap();
2753 assert_debug_string("~P(x)", formula.simplify());
2754 }
2755 {
2756 let formula: Formula = "true <=> P(x)".parse().unwrap();
2757 assert_debug_string("P(x)", formula.simplify());
2758 }
2759 {
2760 let formula: Formula = "P(x) <=> Q(x)".parse().unwrap();
2761 assert_debug_string("P(x) <=> Q(x)", formula.simplify());
2762 }
2763 {
2764 let formula: Formula = "?x, y. P(y, z)".parse().unwrap();
2765 assert_debug_string("? y. P(y, z)", formula.simplify());
2766 }
2767 {
2768 let formula: Formula = "?x. P(x)".parse().unwrap();
2769 assert_debug_string("? x. P(x)", formula.simplify());
2770 }
2771 {
2772 let formula: Formula = "?x. P(y)".parse().unwrap();
2773 assert_debug_string("P(y)", formula.simplify());
2774 }
2775 {
2776 let formula: Formula = "!x, y. P(y, z)".parse().unwrap();
2777 assert_debug_string("! y. P(y, z)", formula.simplify());
2778 }
2779 {
2780 let formula: Formula = "!x. P(x)".parse().unwrap();
2781 assert_debug_string("! x. P(x)", formula.simplify());
2782 }
2783 {
2784 let formula: Formula = "!x. P(y)".parse().unwrap();
2785 assert_debug_string("P(y)", formula.simplify());
2786 }
2787 {
2789 let formula: Formula = "~~P(x)".parse().unwrap();
2790 assert_debug_string("P(x)", formula.simplify());
2791 }
2792 {
2793 let formula: Formula = "~~~P(x)".parse().unwrap();
2794 assert_debug_string("~P(x)", formula.simplify());
2795 }
2796 {
2797 let formula: Formula = "~(true -> false)".parse().unwrap();
2798 assert_debug_string("true", formula.simplify());
2799 }
2800 {
2801 let formula: Formula = "false | (P(x) & true)".parse().unwrap();
2802 assert_debug_string("P(x)", formula.simplify());
2803 }
2804 {
2805 let formula: Formula = "?x. P(x) | true".parse().unwrap();
2806 assert_debug_string("true", formula.simplify());
2807 }
2808 {
2809 let formula: Formula = "?y. (P(x) -> false) & (false -> Q(x))".parse().unwrap();
2810 assert_debug_string("~P(x)", formula.simplify());
2811 }
2812 {
2813 let formula: Formula = "!x. ?y. P(x, y) | true".parse().unwrap();
2814 assert_debug_string("true", formula.simplify());
2815 }
2816 {
2817 let formula: Formula = "(((x = y -> false) -> false) -> false) -> false".parse().unwrap();
2818 assert_debug_string("x = y", formula.simplify());
2819 }
2820 {
2821 let formula: Formula = "!x, y, z. ?z. P(x) | w = x".parse().unwrap();
2822 assert_debug_string("! x. (P(x) | (w = x))", formula.simplify());
2823 }
2824 {
2825 let formula: Formula = "(P(x) | false) | (P(x) | true)".parse().unwrap();
2826 assert_debug_string("true", formula.simplify());
2827 }
2828 {
2829 let formula: Formula = "(P(x) & false) & (P(x) & true)".parse().unwrap();
2830 assert_debug_string("false", formula.simplify());
2831 }
2832 }
2833
2834 #[test]
2835 fn test_gnf() {
2836 {
2837 let formula: Formula = "true".parse().unwrap();
2838 assert_debug_strings("true -> true", formula.gnf());
2839 }
2840 {
2841 let formula: Formula = "false".parse().unwrap();
2842 assert_debug_strings("true -> false", formula.gnf());
2843 }
2844 {
2845 let formula: Formula = "P(x)".parse().unwrap();
2846 assert_debug_strings("true -> P(x)", formula.gnf());
2847 }
2848 {
2849 let formula: Formula = "x = y".parse().unwrap();
2850 assert_debug_strings("true -> (x = y)", formula.gnf());
2851 }
2852 {
2853 let formula: Formula = "~P(x)".parse().unwrap();
2854 assert_debug_strings("P(x) -> false", formula.gnf());
2855 }
2856 {
2857 let formula: Formula = "P(x) -> Q(x)".parse().unwrap();
2858 assert_debug_strings("P(x) -> Q(x)", formula.gnf());
2859 }
2860 {
2861 let formula: Formula = "P(x) & Q(x)".parse().unwrap();
2862 assert_debug_strings("true -> P(x)\ntrue -> Q(x)", formula.gnf());
2863 }
2864 {
2865 let formula: Formula = "P(x) | Q(x)".parse().unwrap();
2866 assert_debug_strings("true -> (P(x) | Q(x))", formula.gnf());
2867 }
2868 {
2869 let formula: Formula = "! x. P(x)".parse().unwrap();
2870 assert_debug_strings("true -> P(x)", formula.gnf());
2871 }
2872 {
2873 let formula: Formula = "? x. P(x)".parse().unwrap();
2874 assert_debug_strings("true -> P('sk#0)", formula.gnf());
2875 }
2876 {
2877 let formula: Formula = "P(x) & Q(x) -> P(y) | Q(y)".parse().unwrap();
2878 assert_debug_strings("(P(x) & Q(x)) -> (P(y) | Q(y))", formula.gnf());
2879 }
2880 {
2881 let formula: Formula = "P(x) | Q(x) -> P(y) & Q(y)".parse().unwrap();
2882 assert_debug_strings("P(x) -> P(y)\n\
2883 P(x) -> Q(y)\n\
2884 Q(x) -> P(y)\n\
2885 Q(x) -> Q(y)", formula.gnf());
2886 }
2887 {
2888 let formula: Formula = "P(x) | Q(x) <=> P(y) & Q(y)".parse().unwrap();
2889 assert_debug_strings("P(x) -> P(y)\n\
2890 P(x) -> Q(y)\n\
2891 Q(x) -> P(y)\n\
2892 Q(x) -> Q(y)\n\
2893 (P(y) & Q(y)) -> (P(x) | Q(x))", formula.gnf());
2894 }
2895 {
2896 let formula: Formula = "!x. (P(x) -> ?y. Q(x,y))".parse().unwrap();
2897 assert_debug_strings("P(x) -> Q(x, sk#0(x))", formula.gnf());
2898 }
2899 {
2900 let formula: Formula = "!x. (P(x) -> (?y. (Q(y) & R(x, y)) | ?y. (P(y) & S(x, y)))))".parse().unwrap();
2901 assert_debug_strings("P(x) -> (Q(sk#0(x)) | P(sk#1(x)))\n\
2902 P(x) -> (Q(sk#0(x)) | S(x, sk#1(x)))\n\
2903 P(x) -> (R(x, sk#0(x)) | P(sk#1(x)))\n\
2904 P(x) -> (R(x, sk#0(x)) | S(x, sk#1(x)))", formula.gnf());
2905 }
2906 {
2907 let formula: Formula = "!x, y. ((P(x) & Q(y)) -> (R(x, y) -> S(x, y)))".parse().unwrap();
2908 assert_debug_strings("((P(x) & Q(y)) & R(x, y)) -> S(x, y)", formula.gnf());
2909 }
2910 {
2911 let formula: Formula = "!x, y. ((P(x) & Q(y)) <=> (R(x, y) <=> S(x, y)))".parse().unwrap();
2912 assert_debug_strings("((P(x) & Q(y)) & R(x, y)) -> S(x, y)\n\
2913 ((P(x) & Q(y)) & S(x, y)) -> R(x, y)\n\
2914 true -> ((R(x, y) | S(x, y)) | P(x))\n\
2915 true -> ((R(x, y) | S(x, y)) | Q(y))\n\
2916 R(x, y) -> (R(x, y) | P(x))\n\
2917 R(x, y) -> (R(x, y) | Q(y))\n\
2918 S(x, y) -> (S(x, y) | P(x))\n\
2919 S(x, y) -> (S(x, y) | Q(y))\n\
2920 (S(x, y) & R(x, y)) -> P(x)\n\
2921 (S(x, y) & R(x, y)) -> Q(y)", formula.gnf());
2922 }
2923 {
2924 let formula: Formula = "? x. P(x) -> Q(x)".parse().unwrap();
2925 assert_debug_strings("P(x`) -> Q(x)", formula.gnf());
2926 }
2927 {
2928 let formula: Formula = "? x. (P(x) -> Q(x))".parse().unwrap();
2929 assert_debug_strings("P('sk#0) -> Q('sk#0)", formula.gnf());
2930 }
2931 {
2932 let formula: Formula = "false -> P(x)".parse().unwrap();
2933 assert_debug_strings("true -> true", formula.gnf());
2934 }
2935 }
2936
2937 #[test]
2938 fn test_gnf_theory() {
2939 {
2941 let theory: Theory = "P('a); P('b);".parse().unwrap();
2942 assert_debug_strings("true -> (P('a) & P('b))", theory.gnf().formulae);
2943 }
2944 {
2945 let theory: Theory = "P('a); P(x);".parse().unwrap();
2946 assert_debug_strings("true -> P(x)\ntrue -> P('a)", theory.gnf().formulae);
2947 }
2948 {
2949 let theory: Theory = "P('a); P(x); P('b);".parse().unwrap();
2950 assert_debug_strings("true -> P(x)\ntrue -> (P(\'a) & P(\'b))", theory.gnf().formulae);
2951 }
2952 {
2953 let theory: Theory = "(T() and V()) or (U() and V());".parse().unwrap();
2954 assert_debug_strings("true -> ((T() & V()) | (U() & V()))", theory.gnf().formulae);
2955 }
2956 }
2957}