summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Notzli <andres.noetzli@gmail.com>2016-08-04 17:39:53 -0700
committerAndres Notzli <andres.noetzli@gmail.com>2017-05-08 11:50:15 -0700
commit992dffa1eba7ee1a8dc2000ae7bef45fdaee8d0c (patch)
tree856e7ca89c94df676d0eed98af68c8dcf829829b
parent5ab14e1abdff2cd4e75b3b698dc3d65fb07be3c1 (diff)
Support rewrite proofs
-rw-r--r--proofs/lfsc_checker/trie.cpp2
-rw-r--r--proofs/signatures/smt.plf95
-rw-r--r--proofs/signatures/th_arrays.plf25
-rw-r--r--proofs/signatures/th_bv.plf290
-rw-r--r--src/Makefile.am4
-rw-r--r--src/compat/Makefile.am2
-rw-r--r--src/lib/Makefile.am1
-rw-r--r--src/main/Makefile.am5
-rw-r--r--src/parser/Makefile.am2
-rw-r--r--src/parser/cvc/Cvc.g2
-rw-r--r--src/parser/smt1/Smt1.g2
-rw-r--r--src/parser/smt2/Smt2.g2
-rw-r--r--src/proof/proof_manager.cpp21
-rw-r--r--src/proof/proof_manager.h3
-rw-r--r--src/proof/rewrite_proof.cpp157
-rw-r--r--src/proof/rewrite_proof.h86
-rw-r--r--src/proof/rewrite_proof_dispatcher.cpp83
-rw-r--r--src/proof/rewrite_proof_dispatcher.h28
-rw-r--r--src/smt/smt_engine.cpp2
-rw-r--r--src/theory/arrays/theory_arrays_rewriter.cpp69
-rw-r--r--src/theory/arrays/theory_arrays_rewriter.h42
-rw-r--r--src/theory/booleans/bool.h1085
-rw-r--r--src/theory/booleans/theory_bool_rewriter.cpp170
-rw-r--r--src/theory/booleans/theory_bool_rewriter.h16
-rw-r--r--src/theory/quantifiers/quantifiers_rewriter.cpp2
-rw-r--r--src/theory/rewriter.cpp86
-rw-r--r--src/theory/rewriter.h42
-rw-r--r--test/regress/regress0/arrays/Makefile.am5
-rw-r--r--test/regress/regress0/arrays/rewrite_proof_cache.smt214
-rw-r--r--test/regress/regress0/arrays/simple_rewrite_proof.smt213
-rw-r--r--test/regress/regress0/arrays/simple_rewrite_proof2.smt213
31 files changed, 2309 insertions, 60 deletions
diff --git a/proofs/lfsc_checker/trie.cpp b/proofs/lfsc_checker/trie.cpp
index fedb508b0..5e25e1e90 100644
--- a/proofs/lfsc_checker/trie.cpp
+++ b/proofs/lfsc_checker/trie.cpp
@@ -12,7 +12,7 @@ public:
template <>
Trie<int>::Cleaner *Trie<int>::cleaner = new Simple;
-void unit_test_trie() {
+int main() {
Trie<int> t;
t.insert("a", 1);
t.insert("b", 2);
diff --git a/proofs/signatures/smt.plf b/proofs/signatures/smt.plf
index 06dc16153..a4de73c7d 100644
--- a/proofs/signatures/smt.plf
+++ b/proofs/signatures/smt.plf
@@ -215,9 +215,7 @@
(! f formula
(th_holds (iff f f))))
-
;; contradiction
-
(declare contra
(! f formula
(! r1 (th_holds f)
@@ -385,6 +383,99 @@
(! u2 (th_holds (not (ifte a b c)))
(th_holds (or (not b) (not c))))))))
+(declare t_eq_n_f (th_holds (iff true (not false))))
+(declare n_t_eq_f (th_holds (iff (not true) false)))
+
+;; XXX: check whether x and y are constant
+;; (program constants_are_disequal ((s sort) (x (term s)) (y (term s))) formula
+;; (match x
+;; (bvn (fail formula))
+;; ((bvc bx x')
+;; (match y
+;; (bvn (fail formula))
+;; ((bvc by y') (match bx
+;; (b0 (match by (b0 (constants_are_disequal x' y')) (b1 (true))))
+;; (b1 (match by (b0 (true)) (b1 (constants_are_disequal x' y'))))
+;; ))
+;; ))
+;; ))
+;;
+;; (declare disequal_constants
+;; (! s sort
+;; (! x (term s)
+;; (! y (term s)
+;; (! c (^ (constants_are_disequal x y) true)
+;; (th_holds (not (= _ x y))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; Rewrite proofs
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Apply a unary operator to the original and the rewritten formula
+(declare symm_formula_op1
+ (! op formula_op1
+ (! x formula
+ (! y formula
+ (! u (th_holds (iff x y))
+ (th_holds (iff (op x) (op y))))))))
+
+; Apply a binary operator to the original and the rewritten formulas
+(declare symm_formula_op2
+ (! op formula_op2
+ (! x formula
+ (! y formula
+ (! z formula
+ (! w formula
+ (! u1 (th_holds (iff x z))
+ (! u2 (th_holds (iff y w))
+ (th_holds (iff (op x y) (op z w)))))))))))
+
+; Apply a ternary operator to the original and the rewritten formulas
+(declare symm_formula_op3
+ (! op formula_op3
+ (! x formula
+ (! y formula
+ (! z formula
+ (! w formula
+ (! a formula
+ (! b formula
+ (! u1 (th_holds (iff x w))
+ (! u2 (th_holds (iff y a))
+ (! u2 (th_holds (iff z b))
+ (th_holds (iff (op x y z) (op w a b))))))))))))))
+
+(declare iff_intro
+ (! s sort
+ (! x (term s)
+ (! y (term s)
+ (! z (term s)
+ (! w (term s)
+ (! lhs (th_holds (= _ x y))
+ (! rhs (th_holds (= _ z w))
+ (th_holds (iff (= _ x z) (= _ y w)))))))))))
+
+; (not true) --> false
+(declare not_t
+ (! o formula
+ (! u (th_holds (iff o (not true)))
+ (th_holds (iff o false)))))))
+
+; (=> true false) --> false
+(declare t_impl_f
+ (! o formula
+ (! u (th_holds (iff o (impl true false)))
+ (th_holds (iff o false)))))))
+
+; (= y y) --> true
+(declare iff_true
+ (! s sort
+ (! x formula
+ (! y (term s)
+ (! u (th_holds (iff x (= _ y y)))
+ (th_holds (iff x true)))))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; For theory lemmas
diff --git a/proofs/signatures/th_arrays.plf b/proofs/signatures/th_arrays.plf
index acfbd2f3b..6dc330967 100644
--- a/proofs/signatures/th_arrays.plf
+++ b/proofs/signatures/th_arrays.plf
@@ -63,3 +63,28 @@
(! u2 (th_holds (or (= _ t1 t2) (not (= _ (apply _ _ (apply _ _ (read s1 s2) t1) k) (apply _ _ (apply _ _ (read s1 s2) t2) k)))))
(holds cln)))
(holds cln)))))))
+
+; Rewrites
+(declare wor (! s18 sort
+ (! s19 sort
+ (! i (term s18)
+ (! oa (term (Array s18 s19))
+ (! a (term (Array s18 s19))
+ (! u (th_holds (= _ oa (apply _ _ (apply _ _ (apply _ _ (write s18 s19) a) i) (apply _ _ (apply _ _ (read s18 s19) a) i))))
+ (th_holds (= _ oa a))))))))))
+
+(declare wow (! s1 sort
+ (! s2 sort
+ (! i (term s1)
+ (! i2 (term s1)
+ (! v (term s2)
+ (! w (term s2)
+ (! w2 (term s2)
+ (! oa (term (Array s1 s2))
+ (! a (term (Array s1 s2))
+ (! a2 (term (Array s1 s2))
+ (! u (th_holds (= _ oa (apply _ _ (apply _ _ (apply _ _ (write s1 s2) (apply _ _ (apply _ _ (apply _ _ (write s1 s2) a) i) v)) i) w)))
+ (! u1 (th_holds (= _ a a2))
+ (! u2 (th_holds (= _ i i2))
+ (! u3 (th_holds (= _ w w2))
+ (th_holds (= _ oa (apply _ _ (apply _ _ (apply _ _ (write s1 s2) a2) i2) w2))))))))))))))))))
diff --git a/proofs/signatures/th_bv.plf b/proofs/signatures/th_bv.plf
index 6012e052a..7b036c341 100644
--- a/proofs/signatures/th_bv.plf
+++ b/proofs/signatures/th_bv.plf
@@ -37,10 +37,10 @@
(declare bvc (! b bit (! v bv bv)))
; calculate the length of a bitvector
-;; (program bv_len ((v bv)) mpz
-;; (match v
-;; (bvn 0)
-;; ((bvc b v') (mp_add (bv_len v') 1))))
+(program bv_len ((v bv)) mpz
+ (match v
+ (bvn 0)
+ ((bvc b v') (mp_add (bv_len v') 1))))
; a bv constant term
@@ -190,3 +190,285 @@
(declare bvsle bvpred)
(declare bvsgt bvpred)
(declare bvsge bvpred)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Rewrite support ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; check whether a constant bitvector is zero
+(program bv_is_constant_zero ((x bv)) formula
+ (match x
+ (bvn (true))
+ ((bvc bx x')
+ (match bx
+ (b0 (bv_is_constant_zero x'))
+ (b1 (fail formula))
+ )
+ )
+ )
+)
+
+; check whether a constant bitvector is all ones
+(program bv_is_constant_all_ones ((x bv)) formula
+ (match x
+ (bvn (true))
+ ((bvc bx x')
+ (match bx
+ (b0 (fail formula))
+ (b1 (bv_is_constant_all_ones x'))
+ )
+ )
+ )
+)
+
+; check whether a constant bitvector is a power of two
+(program bv_is_constant_pow2 ((x bv)) formula
+ (match x
+ (bvn (fail formula))
+ ((bvc bx x')
+ (match bx
+ (b0 (bv_is_constant_pow2 x'))
+ (b1 (bv_is_constant_zero x'))
+ )
+ )
+ )
+)
+
+; compute 2**len
+; TODO: add native mp_pow to lfsc more efficiency?
+(program pow2len ((x bv)) mpz
+ (match x
+ (bvn (fail mpz))
+ ((bvc bx x')
+ (match x'
+ (bvn 1)
+ ((bvc bx' x'') (mp_mul 2 (pow2len x')))
+ )
+ )
+ )
+)
+
+; convert bitvector constant to size
+(program bv_const_to_size ((x bv)) mpz
+ (match x
+ (bvn 0)
+ ((bvc bx x')
+ (match bx
+ (b0 (bv_const_to_size x'))
+ (b1 (mp_add (pow2len x) (bv_const_to_size x')))
+ )
+ )
+ )
+)
+
+; computes log2 of a bitvector constant and returns the result as a size
+; NOTE: requires the bitvector to be a power of two
+(program bv_const_log2 ((x bv)) mpz
+ (match x
+ (bvn (fail mpz))
+ ((bvc bx x')
+ (match bx
+ (b0 (bv_const_log2 x'))
+ (b1 (bv_len x'))
+ )
+ )
+ )
+)
+
+(program swap_op2_ ((op formula_op2) (x formula) (other formula) (n mpz)) formula
+ (mp_ifzero n
+ (match x
+ ((op l r) (op l (op other r)))
+ (default (op x other))
+ )
+ (match x
+ ((op l r)
+ (match (swap_op2_ op r other (mp_add n (~1)))
+ ((op e new_r) (op e (op l new_r)))
+ (x (fail formula))
+ )
+ )
+ (default (fail formula))
+ )
+ )
+)
+
+(program swap_op2 ((op formula_op2) (x formula) (n mpz) (m mpz)) formula
+ (mp_ifzero n
+ (match x
+ ((op l r) (swap_op2_ op r l (mp_add m (~1))))
+ (default (fail formula))
+ )
+ (match x
+ ((op l r) (op l (swap_op2 op r (mp_add n (~1)) (mp_add m (~1)))))
+ (default (fail formula))
+ )
+ )
+)
+
+(declare do_swap_op2
+ (! op formula_op2
+ (! n mpz
+ (! m mpz
+ (! p formula
+ (! q formula
+ (! r formula
+ (! x (th_holds (iff p q))
+ (! c (^ (swap_op2 op q n m) r)
+ (th_holds (iff p r)))))))))))
+
+(program get_op2 ((op formula_op2) (x formula) (n mpz)) formula
+ (mp_ifzero n
+ (match x
+ ((op l r) l)
+ (default x)
+ )
+ (match x
+ ((op l r) (get_op2 op r (mp_add n (~1))))
+ (default (fail formula))
+ )
+ )
+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Test helpers ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(declare test_bv_is_constant_zero
+ (! x bv
+ (! c (^ (bv_is_constant_zero x) true)
+ (th_holds true))))
+
+(declare test_bv_is_constant_all_ones
+ (! x bv
+ (! c (^ (bv_is_constant_all_ones x) true)
+ (th_holds true))))
+
+(declare test_bv_is_constant_pow2
+ (! x bv
+ (! c (^ (bv_is_constant_pow2 x) true)
+ (th_holds true))))
+
+(declare test_pow2len
+ (! n mpz
+ (! x bv
+ (! c (^ (pow2len x) n)
+ (th_holds true)))))
+
+(declare test_bv_const_to_size
+ (! n mpz
+ (! x bv
+ (! c (^ (bv_const_to_size x) n)
+ (th_holds true)))))
+
+(declare test_bv_const_log2
+ (! n mpz
+ (! x bv
+ (! c (^ (bv_const_log2 x) n)
+ (th_holds true)))))
+
+(declare test_swap_op2
+ (! x formula
+ (! y formula
+ (! op formula_op2
+ (! n mpz
+ (! m mpz
+ (! c (^ (swap_op2 op x n m) y)
+ (th_holds y))))))))
+
+(declare test_get_op2
+ (! x formula
+ (! op formula_op2
+ (! n mpz
+ (! c (^ (get_op2 op x n) (iff true false))
+ (th_holds true))))))))))
+
+(declare test_nested_get_op2
+ (! x formula
+ (! op formula_op2
+ (! n mpz
+ (! c (^ (get_op2 op x n) (iff true false))
+ (th_holds true))))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; EXAMPLES
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; XXX: remove
+; (declare shl_by_const_zero
+; (! n mpz
+; (! x (term (BitVec n))
+; (! y bv
+; (! o (term (BitVec n))
+; (! u1 (th_holds (= _ o (bvshl n x (a_bv n y))))
+; (! u2 (^ (bv_is_constant_zero y) true)
+; (th_holds (= _ o x)))))))))
+
+(declare shl_by_const_zero
+ (! n10 mpz
+ (! x (term (BitVec n10))
+ (! XXXv0 bv
+ (! o (term (BitVec n10))
+ (! u (th_holds (= _ o (bvshl _ x (a_bv _ XXXv0))))
+ (! u (^ (bv_is_constant_zero XXXv0) true)
+ (th_holds (= _ o x)))))))))
+
+; XXX: remove
+; (declare shl_by_const_more_than_len
+; (! n mpz
+; (! x (term (BitVec n))
+; (! y bv
+; (! o (term (BitVec n))
+; (! r bv
+; (! u1 (th_holds (= _ o (bvshl n x (a_bv n y))))
+; (! u2 (^ (mpz_lte n (bv_const_to_size y)) true)
+; (! u3 (^ (bv_is_constant_zero r) true)
+; (th_holds (= _ o (a_bv n r))))))))))))
+
+(declare shl_by_const_more_than_len
+ (! n26 mpz
+ (! x (term (BitVec n26))
+ (! y bv
+ (! o (term (BitVec n26))
+ (! XXXv1 bv
+ (! u (th_holds (= _ o (bvshl _ x (a_bv _ y))))
+ (! u (^ (mpz_lte (n26) (bv_const_to_size y)) true)
+ (! u (^ (bv_is_constant_zero XXXv1) true)
+ (th_holds (= _ o (a_bv _ XXXv1))))))))))))
+
+; Name: SHL_BY_CONST
+; Precond: const_bv(#y)
+; (bvshl #x #y) --> (concat (extract #x (size(#x) - 1 - to_unsigned_int(#y)) 0) (bvconst(to_unsigned_int(#y), 0)))
+;
+; (declare shl_by_const
+; (! n mpz
+; (! x (term (BitVec n))
+; (! y bv
+; (! o (term (BitVec n))
+; (! n1 mpz
+; (! n2 mpz
+; (! r bv
+; (! u (th_holds (= _ o (bvshl x (a_bv y))))
+; (! u (^ (mpz_sub (mpz_sub n 1) (bv_const_to_size y)) n1)
+; (! u (^ (bv_is_constant_zero r) true)
+; (th_holds (= _ o (concat (extract n2 n1 0 _ x) (a_bv r)))))))))))))
+
+
+(declare lshr_by_const_zero (! n48 mpz (! x (term (BitVec n48)) (! XXXv3 bv (! o (term (BitVec n48)) (! u (^ (bv_is_constant_zero XXXv3) true) (! u (th_holds (= _ o (bvlshr _ x (a_bv _ XXXv3)))) (th_holds (= _ o x)))))))))
+(declare lshr_by_const_more_than_len (! n63 mpz (! y bv (! x (term (BitVec n63)) (! XXXv4 bv (! o (term (BitVec n63)) (! u (^ (mpz_lte (n63) (bv_const_to_size y)) true) (! u (^ (bv_is_constant_zero XXXv4) true) (! u (th_holds (= _ o (bvlshr _ x (a_bv _ y)))) (th_holds (= _ o (a_bv _ XXXv4))))))))))))
+(declare bitwise_idemp_and (! n68 mpz (! x (term (BitVec n68)) (! o (term (BitVec n68)) (! u (th_holds (= _ o (bvand n68 x x))) (th_holds (= _ o x)))))))
+(declare bitwise_idemp_or (! n73 mpz (! x (term (BitVec n73)) (! o (term (BitVec n73)) (! u (th_holds (= _ o (bvor _ x x))) (th_holds (= _ o x)))))))
+(declare and_zero_r (! n88 mpz (! XXXv6 bv (! x (term (BitVec n88)) (! XXXv5 bv (! o (term (BitVec n88)) (! u (^ (bv_is_constant_zero XXXv6) true) (! u (^ (bv_is_constant_zero XXXv5) true) (! u (th_holds (= _ o (bvand n88 x (a_bv _ XXXv5)))) (th_holds (= _ o (a_bv _ XXXv6))))))))))))
+(declare and_zero_l (! n103 mpz (! XXXv8 bv (! x (term (BitVec n103)) (! XXXv7 bv (! o (term (BitVec n103)) (! u (^ (bv_is_constant_zero XXXv8) true) (! u (^ (bv_is_constant_zero XXXv7) true) (! u (th_holds (= _ o (bvand n103 (a_bv _ XXXv7) x))) (th_holds (= _ o (a_bv _ XXXv8))))))))))))
+(declare bitwise_not_and_r (! n114 mpz (! x (term (BitVec n114)) (! XXXv9 bv (! o (term (BitVec n114)) (! u (^ (bv_is_constant_zero XXXv9) true) (! u (th_holds (= _ o (bvand n114 x (bvnot _ x)))) (th_holds (= _ o (a_bv _ XXXv9))))))))))
+(declare bitwise_not_and_l (! n125 mpz (! x (term (BitVec n125)) (! XXXv10 bv (! o (term (BitVec n125)) (! u (^ (bv_is_constant_zero XXXv10) true) (! u (th_holds (= _ o (bvand n125 (bvnot _ x) x))) (th_holds (= _ o (a_bv _ XXXv10))))))))))
+(declare not_idemp (! n130 mpz (! x (term (BitVec n130)) (! o (term (BitVec n130)) (! u (th_holds (= _ o (bvnot _ (bvnot _ x)))) (th_holds (= _ o x)))))))
+(declare lt_self_ult (! n135 mpz (! x (term (BitVec n135)) (! o formula (! u (th_holds (iff o (bvult _ x x))) (th_holds (iff o (false))))))))
+(declare lt_self_slt (! n139 mpz (! x (term (BitVec n139)) (! o formula (! u (th_holds (iff o (bvslt _ x x))) (th_holds (iff o (false))))))))
+(declare lte_self_ule (! n143 mpz (! x (term (BitVec n143)) (! o formula (! u (th_holds (iff o (bvule _ x x))) (th_holds (iff o (true))))))))
+(declare lte_self_sle (! n147 mpz (! x (term (BitVec n147)) (! o formula (! u (th_holds (iff o (bvsle _ x x))) (th_holds (iff o (true))))))))
+(declare ugt_eliminate (! n155 mpz (! y (term (BitVec n155)) (! x (term (BitVec n155)) (! o formula (! u (th_holds (iff o (bvugt _ x y))) (th_holds (iff o (bvult _ y x)))))))))
+(declare uge_eliminate (! n163 mpz (! y (term (BitVec n163)) (! x (term (BitVec n163)) (! o formula (! u (th_holds (iff o (bvuge _ x y))) (th_holds (iff o (bvule _ y x)))))))))
+(declare sgt_eliminate (! n171 mpz (! y (term (BitVec n171)) (! x (term (BitVec n171)) (! o formula (! u (th_holds (iff o (bvsgt _ x y))) (th_holds (iff o (bvslt _ y x)))))))))
+(declare sge_eliminate (! n179 mpz (! y (term (BitVec n179)) (! x (term (BitVec n179)) (! o formula (! u (th_holds (iff o (bvsge _ x y))) (th_holds (iff o (bvsle _ y x)))))))))
diff --git a/src/Makefile.am b/src/Makefile.am
index e44bd920c..991ef5bf3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -94,6 +94,10 @@ libcvc4_la_SOURCES = \
proof/proof_output_channel.h \
proof/proof_utils.cpp \
proof/proof_utils.h \
+ proof/rewrite_proof.cpp \
+ proof/rewrite_proof.h \
+ proof/rewrite_proof_dispatcher.cpp \
+ proof/rewrite_proof_dispatcher.h \
proof/sat_proof.h \
proof/sat_proof_implementation.h \
proof/simplify_boolean_node.cpp \
diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am
index df4603a9a..46a9155d3 100644
--- a/src/compat/Makefile.am
+++ b/src/compat/Makefile.am
@@ -26,7 +26,7 @@ libcvc4compat_la_LDFLAGS = \
libcvc4compat_la_LIBADD = \
@builddir@/../libcvc4.la \
- @builddir@/../parser/libcvc4parser.la \
+ @builddir@/../parser/libcvc4parser.la
@builddir@/../lib/libreplacements.la
libcvc4compat_la_SOURCES = \
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 8db3d664c..1036e7169 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -7,7 +7,6 @@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN)
noinst_LTLIBRARIES = libreplacements.la
libreplacements_la_SOURCES =
-
libreplacements_la_LIBADD = \
$(LTLIBOBJS)
diff --git a/src/main/Makefile.am b/src/main/Makefile.am
index 372e817f6..00c77ffc0 100644
--- a/src/main/Makefile.am
+++ b/src/main/Makefile.am
@@ -30,9 +30,8 @@ pcvc4_LDADD = \
libmain.a \
@builddir@/../parser/libcvc4parser.la \
@builddir@/../libcvc4.la \
- $(READLINE_LIBS) \
+ $(READLINE_LIBS)
@builddir@/../lib/libreplacements.la
-
pcvc4_CPPFLAGS = $(AM_CPPFLAGS) $(BOOST_CPPFLAGS) -DPORTFOLIO_BUILD
pcvc4_LDADD += $(BOOST_THREAD_LIBS)
pcvc4_LDADD += $(BOOST_THREAD_LDFLAGS)
@@ -52,7 +51,7 @@ cvc4_LDADD = \
libmain.a \
@builddir@/../parser/libcvc4parser.la \
@builddir@/../libcvc4.la \
- $(READLINE_LIBS) \
+ $(READLINE_LIBS)
@builddir@/../lib/libreplacements.la
BUILT_SOURCES = \
diff --git a/src/parser/Makefile.am b/src/parser/Makefile.am
index ca10de684..b16028f87 100644
--- a/src/parser/Makefile.am
+++ b/src/parser/Makefile.am
@@ -29,7 +29,7 @@ libcvc4parser_la_LIBADD = \
@builddir@/smt2/libparsersmt2.la \
@builddir@/tptp/libparsertptp.la \
@builddir@/cvc/libparsercvc.la \
- @builddir@/../libcvc4.la \
+ @builddir@/../libcvc4.la
@builddir@/../lib/libreplacements.la
libcvc4parser_la_SOURCES = \
diff --git a/src/parser/cvc/Cvc.g b/src/parser/cvc/Cvc.g
index b5bad6a2d..477cd940d 100644
--- a/src/parser/cvc/Cvc.g
+++ b/src/parser/cvc/Cvc.g
@@ -522,6 +522,8 @@ Expr addNots(ExprManager* em, size_t n, Expr e) {
#include "parser/parser.h"
#include "util/integer.h"
+#define _empty NULL
+
}/* @lexer::includes */
@parser::includes {
diff --git a/src/parser/smt1/Smt1.g b/src/parser/smt1/Smt1.g
index 28c54fc80..eb7e918bd 100644
--- a/src/parser/smt1/Smt1.g
+++ b/src/parser/smt1/Smt1.g
@@ -62,6 +62,8 @@ options {
#endif /* CVC4_COMPETITION_MODE && !CVC4_SMTCOMP_APPLICATION_TRACK */
#include "parser/antlr_tracing.h"
+
+#define _empty NULL
}/* @lexer::includes */
@parser::includes {
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g
index a49190825..779715ca5 100644
--- a/src/parser/smt2/Smt2.g
+++ b/src/parser/smt2/Smt2.g
@@ -63,6 +63,8 @@ options {
#include "parser/antlr_tracing.h"
+#define _empty NULL
+
}/* @lexer::includes */
@lexer::postinclude {
diff --git a/src/proof/proof_manager.cpp b/src/proof/proof_manager.cpp
index cbc7f591a..9647668a8 100644
--- a/src/proof/proof_manager.cpp
+++ b/src/proof/proof_manager.cpp
@@ -25,6 +25,7 @@
#include "proof/clause_id.h"
#include "proof/cnf_proof.h"
#include "proof/proof_utils.h"
+#include "proof/rewrite_proof_dispatcher.h"
#include "proof/sat_proof_implementation.h"
#include "proof/theory_proof.h"
#include "smt/smt_engine.h"
@@ -758,8 +759,6 @@ void LFSCProof::printPreprocessedAssertions(const NodeSet& assertions,
for (; it != end; ++it) {
// Rewrite preprocessing step if it cannot be eliminated
if (!ProofManager::currentPM()->have_input_assertion((*it).toExpr())) {
- os << "(th_let_pf _ (trust_f (iff ";
-
Expr inputAssertion;
if (((*it).isConst() && *it == NodeManager::currentNM()->mkConst<bool>(true)) ||
@@ -802,12 +801,20 @@ void LFSCProof::printPreprocessedAssertions(const NodeSet& assertions,
<< ", AKA "
<< ProofManager::currentPM()->getInputFormulaName(inputAssertion)
<< std::endl;
+ os << "(th_let_pf _ ";
+ RewriteProof rp;
+ if ((*it).getKind() == kind::NOT && (*it)[0] == NodeManager::currentNM()->mkConst<bool>(false)) {
+ os << "t_eq_n_f ";
+ } else if (theory::Rewriter::rewriteWithProof(inputAssertion, &rp) == *it) {
+ printProof(ProofManager::currentPM()->getTheoryProofEngine(), rp, os, globalLetMap);
+ } else {
+ os << "(trust_f (iff ";
+ ProofManager::currentPM()->getTheoryProofEngine()->printTheoryTerm(inputAssertion, os, globalLetMap);
+ os << " ";
+ ProofManager::currentPM()->getTheoryProofEngine()->printTheoryTerm((*it).toExpr(), os, globalLetMap);
+ os << ")) ";
+ }
- ProofManager::currentPM()->getTheoryProofEngine()->printTheoryTerm(inputAssertion, os, globalLetMap);
- os << " ";
- ProofManager::currentPM()->getTheoryProofEngine()->printTheoryTerm((*it).toExpr(), os, globalLetMap);
-
- os << "))";
os << "(\\ "<< ProofManager::getPreprocessedAssertionName(*it, "") << "\n";
paren << "))";
diff --git a/src/proof/proof_manager.h b/src/proof/proof_manager.h
index 31638e8ee..e105a849c 100644
--- a/src/proof/proof_manager.h
+++ b/src/proof/proof_manager.h
@@ -31,7 +31,7 @@
#include "theory/logic_info.h"
#include "theory/substitutions.h"
#include "util/proof.h"
-
+#include "proof/rewrite_proof.h"
namespace CVC4 {
@@ -68,6 +68,7 @@ class UFProof;
class ArithProof;
class ArrayProof;
class BitVectorProof;
+class RewriteProof;
template <class Solver> class LFSCSatProof;
typedef LFSCSatProof< CVC4::Minisat::Solver> LFSCCoreSatProof;
diff --git a/src/proof/rewrite_proof.cpp b/src/proof/rewrite_proof.cpp
new file mode 100644
index 000000000..15e79d1e0
--- /dev/null
+++ b/src/proof/rewrite_proof.cpp
@@ -0,0 +1,157 @@
+#include "proof/rewrite_proof.h"
+
+#include "proof/rewrite_proof_dispatcher.h"
+#include "proof_manager.h"
+#include "theory/rewriter.h"
+
+namespace CVC4 {
+
+Rewrite::~Rewrite() {
+ for (size_t i = 0; i < d_subproofs.size(); i++) {
+ delete d_subproofs[i];
+ }
+}
+
+void Rewrite::deleteUncachedChildren() {
+ for (size_t i = 0; i < d_children.size(); i++) {
+ if (d_children[i] != NULL) {
+ d_children[i]->deleteUncachedChildren();
+ if (!d_children[i]->d_cached_version_used) {
+ delete d_children[i];
+ d_children[i] = NULL;
+ }
+ }
+ }
+}
+
+void Rewrite::print(int tab) const {
+ for (int j = 0; j < tab; j++)
+ std::cout << " ";
+ std::cout << d_tag << " > " << d_original << " < " << std::endl;
+
+ for (size_t i = 0; i < d_children.size(); i++) {
+ d_children[i]->print(tab + 1);
+ std::cout << std::endl;
+ }
+}
+
+RewriteProof::~RewriteProof() {
+ for (ProofCacheIterator iter = preRewriteCache.begin();
+ iter != preRewriteCache.end(); ++iter) {
+ if (!iter->second->d_cached_version_used) {
+ preRewriteCache[iter->first] = NULL;
+ }
+ }
+ /*
+ for (ProofCacheIterator iter = postRewriteCache.begin();
+ iter != postRewriteCache.end(); ++iter) {
+ if (!iter->second->d_cached_version_used) {
+ postRewriteCache[iter->first] = NULL;
+ }
+ }*/
+
+ for (size_t i = 0; i < d_rewrites.size(); i++) {
+ d_rewrites[i]->deleteUncachedChildren();
+ if (!d_rewrites[i]->d_cached_version_used) {
+ delete d_rewrites[i];
+ }
+ }
+
+ for (ProofCacheIterator iter = preRewriteCache.begin();
+ iter != preRewriteCache.end(); ++iter) {
+ if (iter->second != NULL) {
+ delete iter->second;
+ }
+ }
+ /*
+ for (ProofCacheIterator iter = postRewriteCache.begin();
+ iter != postRewriteCache.end(); ++iter) {
+ if (iter->second != NULL) {
+ delete iter->second;
+ }
+ }*/
+}
+
+void RewriteProof::attachSubproofToParent() {
+ Rewrite *topRewrite = d_rewrites.back();
+
+ // Simplify proof
+ if (topRewrite->d_tag == ORIGINAL_OP) {
+ bool allChildrenRefl = true;
+ for (size_t i = 0; i < topRewrite->d_children.size(); i++) {
+ if (topRewrite->d_children[i]->d_tag != ORIGINAL_OP) {
+ allChildrenRefl = false;
+ break;
+ }
+ }
+ if (allChildrenRefl) {
+ topRewrite->d_children.clear();
+ }
+ }
+ d_rewrites[d_rewrites.size() - 2]->d_children.push_back(d_rewrites.back());
+ d_rewrites.pop_back();
+}
+
+Rewrite *RewriteProof::getRewrite() const {
+ Assert(d_rewrites.size() == 1);
+ return d_rewrites[0];
+}
+
+void RewriteProof::registerRewrite(const int tag) {
+ Rewrite *topRewrite = d_rewrites.back();
+ d_rewrites.pop_back();
+ Rewrite *newRewrite = new Rewrite(tag, topRewrite->d_original);
+ newRewrite->d_children.push_back(topRewrite);
+ d_rewrites.push_back(newRewrite);
+}
+
+void RewriteProof::registerSwap(const unsigned swap_id1, const unsigned swap_id2) {
+ // Register swap if it does not swap head with head
+ if (swap_id1 != swap_id2) {
+ Rewrite *topRewrite = d_rewrites.back();
+ d_rewrites.pop_back();
+ Rewrite *newRewrite = new Rewrite(SWAP, topRewrite->d_original);
+ newRewrite->swap_id1 = swap_id1;
+ newRewrite->swap_id2 = swap_id2;
+ newRewrite->d_children.push_back(topRewrite);
+ d_rewrites.push_back(newRewrite);
+ }
+}
+
+void RewriteProof::replaceRewrite(Rewrite *rewrite) {
+ // XXX: make sure that this is always safe
+ delete d_rewrites.back();
+ d_rewrites.back() = rewrite;
+}
+
+Rewrite *RewriteProof::getPreRewriteCache(Node node) {
+ return NULL; //preRewriteCache[node];
+}
+
+Rewrite *RewriteProof::getPostRewriteCache(Node node) {
+ return NULL; //postRewriteCache[node];
+}
+
+void RewriteProof::setPreRewriteCache(Node node, Rewrite *rewrite) {
+ preRewriteCache[node] = rewrite;
+}
+
+void RewriteProof::setPostRewriteCache(Node node, Rewrite *rewrite) {
+ postRewriteCache[node] = rewrite;
+}
+
+void RewriteProof::printCachedProofs(TheoryProofEngine *tp, std::ostream &os,
+ std::ostream &paren,
+ ProofLetMap &globalLetMap) const {
+ for (ProofCacheIterator iter = preRewriteCache.begin();
+ iter != preRewriteCache.end(); ++iter) {
+ if (iter->second->d_cached_version_used) {
+ os << std::endl;
+ os << "(@ let" << iter->second->d_id << " ";
+ callPrintRewriteProof(false, tp, iter->second, os, globalLetMap);
+ paren << ")";
+ }
+ }
+}
+
+} /* CVC4 namespace */
diff --git a/src/proof/rewrite_proof.h b/src/proof/rewrite_proof.h
new file mode 100644
index 000000000..5701e019a
--- /dev/null
+++ b/src/proof/rewrite_proof.h
@@ -0,0 +1,86 @@
+#include "cvc4_private.h"
+
+#pragma once
+
+#include "expr/node.h"
+#include "proof/theory_proof.h"
+#include "util/proof.h"
+
+namespace CVC4 {
+
+typedef int rewrite_tag_t;
+
+// Theory independent rewrites
+enum SharedRewrites {
+ ORIGINAL_OP, // Mirror an original operator
+ TRUSTED,
+ SWAP,
+ LAST_SHARED,
+};
+
+struct Rewrite {
+ // The type of the rewrite
+ int d_tag;
+ // Node before the rewrite
+ Node d_original;
+ // Rewrite proofs for children
+ std::vector<Rewrite *> d_children;
+ // Subproofs
+ std::vector<Rewrite *> d_subproofs;
+ // Unique id to identify the rewrite
+ unsigned d_id;
+ // Stores whether the cached version of this rewrite is ever used
+ bool d_cached_version_used;
+ // XXX: refactor into seperate class
+ unsigned swap_id1, swap_id2;
+
+ Rewrite(const Node original)
+ : d_tag(0), d_original(original), d_cached_version_used(false) {
+ d_id = ProofLetCount::newId();
+ }
+ Rewrite(const rewrite_tag_t tag, const Node original)
+ : d_tag(tag), d_original(original), d_cached_version_used(false) {
+ d_id = ProofLetCount::newId();
+ }
+ ~Rewrite();
+
+ void deleteUncachedChildren();
+ void print(int tab) const;
+ bool isLeaf() const { return d_children.size() == 0; }
+};
+
+typedef __gnu_cxx::hash_map<Node, Rewrite *, NodeHashFunction> ProofCache;
+typedef __gnu_cxx::hash_map<Node, Rewrite *, NodeHashFunction>::const_iterator
+ ProofCacheIterator;
+
+class RewriteProof {
+private:
+ std::vector<Rewrite *> d_rewrites;
+ ProofCache preRewriteCache;
+ ProofCache postRewriteCache;
+
+public:
+ RewriteProof() {}
+ ~RewriteProof();
+
+ void addRewrite(Rewrite *rewrite) { d_rewrites.push_back(rewrite); }
+
+ void attachSubproofToParent();
+
+ Rewrite *getRewrite() const;
+ Rewrite *getTopRewrite() const { return d_rewrites.back(); };
+
+ void registerRewrite(const int tag);
+ void registerSwap(const unsigned swap_id1, const unsigned swap_id2);
+ void replaceRewrite(Rewrite *rewrite);
+
+ Rewrite *getPreRewriteCache(Node node);
+ Rewrite *getPostRewriteCache(Node node);
+ void setPreRewriteCache(Node node, Rewrite *rewrite);
+ void setPostRewriteCache(Node node, Rewrite *rewrite);
+
+ void printCachedProofs(TheoryProofEngine *tp, std::ostream &os,
+ std::ostream &paren, ProofLetMap &globalLetMap) const;
+};
+
+} /* CVC4 namespace */
diff --git a/src/proof/rewrite_proof_dispatcher.cpp b/src/proof/rewrite_proof_dispatcher.cpp
new file mode 100644
index 000000000..3b01719d2
--- /dev/null
+++ b/src/proof/rewrite_proof_dispatcher.cpp
@@ -0,0 +1,83 @@
+// TODO: decide whether this should be part of rewriter_tables
+#include "proof/rewrite_proof_dispatcher.h"
+
+#include "theory/arrays/theory_arrays_rewriter.h"
+#include "theory/booleans/theory_bool_rewriter.h"
+
+namespace CVC4 {
+
+void printProof(TheoryProofEngine *tp, const RewriteProof &rp, std::ostream &os,
+ ProofLetMap &globalLetMap) {
+ std::ostringstream paren;
+ rp.printCachedProofs(tp, os, paren, globalLetMap);
+ os << std::endl;
+ callPrintRewriteProof(true, tp, rp.getRewrite(), os, globalLetMap);
+ os << paren.str();
+}
+
+theory::RewriteResponse callPreRewriteWithProof(theory::TheoryId theory,
+ TNode node,
+ RewriteProof *proof) {
+ Assert(proof);
+ switch (theory) {
+ case theory::THEORY_ARRAY:
+ return theory::arrays::TheoryArraysRewriter::preRewriteEx<true>(node,
+ proof);
+
+ case theory::THEORY_BOOL:
+ return theory::booleans::TheoryBoolRewriter::preRewriteEx<true>(node,
+ proof);
+
+ default:
+ Unreachable();
+ }
+}
+
+theory::RewriteResponse callPostRewriteWithProof(theory::TheoryId theory,
+ TNode node,
+ RewriteProof *proof) {
+ Assert(proof);
+ switch (theory) {
+ case theory::THEORY_ARRAY:
+ return theory::arrays::TheoryArraysRewriter::postRewriteEx<true>(node,
+ proof);
+
+ case theory::THEORY_BOOL:
+ return theory::booleans::TheoryBoolRewriter::postRewriteEx<true>(node,
+ proof);
+
+ default:
+ Unreachable();
+ }
+}
+
+void callPrintRewriteProof(bool use_cache, TheoryProofEngine *tp,
+ const Rewrite *rewrite, std::ostream &os,
+ ProofLetMap &globalLetMap) {
+ if (use_cache && rewrite->d_cached_version_used) {
+ os << "let" << rewrite->d_id;
+ return;
+ }
+
+ switch (theory::theoryOf(rewrite->d_original)) {
+ case theory::THEORY_ARRAY:
+ theory::arrays::TheoryArraysRewriter::printRewriteProof(
+ use_cache, tp, rewrite, os, globalLetMap);
+ break;
+
+ case theory::THEORY_BOOL:
+ theory::booleans::TheoryBoolRewriter::printRewriteProof(
+ use_cache, tp, rewrite, os, globalLetMap);
+ break;
+
+ default:
+ for (size_t i = 0; i < rewrite->d_children.size(); i++) {
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[i], os,
+ globalLetMap);
+ std::cout << std::endl;
+ }
+ break;
+ }
+}
+
+} /* CVC4 namespace */
diff --git a/src/proof/rewrite_proof_dispatcher.h b/src/proof/rewrite_proof_dispatcher.h
new file mode 100644
index 000000000..8c1202c16
--- /dev/null
+++ b/src/proof/rewrite_proof_dispatcher.h
@@ -0,0 +1,28 @@
+// TODO: decide whether this should be part of rewriter_tables
+#include "cvc4_private.h"
+
+#pragma once
+
+#include "expr/node.h"
+#include "proof/theory_proof.h"
+#include "theory/rewriter.h"
+#include "util/proof.h"
+
+namespace CVC4 {
+
+void printProof(TheoryProofEngine *tp, const RewriteProof &rp, std::ostream &os,
+ ProofLetMap &globalLetMap);
+
+theory::RewriteResponse callPreRewriteWithProof(theory::TheoryId theory,
+ TNode node,
+ RewriteProof *proof);
+
+theory::RewriteResponse callPostRewriteWithProof(theory::TheoryId theory,
+ TNode node,
+ RewriteProof *proof);
+
+void callPrintRewriteProof(bool use_cache, TheoryProofEngine *tp,
+ const Rewrite *rewrite, std::ostream &os,
+ ProofLetMap &globalLetMap);
+
+} /* CVC4 namespace */
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index 31b62f25a..bdffad056 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -2861,6 +2861,8 @@ bool SmtEnginePrivate::nonClausalSimplify() {
Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): "
<< "asserting to propagator" << endl;
for (unsigned i = 0; i < d_assertions.size(); ++ i) {
+ //std::cout << Rewriter::rewrite(d_assertions[i]) << std::endl;
+ //std::cout << d_assertions[i] << std::endl;
Assert(Rewriter::rewrite(d_assertions[i]) == d_assertions[i]);
// Don't reprocess substitutions
if (d_substitutionsIndex > 0 && i == d_substitutionsIndex) {
diff --git a/src/theory/arrays/theory_arrays_rewriter.cpp b/src/theory/arrays/theory_arrays_rewriter.cpp
index f1cf1d320..8a17a62eb 100644
--- a/src/theory/arrays/theory_arrays_rewriter.cpp
+++ b/src/theory/arrays/theory_arrays_rewriter.cpp
@@ -17,11 +17,80 @@
#include "expr/attribute.h"
#include "theory/arrays/theory_arrays_rewriter.h"
+#include "proof/rewrite_proof_dispatcher.h"
namespace CVC4 {
namespace theory {
namespace arrays {
+void TheoryArraysRewriter::printRewriteProof(bool use_cache,
+ TheoryProofEngine* tp,
+ const Rewrite* rewrite,
+ std::ostream& os,
+ ProofLetMap& globalLetMap) {
+ if (rewrite->d_tag == ORIGINAL_OP && rewrite->d_children.size() == 0) {
+ switch (rewrite->d_original.getKind()) {
+ case kind::EQUAL:
+ os << "(iff_symm ";
+ tp->printTheoryTerm(rewrite->d_original.toExpr(), os, globalLetMap);
+ os << ")";
+ break;
+ default:
+ os << "(refl _ ";
+ tp->printTheoryTerm(rewrite->d_original.toExpr(), os, globalLetMap);
+ os << ")";
+ break;
+ }
+ } else if (rewrite->d_tag == EQ) {
+ os << "(iff_true _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ORIGINAL_OP) {
+ switch (rewrite->d_original.getKind()) {
+ case kind::EQUAL:
+ os << "(iff_intro _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << " ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[1], os, globalLetMap);
+ os << ")";
+ break;
+ case kind::SELECT:
+ os << "(cong _ _ _ _ _ _ (cong _ _ _ _ _ _ ";
+ os << "(refl _ (read ";
+ tp->printSort(ArrayType(rewrite->d_original.toExpr()[0].getType()).getIndexType(), os);
+ os << " ";
+ tp->printSort(ArrayType(rewrite->d_original.toExpr()[0].getType()).getConstituentType(), os);
+ os << ")) ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << ") ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[1], os, globalLetMap);
+ os << ")";
+ break;
+ default:
+ std::cout << "ERROR!" << rewrite->d_original.getKind() << std::endl;
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ Unreachable();
+ }
+ } else if (rewrite->d_tag == WOR) {
+ os << "(wor _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == WOW) {
+ os << "(wow _ _ _ _ _ _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << " ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[1], os, globalLetMap);
+ os << " ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[2], os, globalLetMap);
+ os << " ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[3], os, globalLetMap);
+ os << ")";
+ } else {
+ std::cout << "ERROR" << rewrite->d_tag << std::endl;
+ Unreachable();
+ }
+}
+
namespace attr {
struct ArrayConstantMostFrequentValueTag { };
struct ArrayConstantMostFrequentValueCountTag { };
diff --git a/src/theory/arrays/theory_arrays_rewriter.h b/src/theory/arrays/theory_arrays_rewriter.h
index e63c224a0..ef4e49def 100644
--- a/src/theory/arrays/theory_arrays_rewriter.h
+++ b/src/theory/arrays/theory_arrays_rewriter.h
@@ -40,7 +40,14 @@ class TheoryArraysRewriter {
static Node normalizeConstant(TNode node) {
return normalizeConstant(node, node[1].getType().getCardinality());
}
+
public:
+ enum ArraysRewrites {
+ WOR = LAST_SHARED,
+ WOW,
+ EQ
+ };
+
//this function is called by printers when using the option "--model-u-dt-enum"
static Node normalizeConstant(TNode node, Cardinality indexCard) {
TNode store = node[0];
@@ -228,7 +235,13 @@ public:
public:
- static RewriteResponse postRewrite(TNode node) {
+ static inline RewriteResponse postRewrite(TNode node) {
+ return postRewriteEx<false>(node, NULL);
+ }
+
+ template<bool Proof>
+ static RewriteResponse postRewriteEx(TNode node, RewriteProof* proof) {
+ Assert(!Proof || proof != NULL);
Trace("arrays-postrewrite") << "Arrays::postRewrite start " << node << std::endl;
switch (node.getKind()) {
case kind::SELECT: {
@@ -281,6 +294,9 @@ public:
value[0] == store &&
value[1] == node[1]) {
Trace("arrays-postrewrite") << "Arrays::postRewrite returning " << store << std::endl;
+ if (Proof) {
+ proof->registerRewrite(WOR);
+ }
return RewriteResponse(REWRITE_DONE, store);
}
TNode index = node[1];
@@ -380,6 +396,9 @@ public:
case kind::EQUAL:{
if(node[0] == node[1]) {
Trace("arrays-postrewrite") << "Arrays::postRewrite returning true" << std::endl;
+ if (Proof) {
+ proof->registerRewrite(EQ);
+ }
return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(true));
}
else if (node[0].isConst() && node[1].isConst()) {
@@ -401,6 +420,12 @@ public:
}
static inline RewriteResponse preRewrite(TNode node) {
+ return preRewriteEx<false>(node, NULL);
+ }
+
+ template<bool Proof>
+ static inline RewriteResponse preRewriteEx(TNode node, RewriteProof* proof) {
+ Assert(!Proof || proof != NULL);
Trace("arrays-prerewrite") << "Arrays::preRewrite start " << node << std::endl;
switch (node.getKind()) {
case kind::SELECT: {
@@ -453,6 +478,9 @@ public:
value[0] == store &&
value[1] == node[1]) {
Trace("arrays-prerewrite") << "Arrays::preRewrite returning " << store << std::endl;
+ if (Proof) {
+ proof->registerRewrite(WOR);
+ }
return RewriteResponse(REWRITE_AGAIN, store);
}
if (store.getKind() == kind::STORE) {
@@ -477,6 +505,9 @@ public:
// store(store(a,i,v),i,w) = store(a,i,w)
Node newNode = nm->mkNode(kind::STORE, store[0], index, value);
Trace("arrays-prerewrite") << "Arrays::preRewrite returning " << newNode << std::endl;
+ if (Proof) {
+ proof->registerRewrite(WOW);
+ }
return RewriteResponse(REWRITE_DONE, newNode);
}
}
@@ -485,6 +516,9 @@ public:
case kind::EQUAL:{
if(node[0] == node[1]) {
Trace("arrays-prerewrite") << "Arrays::preRewrite returning true" << std::endl;
+ if (Proof) {
+ proof->registerRewrite(EQ);
+ }
return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(true));
}
break;
@@ -497,6 +531,12 @@ public:
return RewriteResponse(REWRITE_DONE, node);
}
+ static void printRewriteProof(bool use_cache,
+ TheoryProofEngine* tp,
+ const Rewrite* rewrite,
+ std::ostream& os,
+ ProofLetMap& globalLetMap);
+
static inline void init() {}
static inline void shutdown() {}
diff --git a/src/theory/booleans/bool.h b/src/theory/booleans/bool.h
new file mode 100644
index 000000000..8654a63d8
--- /dev/null
+++ b/src/theory/booleans/bool.h
@@ -0,0 +1,1085 @@
+
+#include "cvc4_private.h"
+
+#pragma once
+
+#include "proof/rewrite_proof_dispatcher.h"
+#include "theory/rewriter.h"
+
+namespace CVC4 {
+namespace theory {
+
+enum bool_Rewrites {
+ NOT_TRUE = LAST_SHARED,
+ NOT_FALSE,
+ NOT_NOT,
+ OR_TRUE,
+ OR_FALSE,
+ OR_DUP,
+ AND_FALSE,
+ AND_TRUE,
+ AND_DUP,
+ FALSE_IMPLIES,
+ IMPLIES_TRUE,
+ TRUE_IMPLIES_FALSE,
+ TRUE_IMPLIES,
+ IMPLIES_FALSE,
+ TRUE_EQ,
+ FALSE_EQ,
+ X_EQ_X,
+ N_X_EQ_X,
+ EQ_EQ_CONSTS,
+ EQ_NEQ_CONSTS_CARD2,
+ EQ_NEQ_CONSTS,
+ TRUE_XOR,
+ FALSE_XOR,
+ X_XOR_X,
+ N_X_XOR_X,
+ ITE_TRUE,
+ ITE_FALSE,
+ ITE_X_TRUE_FALSE,
+ ITE_C_FALSE_TRUE,
+ ITE_C_X_X,
+ ITE_C_X_N_X,
+ ITE_C_N_X_X,
+ ITE_X_X_Y,
+ ITE_N_X_X_Y,
+ ITE_X_N_X_Y,
+ ITE_X_Y_X,
+ ITE_N_X_Y_X,
+ ITE_X_Y_N_X,
+ ITE_C_ITE_C_X_Y_Z,
+ ITE_C_ITE_N_C_X_Y_Z,
+ ITE_N_C_ITE_C_X_Y_Z,
+ ITE_C_Z_ITE_C_X_Y,
+ ITE_C_Z_ITE_N_C_X_Y,
+ ITE_N_C_Z_ITE_C_X_Y
+};
+
+template <bool Proof>
+inline RewriteResponse rewrite1(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite2(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if ((node).getKind() == kind::ITE) {
+ if (((node[0]).getKind() == kind::CONST_BOOLEAN) && (true)) {
+ if (node[0] == nm->mkConst(true)) {
+ if (Proof) {
+ proof->registerRewrite(ITE_TRUE);
+ };
+ Node rewritten_node = node[1];
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (node[0] == nm->mkConst(false)) {
+ if (Proof) {
+ proof->registerRewrite(ITE_FALSE);
+ };
+ Node rewritten_node = node[2];
+ return rewrite1<Proof>(rewritten_node, proof);
+ }
+ };
+ if (((node[1]).getKind() == kind::CONST_BOOLEAN) &&
+ ((node[2]).getKind() == kind::CONST_BOOLEAN) && (true)) {
+ if ((node[1] == nm->mkConst(true)) && (node[2] == nm->mkConst(false))) {
+ if (Proof) {
+ proof->registerRewrite(ITE_X_TRUE_FALSE);
+ };
+ Node rewritten_node = node[0];
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if ((node[1] == nm->mkConst(false)) && (node[2] == nm->mkConst(true))) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_FALSE_TRUE);
+ };
+ Node rewritten_node = nm->mkNode(kind::NOT, node[0]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ }
+ };
+ if ((true) && (node[1] == node[2])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_X_X);
+ };
+ Node rewritten_node = node[1];
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[2]).getKind() == kind::NOT) && (true) &&
+ (node[1] == node[2][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_X_N_X);
+ };
+ Node rewritten_node = nm->mkNode(kind::EQUAL, node[0], node[1]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[1]).getKind() == kind::NOT) && (true) &&
+ (node[1][0] == node[2])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_N_X_X);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::EQUAL, node[0], nm->mkNode(kind::NOT, node[1][0]));
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if ((!((node[0]).isConst())) && (node[0] == node[1])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_X_X_Y);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], nm->mkConst(true), node[2]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[0]).getKind() == kind::NOT) && (!((node[0][0]).isConst())) &&
+ (node[0][0] == node[1])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_N_X_X_Y);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, nm->mkNode(kind::NOT, node[0][0]),
+ nm->mkConst(false), node[2]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[1]).getKind() == kind::NOT) && (!((node[0]).isConst())) &&
+ (node[0] == node[1][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_X_N_X_Y);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], nm->mkConst(false), node[2]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if ((!((node[0]).isConst())) && (node[0] == node[2])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_X_Y_X);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], node[1], nm->mkConst(false));
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[0]).getKind() == kind::NOT) && (!((node[0][0]).isConst())) &&
+ (node[0][0] == node[2])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_N_X_Y_X);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, nm->mkNode(kind::NOT, node[0][0]), node[1],
+ nm->mkConst(true));
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[2]).getKind() == kind::NOT) && (!((node[0]).isConst())) &&
+ (node[0] == node[2][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_X_Y_N_X);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], node[1], nm->mkConst(true));
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if ((node[1]).getKind() == kind::ITE) {
+ if ((true) && (node[0] == node[1][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_ITE_C_X_Y_Z);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], node[1][1], node[2]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[1][0]).getKind() == kind::NOT) && (true) &&
+ (node[0] == node[1][0][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_ITE_N_C_X_Y_Z);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], node[1][2], node[2]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ }
+ };
+ if (((node[0]).getKind() == kind::NOT) &&
+ ((node[1]).getKind() == kind::ITE) && (true) &&
+ (node[0][0] == node[1][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_N_C_ITE_C_X_Y_Z);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0][0], node[1][2], node[2]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if ((node[2]).getKind() == kind::ITE) {
+ if ((true) && (node[0] == node[2][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_Z_ITE_C_X_Y);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], node[1], node[2][2]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ };
+ if (((node[2][0]).getKind() == kind::NOT) && (true) &&
+ (node[0] == node[2][0][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_C_Z_ITE_N_C_X_Y);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0], node[1], node[2][1]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ }
+ };
+ if (((node[0]).getKind() == kind::NOT) &&
+ ((node[2]).getKind() == kind::ITE) && (true) &&
+ (node[0][0] == node[2][0])) {
+ if (Proof) {
+ proof->registerRewrite(ITE_N_C_Z_ITE_C_X_Y);
+ };
+ Node rewritten_node =
+ nm->mkNode(kind::ITE, node[0][0], node[1], node[2][1]);
+ return rewrite1<Proof>(rewritten_node, proof);
+ }
+ };
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite3(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite4(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::XOR) && (true)) {
+ for (unsigned in_tmp352 = 0, in_tmp352_end = node.getNumChildren();
+ in_tmp352 < in_tmp352_end; in_tmp352++) {
+ TNode n_tmp352 = node[in_tmp352];
+
+ for (unsigned in_tmp351 = 0, in_tmp351_end = node.getNumChildren();
+ in_tmp351 < in_tmp351_end; in_tmp351++) {
+ TNode n_tmp351 = node[in_tmp351];
+ if (!(in_tmp352 == in_tmp351)) {
+ if (n_tmp351 == n_tmp352) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(X_XOR_X);
+ };
+ Node rewritten_node = nm->mkConst(false);
+ return rewrite3<Proof>(rewritten_node, proof);
+ };
+ if (((n_tmp351).getKind() == kind::NOT) &&
+ (n_tmp351[0] == n_tmp352)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(N_X_XOR_X);
+ };
+ Node rewritten_node = nm->mkConst(true);
+ return rewrite3<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ }
+ };
+ return rewrite2<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite5(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite6(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::XOR) && (true)) {
+ for (unsigned in_tmp348 = 0, in_tmp348_end = node.getNumChildren();
+ in_tmp348 < in_tmp348_end; in_tmp348++) {
+ TNode n_tmp348 = node[in_tmp348];
+
+ for (unsigned in_tmp347 = 0, in_tmp347_end = node.getNumChildren();
+ in_tmp347 < in_tmp347_end; in_tmp347++) {
+ TNode n_tmp347 = node[in_tmp347];
+ if ((!(in_tmp348 == in_tmp347)) &&
+ ((n_tmp347).getKind() == kind::CONST_BOOLEAN)) {
+ if (n_tmp347 == nm->mkConst(true)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(TRUE_XOR);
+ };
+ Node rewritten_node = nm->mkNode(kind::NOT, n_tmp348);
+ return rewrite5<Proof>(rewritten_node, proof);
+ };
+ if (n_tmp347 == nm->mkConst(false)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(FALSE_XOR);
+ };
+ Node rewritten_node = n_tmp348;
+ return rewrite5<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ }
+ };
+ return rewrite4<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite7(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN_FULL, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite8(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if ((node).getKind() == kind::EQUAL) {
+ for (unsigned in_tmp342 = 0, in_tmp342_end = node.getNumChildren();
+ in_tmp342 < in_tmp342_end; in_tmp342++) {
+ TNode n_tmp342 = node[in_tmp342];
+ if ((n_tmp342).getKind() == kind::EQUAL) {
+ for (unsigned in_tmp341 = 0, in_tmp341_end = node.getNumChildren();
+ in_tmp341 < in_tmp341_end; in_tmp341++) {
+ TNode n_tmp341 = node[in_tmp341];
+ if ((!(in_tmp342 == in_tmp341)) &&
+ ((n_tmp341).getKind() == kind::EQUAL)) {
+ for (unsigned in_tmp346 = 0,
+ in_tmp346_end = n_tmp342.getNumChildren();
+ in_tmp346 < in_tmp346_end; in_tmp346++) {
+ TNode n_tmp346 = n_tmp342[in_tmp346];
+
+ for (unsigned in_tmp345 = 0,
+ in_tmp345_end = n_tmp342.getNumChildren();
+ in_tmp345 < in_tmp345_end; in_tmp345++) {
+ TNode n_tmp345 = n_tmp342[in_tmp345];
+ if (!(in_tmp346 == in_tmp345)) {
+ for (unsigned in_tmp344 = 0,
+ in_tmp344_end = n_tmp341.getNumChildren();
+ in_tmp344 < in_tmp344_end; in_tmp344++) {
+ TNode n_tmp344 = n_tmp341[in_tmp344];
+ if (n_tmp344 == n_tmp346) {
+ for (unsigned in_tmp343 = 0,
+ in_tmp343_end = n_tmp341.getNumChildren();
+ in_tmp343 < in_tmp343_end; in_tmp343++) {
+ TNode n_tmp343 = n_tmp341[in_tmp343];
+ if ((!(in_tmp344 == in_tmp343)) &&
+ ((((n_tmp343).isConst()) &&
+ ((n_tmp345).isConst())) &&
+ ((n_tmp343 != n_tmp345)))) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(EQ_NEQ_CONSTS);
+ };
+ Node rewritten_node = nm->mkNode(
+ kind::AND,
+ nm->mkNode(
+ kind::NOT,
+ nm->mkNode(kind::EQUAL, n_tmp343, n_tmp344)),
+ nm->mkNode(
+ kind::NOT,
+ nm->mkNode(kind::EQUAL, n_tmp345, n_tmp344)));
+ return rewrite7<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ return rewrite6<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite9(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite10(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if ((node).getKind() == kind::EQUAL) {
+ for (unsigned in_tmp330 = 0, in_tmp330_end = node.getNumChildren();
+ in_tmp330 < in_tmp330_end; in_tmp330++) {
+ TNode n_tmp330 = node[in_tmp330];
+ if ((n_tmp330).getKind() == kind::EQUAL) {
+ for (unsigned in_tmp329 = 0, in_tmp329_end = node.getNumChildren();
+ in_tmp329 < in_tmp329_end; in_tmp329++) {
+ TNode n_tmp329 = node[in_tmp329];
+ if ((!(in_tmp330 == in_tmp329)) &&
+ ((n_tmp329).getKind() == kind::EQUAL)) {
+ for (unsigned in_tmp334 = 0,
+ in_tmp334_end = n_tmp330.getNumChildren();
+ in_tmp334 < in_tmp334_end; in_tmp334++) {
+ TNode n_tmp334 = n_tmp330[in_tmp334];
+
+ for (unsigned in_tmp333 = 0,
+ in_tmp333_end = n_tmp330.getNumChildren();
+ in_tmp333 < in_tmp333_end; in_tmp333++) {
+ TNode n_tmp333 = n_tmp330[in_tmp333];
+ if (!(in_tmp334 == in_tmp333)) {
+ for (unsigned in_tmp332 = 0,
+ in_tmp332_end = n_tmp329.getNumChildren();
+ in_tmp332 < in_tmp332_end; in_tmp332++) {
+ TNode n_tmp332 = n_tmp329[in_tmp332];
+ if (n_tmp332 == n_tmp334) {
+ for (unsigned in_tmp331 = 0,
+ in_tmp331_end = n_tmp329.getNumChildren();
+ in_tmp331 < in_tmp331_end; in_tmp331++) {
+ TNode n_tmp331 = n_tmp329[in_tmp331];
+ if ((!(in_tmp332 == in_tmp331)) &&
+ ((n_tmp331).isConst()) && (n_tmp331 == n_tmp333)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(EQ_EQ_CONSTS);
+ };
+ Node rewritten_node = nm->mkConst(true);
+ return rewrite9<Proof>(rewritten_node, proof);
+ }
+ }
+ };
+ if (n_tmp332 == n_tmp334) {
+ for (unsigned in_tmp337 = 0,
+ in_tmp337_end = n_tmp329.getNumChildren();
+ in_tmp337 < in_tmp337_end; in_tmp337++) {
+ TNode n_tmp337 = n_tmp329[in_tmp337];
+ if ((!(in_tmp332 == in_tmp337)) &&
+ (((((n_tmp337).isConst()) &&
+ ((n_tmp333).isConst())) &&
+ ((n_tmp337 != n_tmp333))) &&
+ ((n_tmp332)
+ .getType()
+ .getCardinality()
+ .knownLessThanOrEqual(Cardinality(2))))) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(EQ_NEQ_CONSTS_CARD2);
+ };
+ Node rewritten_node = nm->mkConst(false);
+ return rewrite9<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ return rewrite8<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite11(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite12(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::EQUAL) && (true)) {
+ for (unsigned in_tmp326 = 0, in_tmp326_end = node.getNumChildren();
+ in_tmp326 < in_tmp326_end; in_tmp326++) {
+ TNode n_tmp326 = node[in_tmp326];
+
+ for (unsigned in_tmp325 = 0, in_tmp325_end = node.getNumChildren();
+ in_tmp325 < in_tmp325_end; in_tmp325++) {
+ TNode n_tmp325 = node[in_tmp325];
+ if (!(in_tmp326 == in_tmp325)) {
+ if (n_tmp325 == n_tmp326) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(X_EQ_X);
+ };
+ Node rewritten_node = nm->mkConst(true);
+ return rewrite11<Proof>(rewritten_node, proof);
+ };
+ if (((n_tmp325).getKind() == kind::NOT) &&
+ (n_tmp325[0] == n_tmp326)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(N_X_EQ_X);
+ };
+ Node rewritten_node = nm->mkConst(false);
+ return rewrite11<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ }
+ };
+ return rewrite10<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite13(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite14(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::EQUAL) && (true)) {
+ for (unsigned in_tmp322 = 0, in_tmp322_end = node.getNumChildren();
+ in_tmp322 < in_tmp322_end; in_tmp322++) {
+ TNode n_tmp322 = node[in_tmp322];
+
+ for (unsigned in_tmp321 = 0, in_tmp321_end = node.getNumChildren();
+ in_tmp321 < in_tmp321_end; in_tmp321++) {
+ TNode n_tmp321 = node[in_tmp321];
+ if ((!(in_tmp322 == in_tmp321)) &&
+ ((n_tmp321).getKind() == kind::CONST_BOOLEAN)) {
+ if (n_tmp321 == nm->mkConst(true)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(TRUE_EQ);
+ };
+ Node rewritten_node = n_tmp322;
+ return rewrite13<Proof>(rewritten_node, proof);
+ };
+ if (n_tmp321 == nm->mkConst(false)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(FALSE_EQ);
+ };
+ Node rewritten_node = nm->mkNode(kind::NOT, n_tmp322);
+ return rewrite13<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ }
+ };
+ return rewrite12<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite15(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite16(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if ((node).getKind() == kind::IMPLIES) {
+ if (((node[0]).getKind() == kind::CONST_BOOLEAN) && (true) &&
+ (node[0] == nm->mkConst(true))) {
+ if (Proof) {
+ proof->registerRewrite(TRUE_IMPLIES);
+ };
+ Node rewritten_node = node[1];
+ return rewrite15<Proof>(rewritten_node, proof);
+ };
+ if (((node[1]).getKind() == kind::CONST_BOOLEAN) && (true) &&
+ (node[1] == nm->mkConst(false))) {
+ if (Proof) {
+ proof->registerRewrite(IMPLIES_FALSE);
+ };
+ Node rewritten_node = nm->mkNode(kind::NOT, node[0]);
+ return rewrite15<Proof>(rewritten_node, proof);
+ }
+ };
+ return rewrite14<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite17(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite18(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if ((node).getKind() == kind::IMPLIES) {
+ if (((node[0]).getKind() == kind::CONST_BOOLEAN) && (true) &&
+ (node[0] == nm->mkConst(false))) {
+ if (Proof) {
+ proof->registerRewrite(FALSE_IMPLIES);
+ };
+ Node rewritten_node = nm->mkConst(true);
+ return rewrite17<Proof>(rewritten_node, proof);
+ };
+ if (((node[1]).getKind() == kind::CONST_BOOLEAN) && (true) &&
+ (node[1] == nm->mkConst(true))) {
+ if (Proof) {
+ proof->registerRewrite(IMPLIES_TRUE);
+ };
+ Node rewritten_node = nm->mkConst(true);
+ return rewrite17<Proof>(rewritten_node, proof);
+ };
+ if (((node[0]).getKind() == kind::CONST_BOOLEAN) &&
+ ((node[1]).getKind() == kind::CONST_BOOLEAN) && (true) &&
+ (node[0] == nm->mkConst(true)) && (node[1] == nm->mkConst(false))) {
+ if (Proof) {
+ proof->registerRewrite(TRUE_IMPLIES_FALSE);
+ };
+ Node rewritten_node = nm->mkConst(false);
+ return rewrite17<Proof>(rewritten_node, proof);
+ }
+ };
+ return rewrite16<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite19(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite20(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::AND) && (true)) {
+ for (unsigned in_tmp318 = 0, in_tmp318_end = node.getNumChildren();
+ in_tmp318 < in_tmp318_end; in_tmp318++) {
+ TNode n_tmp318 = node[in_tmp318];
+ if (((n_tmp318).getKind() == kind::CONST_BOOLEAN) &&
+ (n_tmp318 == nm->mkConst(true))) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(AND_TRUE);
+ };
+ std::vector<Node> new_children =
+ std::vector<Node>(node.begin(), node.end());
+ ;
+ new_children.erase(new_children.begin() + in_tmp318);
+ Node x = mkCommutativeNode((node).getKind(), new_children);
+ ;
+ Node rewritten_node = x;
+ return rewrite19<Proof>(rewritten_node, proof);
+ };
+ for (unsigned in_tmp319 = 0, in_tmp319_end = node.getNumChildren();
+ in_tmp319 < in_tmp319_end; in_tmp319++) {
+ TNode n_tmp319 = node[in_tmp319];
+ if ((!(in_tmp318 == in_tmp319)) && (n_tmp319 == n_tmp318)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(AND_DUP);
+ };
+ std::vector<Node> new_children =
+ std::vector<Node>(node.begin(), node.end());
+ ;
+ new_children.erase(new_children.begin() + in_tmp319);
+ new_children.erase(new_children.begin() + in_tmp318);
+ Node x = mkCommutativeNode((node).getKind(), new_children);
+ ;
+ Node rewritten_node = nm->mkNode(kind::AND, n_tmp319, x);
+ return rewrite19<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ };
+ return rewrite18<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite21(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite22(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::AND) && (true)) {
+ for (unsigned in_tmp317 = 0, in_tmp317_end = node.getNumChildren();
+ in_tmp317 < in_tmp317_end; in_tmp317++) {
+ TNode n_tmp317 = node[in_tmp317];
+ if (((n_tmp317).getKind() == kind::CONST_BOOLEAN) &&
+ (n_tmp317 == nm->mkConst(false))) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(AND_FALSE);
+ };
+ std::vector<Node> new_children =
+ std::vector<Node>(node.begin(), node.end());
+ ;
+ new_children.erase(new_children.begin() + in_tmp317);
+ Node x = mkCommutativeNode((node).getKind(), new_children);
+ ;
+ Node rewritten_node = nm->mkConst(false);
+ return rewrite21<Proof>(rewritten_node, proof);
+ }
+ }
+ };
+ return rewrite20<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite23(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite24(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::OR) && (true)) {
+ for (unsigned in_tmp314 = 0, in_tmp314_end = node.getNumChildren();
+ in_tmp314 < in_tmp314_end; in_tmp314++) {
+ TNode n_tmp314 = node[in_tmp314];
+ if (((n_tmp314).getKind() == kind::CONST_BOOLEAN) &&
+ (n_tmp314 == nm->mkConst(false))) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(OR_FALSE);
+ };
+ std::vector<Node> new_children =
+ std::vector<Node>(node.begin(), node.end());
+ ;
+ new_children.erase(new_children.begin() + in_tmp314);
+ Node x = mkCommutativeNode((node).getKind(), new_children);
+ ;
+ Node rewritten_node = x;
+ return rewrite23<Proof>(rewritten_node, proof);
+ };
+ for (unsigned in_tmp315 = 0, in_tmp315_end = node.getNumChildren();
+ in_tmp315 < in_tmp315_end; in_tmp315++) {
+ TNode n_tmp315 = node[in_tmp315];
+ if ((!(in_tmp314 == in_tmp315)) && (n_tmp315 == n_tmp314)) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(OR_DUP);
+ };
+ std::vector<Node> new_children =
+ std::vector<Node>(node.begin(), node.end());
+ ;
+ new_children.erase(new_children.begin() + in_tmp315);
+ new_children.erase(new_children.begin() + in_tmp314);
+ Node x = mkCommutativeNode((node).getKind(), new_children);
+ ;
+ Node rewritten_node = nm->mkNode(kind::OR, n_tmp315, x);
+ return rewrite23<Proof>(rewritten_node, proof);
+ }
+ }
+ }
+ };
+ return rewrite22<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite25(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite26(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::OR) && (true)) {
+ for (unsigned in_tmp313 = 0, in_tmp313_end = node.getNumChildren();
+ in_tmp313 < in_tmp313_end; in_tmp313++) {
+ TNode n_tmp313 = node[in_tmp313];
+ if (((n_tmp313).getKind() == kind::CONST_BOOLEAN) &&
+ (n_tmp313 == nm->mkConst(true))) {
+ if (Proof) {
+ proof->registerSwap(0, 0);
+ proof->registerRewrite(OR_TRUE);
+ };
+ std::vector<Node> new_children =
+ std::vector<Node>(node.begin(), node.end());
+ ;
+ new_children.erase(new_children.begin() + in_tmp313);
+ Node x = mkCommutativeNode((node).getKind(), new_children);
+ ;
+ Node rewritten_node = nm->mkConst(true);
+ return rewrite25<Proof>(rewritten_node, proof);
+ }
+ }
+ };
+ return rewrite24<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite27(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_AGAIN, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite28(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::NOT) && ((node[0]).getKind() == kind::NOT) &&
+ (true)) {
+ if (Proof) {
+ proof->registerRewrite(NOT_NOT);
+ };
+ Node rewritten_node = node[0][0];
+ return rewrite27<Proof>(rewritten_node, proof);
+ };
+ return rewrite26<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite29(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ return RewriteResponse(REWRITE_DONE, node);
+}
+
+template <bool Proof>
+inline RewriteResponse rewrite30(TNode node, RewriteProof *proof) {
+ NodeManager *nm = NodeManager::currentNM();
+ if (((node).getKind() == kind::NOT) &&
+ ((node[0]).getKind() == kind::CONST_BOOLEAN) && (true)) {
+ if (node[0] == nm->mkConst(true)) {
+ if (Proof) {
+ proof->registerRewrite(NOT_TRUE);
+ };
+ Node rewritten_node = nm->mkConst(false);
+ return rewrite29<Proof>(rewritten_node, proof);
+ };
+ if (node[0] == nm->mkConst(false)) {
+ if (Proof) {
+ proof->registerRewrite(NOT_FALSE);
+ };
+ Node rewritten_node = nm->mkConst(true);
+ return rewrite29<Proof>(rewritten_node, proof);
+ }
+ };
+ return rewrite28<Proof>(node, proof);
+}
+
+template <bool Proof>
+inline RewriteResponse bool_applyRules(TNode node, RewriteProof *proof) {
+
+ return rewrite30<Proof>(node, proof);
+}
+
+inline void bool_printProof(bool use_cache, TheoryProofEngine *tp,
+ const Rewrite *rewrite, std::ostream &os,
+ ProofLetMap &globalLetMap) {
+
+ if (rewrite->d_tag == NOT_TRUE) {
+ os << "(not_true _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == NOT_FALSE) {
+ os << "(not_false _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == NOT_NOT) {
+ os << "(not_not _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == OR_TRUE) {
+ os << "(or_true _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == OR_FALSE) {
+ os << "(or_false _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == OR_DUP) {
+ os << "(or_dup _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == AND_FALSE) {
+ os << "(and_false _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == AND_TRUE) {
+ os << "(and_true _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == AND_DUP) {
+ os << "(and_dup _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == FALSE_IMPLIES) {
+ os << "(false_implies _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == IMPLIES_TRUE) {
+ os << "(implies_true _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == TRUE_IMPLIES_FALSE) {
+ os << "(true_implies_false _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == TRUE_IMPLIES) {
+ os << "(true_implies _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == IMPLIES_FALSE) {
+ os << "(implies_false _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == TRUE_EQ) {
+ os << "(true_eq _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == FALSE_EQ) {
+ os << "(false_eq _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == X_EQ_X) {
+ os << "(x_eq_x _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == N_X_EQ_X) {
+ os << "(n_x_eq_x _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == EQ_EQ_CONSTS) {
+ os << "(eq_eq_consts _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == EQ_NEQ_CONSTS_CARD2) {
+ os << "(eq_neq_consts_card2 _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == EQ_NEQ_CONSTS) {
+ os << "(eq_neq_consts _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == TRUE_XOR) {
+ os << "(true_xor _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == FALSE_XOR) {
+ os << "(false_xor _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == X_XOR_X) {
+ os << "(x_xor_x _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == N_X_XOR_X) {
+ os << "(n_x_xor_x _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_TRUE) {
+ os << "(ite_true _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_FALSE) {
+ os << "(ite_false _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_X_TRUE_FALSE) {
+ os << "(ite_x_true_false _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_FALSE_TRUE) {
+ os << "(ite_c_false_true _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_X_X) {
+ os << "(ite_c_x_x _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_X_N_X) {
+ os << "(ite_c_x_n_x _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_N_X_X) {
+ os << "(ite_c_n_x_x _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_X_X_Y) {
+ os << "(ite_x_x_y _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_N_X_X_Y) {
+ os << "(ite_n_x_x_y _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_X_N_X_Y) {
+ os << "(ite_x_n_x_y _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_X_Y_X) {
+ os << "(ite_x_y_x _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_N_X_Y_X) {
+ os << "(ite_n_x_y_x _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_X_Y_N_X) {
+ os << "(ite_x_y_n_x _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_ITE_C_X_Y_Z) {
+ os << "(ite_c_ite_c_x_y_z _ _ _ _ _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_ITE_N_C_X_Y_Z) {
+ os << "(ite_c_ite_n_c_x_y_z _ _ _ _ _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_N_C_ITE_C_X_Y_Z) {
+ os << "(ite_n_c_ite_c_x_y_z _ _ _ _ _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_Z_ITE_C_X_Y) {
+ os << "(ite_c_z_ite_c_x_y _ _ _ _ _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_C_Z_ITE_N_C_X_Y) {
+ os << "(ite_c_z_ite_n_c_x_y _ _ _ _ _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == ITE_N_C_Z_ITE_C_X_Y) {
+ os << "(ite_n_c_z_ite_c_x_y _ _ _ _ _ _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os,
+ globalLetMap);
+ os << ")";
+ }
+}
+
+} /* CVC4::theory namespace */
+} /* CVC4 namespace */
diff --git a/src/theory/booleans/theory_bool_rewriter.cpp b/src/theory/booleans/theory_bool_rewriter.cpp
index 32f69e037..124b08cc9 100644
--- a/src/theory/booleans/theory_bool_rewriter.cpp
+++ b/src/theory/booleans/theory_bool_rewriter.cpp
@@ -15,15 +15,70 @@
** \todo document this file
**/
-#include <algorithm>
#include "theory/booleans/theory_bool_rewriter.h"
+#include <algorithm>
+
+#include "proof/rewrite_proof_dispatcher.h"
+
namespace CVC4 {
namespace theory {
namespace booleans {
RewriteResponse TheoryBoolRewriter::postRewrite(TNode node) {
- return preRewrite(node);
+ return preRewriteEx<false>(node, NULL);
+}
+
+Node flattenIfNeeded(TNode n) {
+ Kind k = n.getKind();
+ if (k != kind::AND && k != kind::OR) {
+ return n;
+ }
+
+ bool needed = false;
+ for (size_t i = 0; i < n.getNumChildren(); i++) {
+ if (n[i].getKind() == k) {
+ needed = true;
+ break;
+ }
+ }
+ if (!needed) {
+ return n;
+ }
+
+ std::vector<TNode> toProcess;
+ toProcess.push_back(n);
+
+ typedef std::vector<TNode> ChildList;
+ ChildList childList;
+
+ for (unsigned i = 0; i < toProcess.size(); ++ i) {
+ TNode current = toProcess[i];
+ for(unsigned j = 0, j_end = current.getNumChildren(); j < j_end; ++ j) {
+ TNode child = current[j];
+ if(child.getKind() == k) {
+ toProcess.push_back(child);
+ } else {
+ childList.push_back(child);
+ }
+ }
+ }
+
+ NodeManager* nm = NodeManager::currentNM();
+ return nm->mkNode(k, childList);
+}
+
+
+template<bool Proof>
+RewriteResponse TheoryBoolRewriter::postRewriteEx(TNode node_, RewriteProof* proof) {
+ Node node = flattenIfNeeded(node_);
+ RewriteResponse r = bool_applyRules<Proof>(node, proof);
+ if (r.node != preRewrite(node).node) {
+ std::cout << node << " --> " << r.node << std::endl;
+ std::cout << preRewrite(node).node << std::endl;
+ }
+ return r;
+
}
/**
@@ -286,21 +341,21 @@ RewriteResponse TheoryBoolRewriter::preRewrite(TNode n) {
if (n[0] == tt) {
// ITE true x y
- Debug("bool-ite") << "n[0] ==tt " << n << ": " << n[1] << std::endl;
+ Debug("bool-ite") << "n[0] == tt " << n << ": " << n[1] << std::endl;
return RewriteResponse(REWRITE_AGAIN, n[1]);
} else {
Assert(n[0] == ff);
// ITE false x y
- Debug("bool-ite") << "n[0] ==ff " << n << ": " << n[1] << std::endl;
+ Debug("bool-ite") << "n[0] == ff " << n << ": " << n[1] << std::endl;
return RewriteResponse(REWRITE_AGAIN, n[2]);
}
} else if (n[1].isConst()) {
if (n[1] == tt && n[2] == ff) {
- Debug("bool-ite") << "n[1] ==tt && n[2] == ff " << n << ": " << n[0] << std::endl;
+ Debug("bool-ite") << "n[1] == tt && n[2] == ff " << n << ": " << n[0] << std::endl;
return RewriteResponse(REWRITE_AGAIN, n[0]);
}
else if (n[1] == ff && n[2] == tt) {
- Debug("bool-ite") << "n[1] ==ff && n[2] == tt " << n << ": " << n[0].notNode() << std::endl;
+ Debug("bool-ite") << "n[1] == ff && n[2] == tt " << n << ": " << n[0].notNode() << std::endl;
return RewriteResponse(REWRITE_AGAIN, makeNegation(n[0]));
}
// else if(n[1] == ff){
@@ -367,6 +422,109 @@ RewriteResponse TheoryBoolRewriter::preRewrite(TNode n) {
return RewriteResponse(REWRITE_DONE, n);
}
+template<bool Proof>
+RewriteResponse TheoryBoolRewriter::preRewriteEx(TNode node_, RewriteProof* proof) {
+ Node node = flattenIfNeeded(node_);
+ RewriteResponse r = bool_applyRules<Proof>(node, NULL);
+ if (r.node != preRewrite(node).node) {
+ std::cout << node << " --> " << r.node << std::endl;
+ std::cout << preRewrite(node).node << std::endl;
+ }
+ return r;
+}
+
+void TheoryBoolRewriter::printRewriteProof(bool use_cache,
+ TheoryProofEngine* tp,
+ const Rewrite* rewrite,
+ std::ostream& os,
+ ProofLetMap& globalLetMap) {
+ if (rewrite->d_tag == ORIGINAL_OP) {
+ if (rewrite->d_children.size() == 0) {
+ os << "(iff_symm ";
+ tp->printTheoryTerm(rewrite->d_original.toExpr(), os, globalLetMap);
+ os << ")";
+ } else {
+ // XXX: we only need one of those options for each arity
+ switch (rewrite->d_original.getKind()) {
+ case kind::NOT:
+ os << "(symm_formula_op1 not _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << ")";
+ break;
+ case kind::IMPLIES:
+ os << "(symm_formula_op2 impl _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << " ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[1], os, globalLetMap);
+ os << ")";
+ break;
+ case kind::AND:
+ os << "(symm_formula_op2 and _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << " ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[1], os, globalLetMap);
+ os << ")";
+ break;
+ // XXX: CHECK THIS
+ case kind::EQUAL:
+ os << "(symm_formula_op2 iff _ _ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << " ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[1], os, globalLetMap);
+ os << ")";
+ break;
+ default:
+ std::cout << "IMPLEMENTATION MISSING " << rewrite->d_original.getKind() << std::endl;
+ Unreachable();
+ }
+ }
+ } else if (rewrite->d_tag == SWAP) {
+ os << "(do_swap_op2 ";
+ switch (rewrite->d_original.getKind()) {
+ case kind::EQUAL:
+ os << "iff ";
+ break;
+ case kind::AND:
+ os << "and ";
+ break;
+ case kind::OR:
+ os << "or ";
+ break;
+ case kind::XOR:
+ os << "xor ";
+ break;
+ default:
+ std::cout << "IMPLEMENTATION MISSING " << rewrite->d_original.getKind() << std::endl;
+ Unreachable();
+ }
+ os << rewrite->swap_id1 << " ";
+ os << rewrite->swap_id2 << " ";
+ os << "_ _ _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << ")";
+ } else {
+ bool_printProof(use_cache, tp, rewrite, os, globalLetMap);
+ }
+ /*
+ if (rewrite->d_tag == NOT_TRUE) {
+ os << "(not_t _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << ")";
+ } else if (rewrite->d_tag == TRUE_IMPLIES_FALSE) {
+ os << "(t_impl_f _ ";
+ callPrintRewriteProof(use_cache, tp, rewrite->d_children[0], os, globalLetMap);
+ os << ")";
+ } else {
+ std::cout << "ERROR" << std::endl;
+ Unreachable();
+ }*/
+}
+
+template RewriteResponse TheoryBoolRewriter::preRewriteEx<true>(TNode node, RewriteProof* proof);
+template RewriteResponse TheoryBoolRewriter::preRewriteEx<false>(TNode node, RewriteProof* proof);
+template RewriteResponse TheoryBoolRewriter::postRewriteEx<true>(TNode node, RewriteProof* proof);
+template RewriteResponse TheoryBoolRewriter::postRewriteEx<false>(TNode node, RewriteProof* proof);
+
}/* CVC4::theory::booleans namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/booleans/theory_bool_rewriter.h b/src/theory/booleans/theory_bool_rewriter.h
index b7512ad09..cba66abe5 100644
--- a/src/theory/booleans/theory_bool_rewriter.h
+++ b/src/theory/booleans/theory_bool_rewriter.h
@@ -20,6 +20,7 @@
#ifndef __CVC4__THEORY__BOOLEANS__THEORY_BOOL_REWRITER_H
#define __CVC4__THEORY__BOOLEANS__THEORY_BOOL_REWRITER_H
+#include "theory/booleans/bool.h"
#include "theory/rewriter.h"
namespace CVC4 {
@@ -27,15 +28,26 @@ namespace theory {
namespace booleans {
class TheoryBoolRewriter {
-
public:
+ enum BoolRewrites {
+ NOT_TRUE = LAST_SHARED,
+ TRUE_IMPLIES_FALSE,
+ };
static RewriteResponse preRewrite(TNode node);
+ template<bool Proof>
+ static RewriteResponse preRewriteEx(TNode node, RewriteProof* proof);
static RewriteResponse postRewrite(TNode node);
+ template<bool Proof>
+ static RewriteResponse postRewriteEx(TNode node, RewriteProof* proof);
+ static void printRewriteProof(bool use_cache,
+ TheoryProofEngine* tp,
+ const Rewrite* rewrite,
+ std::ostream& os,
+ ProofLetMap& globalLetMap);
static void init() {}
static void shutdown() {}
-
};/* class TheoryBoolRewriter */
}/* CVC4::theory::booleans namespace */
diff --git a/src/theory/quantifiers/quantifiers_rewriter.cpp b/src/theory/quantifiers/quantifiers_rewriter.cpp
index 01352217e..6b4b890de 100644
--- a/src/theory/quantifiers/quantifiers_rewriter.cpp
+++ b/src/theory/quantifiers/quantifiers_rewriter.cpp
@@ -508,7 +508,7 @@ Node QuantifiersRewriter::computeProcessTerms( Node body, std::vector< Node >& n
Assert( !h.isNull() );
// if it is a function definition, rewrite the body independently
Node fbody = TermDb::getFunDefBody( q );
- Assert( !body.isNull() );
+ Assert( !fbody.isNull() );
Trace("quantifiers-rewrite-debug") << "Decompose " << h << " / " << fbody << " as function definition for " << q << "." << std::endl;
Node r = computeProcessTerms2( fbody, true, true, curr_cond, 0, cache, icache, new_vars, new_conds, false );
Assert( new_vars.size()==h.getNumChildren() );
diff --git a/src/theory/rewriter.cpp b/src/theory/rewriter.cpp
index 0df122571..a5d011e9f 100644
--- a/src/theory/rewriter.cpp
+++ b/src/theory/rewriter.cpp
@@ -17,11 +17,8 @@
#include "theory/rewriter.h"
-#include "theory/theory.h"
-#include "smt/smt_engine_scope.h"
-#include "smt/smt_statistics_registry.h"
+#include "proof/rewrite_proof_dispatcher.h"
#include "theory/rewriter_tables.h"
-#include "util/resource_manager.h"
using namespace std;
@@ -30,10 +27,6 @@ namespace theory {
unsigned long Rewriter::d_iterationCount = 0;
-static TheoryId theoryOf(TNode node) {
- return Theory::theoryOf(THEORY_OF_TYPE_BASED, node);
-}
-
#ifdef CVC4_ASSERTIONS
static CVC4_THREADLOCAL(std::hash_set<Node, NodeHashFunction>*) s_rewriteStack = NULL;
#endif /* CVC4_ASSERTIONS */
@@ -85,11 +78,11 @@ struct RewriteStackElement {
};
Node Rewriter::rewrite(TNode node) {
- return rewriteTo(theoryOf(node), node);
+ return rewriteTo<false>(theoryOf(node), node, NULL);
}
-Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
-
+template<bool Proof>
+Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node, RewriteProof* rp) {
#ifdef CVC4_ASSERTIONS
bool isEquality = node.getKind() == kind::EQUAL && (!node[0].getType().isBoolean());
@@ -101,14 +94,19 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
Trace("rewriter") << "Rewriter::rewriteTo(" << theoryId << "," << node << ")"<< std::endl;
// Check if it's been cached already
- Node cached = getPostRewriteCache(theoryId, node);
- if (!cached.isNull()) {
- return cached;
+ if (!Proof) {
+ Node cached = getPostRewriteCache(theoryId, node);
+ if (!cached.isNull()) {
+ return cached;
+ }
}
// Put the node on the stack in order to start the "recursive" rewrite
vector<RewriteStackElement> rewriteStack;
rewriteStack.push_back(RewriteStackElement(node, theoryId));
+ if (Proof) {
+ rp->addRewrite(new Rewrite(ORIGINAL_OP, node));
+ }
ResourceManager* rm = NULL;
bool hasSmtEngine = smt::smtEngineInScope();
@@ -119,26 +117,25 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
for (;;){
if (hasSmtEngine &&
- d_iterationCount % ResourceManager::getFrequencyCount() == 0) {
+ d_iterationCount % ResourceManager::getFrequencyCount() == 0) {
rm->spendResource(options::rewriteStep());
d_iterationCount = 0;
}
// Get the top of the recursion stack
RewriteStackElement& rewriteStackTop = rewriteStack.back();
-
Trace("rewriter") << "Rewriter::rewriting: " << (TheoryId) rewriteStackTop.theoryId << "," << rewriteStackTop.node << std::endl;
// Before rewriting children we need to do a pre-rewrite of the node
if (rewriteStackTop.nextChild == 0) {
-
// Check if the pre-rewrite has already been done (it's in the cache)
Node cached = Rewriter::getPreRewriteCache((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node);
- if (cached.isNull()) {
+ if ((Proof && rp->getPreRewriteCache(rewriteStackTop.node) == NULL) || cached.isNull()) {
// Rewrite until fix-point is reached
for(;;) {
// Perform the pre-rewrite
- RewriteResponse response = Rewriter::callPreRewrite((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node);
+ RewriteResponse response = Proof ? callPreRewriteWithProof((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node, rp) : Rewriter::callPreRewrite((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node);
+
// Put the rewritten node to the top of the stack
rewriteStackTop.node = response.node;
TheoryId newTheory = theoryOf(rewriteStackTop.node);
@@ -148,14 +145,23 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
}
rewriteStackTop.theoryId = newTheory;
}
+
// Cache the rewrite
Rewriter::setPreRewriteCache((TheoryId) rewriteStackTop.originalTheoryId, rewriteStackTop.original, rewriteStackTop.node);
+ if (Proof) {
+ rp->setPreRewriteCache(rewriteStackTop.original, rp->getTopRewrite());
+ }
}
// Otherwise we're have already been pre-rewritten (in pre-rewrite cache)
else {
// Continue with the cached version
rewriteStackTop.node = cached;
rewriteStackTop.theoryId = theoryOf(cached);
+ if (Proof) {
+ Rewrite* cachedRewrite = rp->getPreRewriteCache(rewriteStackTop.original);
+ cachedRewrite->d_cached_version_used = true;
+ rp->replaceRewrite(cachedRewrite);
+ }
}
}
@@ -163,7 +169,7 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
// Now it's time to rewrite the children, check if this has already been done
Node cached = Rewriter::getPostRewriteCache((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node);
// If not, go through the children
- if(cached.isNull()) {
+ if((Proof && rp->getPostRewriteCache(rewriteStackTop.node) == NULL) || cached.isNull()) {
// The child we need to rewrite
unsigned child = rewriteStackTop.nextChild++;
@@ -186,6 +192,9 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
Node childNode = rewriteStackTop.node[child];
// Push the rewrite request to the stack (NOTE: rewriteStackTop might be a bad reference now)
rewriteStack.push_back(RewriteStackElement(childNode, theoryOf(childNode)));
+ if (Proof) {
+ rp->addRewrite(new Rewrite(ORIGINAL_OP, childNode));
+ }
// Go on with the rewriting
continue;
}
@@ -200,7 +209,7 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
// Done with all pre-rewriting, so let's do the post rewrite
for(;;) {
// Do the post-rewrite
- RewriteResponse response = Rewriter::callPostRewrite((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node);
+ RewriteResponse response = Proof ? callPostRewriteWithProof((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node, rp) : Rewriter::callPostRewrite((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node);
// We continue with the response we got
TheoryId newTheoryId = theoryOf(response.node);
if (newTheoryId != (TheoryId) rewriteStackTop.theoryId || response.status == REWRITE_AGAIN_FULL) {
@@ -211,24 +220,30 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
Assert(s_rewriteStack->find(response.node) == s_rewriteStack->end());
s_rewriteStack->insert(response.node);
#endif
- Node rewritten = rewriteTo(newTheoryId, response.node);
- rewriteStackTop.node = rewritten;
+ if (Proof) {
+ RewriteProof subRp;
+ Node rewritten = rewriteWithProof(response.node, &subRp);
+ rewriteStackTop.node = rewritten;
+ } else {
+ rewriteStackTop.node = rewrite(response.node);
+ }
#ifdef CVC4_ASSERTIONS
+ Assert(s_rewriteStack);
s_rewriteStack->erase(response.node);
#endif
break;
} else if (response.status == REWRITE_DONE) {
#ifdef CVC4_ASSERTIONS
- RewriteResponse r2 = Rewriter::callPostRewrite(newTheoryId, response.node);
- Assert(r2.node == response.node);
+ RewriteResponse r2 = Rewriter::callPostRewrite(newTheoryId, response.node);
+ Assert(r2.node == response.node);
#endif
- rewriteStackTop.node = response.node;
+ rewriteStackTop.node = response.node;
break;
}
// Check for trivial rewrite loops of size 1 or 2
Assert(response.node != rewriteStackTop.node);
Assert(Rewriter::callPostRewrite((TheoryId) rewriteStackTop.theoryId, response.node).node != rewriteStackTop.node);
- rewriteStackTop.node = response.node;
+ rewriteStackTop.node = response.node;
}
// We're done with the post rewrite, so we add to the cache
Rewriter::setPostRewriteCache((TheoryId) rewriteStackTop.originalTheoryId, rewriteStackTop.original, rewriteStackTop.node);
@@ -237,6 +252,11 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
// We were already in cache, so just remember it
rewriteStackTop.node = cached;
rewriteStackTop.theoryId = theoryOf(cached);
+ if (Proof) {
+ Rewrite* cachedRewrite = rp->getPostRewriteCache(rewriteStackTop.original);
+ cachedRewrite->d_cached_version_used = true;
+ rp->replaceRewrite(cachedRewrite);
+ }
}
// If this is the last node, just return
@@ -248,12 +268,21 @@ Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) {
// We're done with this node, append it to the parent
rewriteStack[rewriteStack.size() - 2].builder << rewriteStackTop.node;
rewriteStack.pop_back();
+
+ if (Proof) {
+ rp->attachSubproofToParent();
+ }
}
Unreachable();
return Node::null();
}/* Rewriter::rewriteTo() */
+Node Rewriter::rewriteWithProof(TNode node, RewriteProof* rp) throw (UnsafeInterruptException){
+ Node result = rewriteTo<true>(theoryOf(node), node, rp);
+ return result;
+}
+
void Rewriter::clearCaches() {
#ifdef CVC4_ASSERTIONS
if(s_rewriteStack != NULL) {
@@ -264,5 +293,8 @@ void Rewriter::clearCaches() {
Rewriter::clearCachesInternal();
}
+template Node Rewriter::rewriteTo<true>(theory::TheoryId theoryId, Node node, RewriteProof* rp);
+template Node Rewriter::rewriteTo<false>(theory::TheoryId theoryId, Node node, RewriteProof* rp);
+
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/rewriter.h b/src/theory/rewriter.h
index aed93a451..7f01be250 100644
--- a/src/theory/rewriter.h
+++ b/src/theory/rewriter.h
@@ -19,11 +19,43 @@
#pragma once
#include "expr/node.h"
+#include "smt/smt_engine_scope.h"
+#include "smt/smt_statistics_registry.h"
+#include "theory/theory.h"
+#include "util/resource_manager.h"
#include "util/unsafe_interrupt_exception.h"
+using namespace std;
+
namespace CVC4 {
namespace theory {
+static inline Node mkCommutativeNode(Kind k, const std::vector<Node>& children) {
+ NodeManager *nm = NodeManager::currentNM();
+
+ if (children.size() == 0) {
+ switch (k) {
+ case kind::AND:
+ return nm->mkConst(true);
+ break;
+ case kind::OR:
+ return nm->mkConst(false);
+ break;
+ default:
+ abort();
+ break;
+ }
+ } else if (children.size() == 1) {
+ return children[0];
+ } else {
+ return nm->mkNode(k, children);
+ }
+}
+
+static inline TheoryId theoryOf(TNode node) {
+ return Theory::theoryOf(THEORY_OF_TYPE_BASED, node);
+}
+
/**
* Theory rewriters signal whether more rewriting is needed (or not)
* by using a member of this enumeration. See RewriteResponse, below.
@@ -44,6 +76,7 @@ enum RewriteStatus {
struct RewriteResponse {
const RewriteStatus status;
const Node node;
+
RewriteResponse(RewriteStatus status, Node node) :
status(status), node(node) {}
};/* struct RewriteResponse */
@@ -78,7 +111,8 @@ class Rewriter {
/**
* Rewrites the node using the given theory rewriter.
*/
- static Node rewriteTo(theory::TheoryId theoryId, Node node);
+ template<bool Proof>
+ static Node rewriteTo(theory::TheoryId theoryId, Node node, RewriteProof* rp);
/** Calls the pre-rewriter for the given theory */
static RewriteResponse callPreRewrite(theory::TheoryId theoryId, TNode node);
@@ -110,6 +144,12 @@ public:
static Node rewrite(TNode node);
/**
+ * Rewrites the node using theoryOf() to determine which rewriter to
+ * use on the node and generates a proof.
+ */
+ static Node rewriteWithProof(TNode node, RewriteProof* rp) throw (UnsafeInterruptException);
+
+ /**
* Garbage collects the rewrite caches.
*/
static void clearCaches();
diff --git a/test/regress/regress0/arrays/Makefile.am b/test/regress/regress0/arrays/Makefile.am
index 17cfa3fd4..5b46f9cd3 100644
--- a/test/regress/regress0/arrays/Makefile.am
+++ b/test/regress/regress0/arrays/Makefile.am
@@ -50,7 +50,10 @@ TESTS = \
constarr3.cvc \
parsing_ringer.cvc \
bug637.delta.smt2 \
- bool-array.smt2
+ bool-array.smt2 \
+ simple_rewrite_proof.smt2 \
+ simple_rewrite_proof2.smt2 \
+ rewrite_proof_cache.smt2
EXTRA_DIST = $(TESTS)
diff --git a/test/regress/regress0/arrays/rewrite_proof_cache.smt2 b/test/regress/regress0/arrays/rewrite_proof_cache.smt2
new file mode 100644
index 000000000..c2d9ee09e
--- /dev/null
+++ b/test/regress/regress0/arrays/rewrite_proof_cache.smt2
@@ -0,0 +1,14 @@
+(set-logic QF_AX)
+(set-info :smt-lib-version 2.0)
+(set-info :status unsat)
+(declare-sort Index 0)
+(declare-sort Element 0)
+(declare-fun a1 () (Array Index Element))
+(declare-fun a2 () (Array Index Element))
+(declare-fun i1 () Index)
+(declare-fun i2 () Index)
+(declare-fun e1 () Element)
+(declare-fun x () Bool)
+(assert (=> (= (select (store a1 i2 (select a1 i2)) i1) (select a1 i1)) (not (= (select (store a1 i2 (select a1 i2)) i1) (select a1 i1)))))
+(check-sat)
+(exit)
diff --git a/test/regress/regress0/arrays/simple_rewrite_proof.smt2 b/test/regress/regress0/arrays/simple_rewrite_proof.smt2
new file mode 100644
index 000000000..0a3fe2229
--- /dev/null
+++ b/test/regress/regress0/arrays/simple_rewrite_proof.smt2
@@ -0,0 +1,13 @@
+(set-logic QF_AX)
+(set-info :smt-lib-version 2.0)
+(set-info :status unsat)
+(declare-sort Index 0)
+(declare-sort Element 0)
+(declare-fun a1 () (Array Index Element))
+(declare-fun a2 () (Array Index Element))
+(declare-fun i1 () Index)
+(declare-fun i2 () Index)
+(declare-fun e1 () Element)
+(assert (not (= (select (store a1 i2 (select a1 i2)) i1) (select a1 i1))))
+(check-sat)
+(exit)
diff --git a/test/regress/regress0/arrays/simple_rewrite_proof2.smt2 b/test/regress/regress0/arrays/simple_rewrite_proof2.smt2
new file mode 100644
index 000000000..639f21e38
--- /dev/null
+++ b/test/regress/regress0/arrays/simple_rewrite_proof2.smt2
@@ -0,0 +1,13 @@
+(set-logic QF_AX)
+(set-info :smt-lib-version 2.0)
+(set-info :status unsat)
+(declare-sort Index 0)
+(declare-sort Element 0)
+(declare-fun a1 () (Array Index Element))
+(declare-fun a2 () (Array Index Element))
+(declare-fun i1 () Index)
+(declare-fun i2 () Index)
+(declare-fun e1 () Element)
+(assert (not (= (select (store (store a1 i2 e1) i2 (select a1 i2)) i1) (select (store a1 i2 (select a1 i2)) i1))))
+(check-sat)
+(exit)
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback