diff --git a/src/HOL/Library/Tools/smt_word.ML b/src/HOL/Library/Tools/smt_word.ML --- a/src/HOL/Library/Tools/smt_word.ML +++ b/src/HOL/Library/Tools/smt_word.ML @@ -1,158 +1,167 @@ (* Title: HOL/Word/Tools/smt_word.ML Author: Sascha Boehme, TU Muenchen SMT setup for words. *) signature SMT_WORD = sig val add_word_shift': term * string -> Context.generic -> Context.generic end structure SMT_Word : SMT_WORD = struct open Word_Lib (* SMT-LIB logic *) (* "QF_AUFBV" is too restrictive for Isabelle's problems, which contain aritmetic and quantifiers. Better set the logic to "" and make at least Z3 happy. *) fun smtlib_logic ts = if exists (Term.exists_type (Term.exists_subtype is_wordT)) ts then SOME "" else NONE (* SMT-LIB builtins *) local val smtlibC = SMTLIB_Interface.smtlibC val wordT = \<^typ>\'a::len word\ fun index1 s i = "(_ " ^ s ^ " " ^ string_of_int i ^ ")" fun index2 s i j = "(_ " ^ s ^ " " ^ string_of_int i ^ " " ^ string_of_int j ^ ")" fun word_typ (Type (\<^type_name>\word\, [T])) = Option.map (rpair [] o index1 "BitVec") (try dest_binT T) | word_typ _ = NONE + (*CVC4 does not support "_bvk T" when k does not fit in the BV of size T, so remove the bits that + will be ignored according to the SMT-LIB*) fun word_num (Type (\<^type_name>\word\, [T])) k = - Option.map (index1 ("bv" ^ string_of_int k)) (try dest_binT T) + let + val size = try dest_binT T + fun max_int size = IntInf.pow (2, size) + in + (case size of + NONE => NONE + | SOME size => SOME (index1 ("bv" ^ string_of_int (Int.rem(k, max_int size))) size)) + end | word_num _ _ = NONE fun if_fixed pred m n T ts = let val (Us, U) = Term.strip_type T in if pred (U, Us) then SOME (n, length Us, ts, Term.list_comb o pair (Const (m, T))) else NONE end fun if_fixed_all m = if_fixed (forall (can dest_wordT) o (op ::)) m fun if_fixed_args m = if_fixed (forall (can dest_wordT) o snd) m fun add_word_fun f (t, n) = let val (m, _) = Term.dest_Const t in SMT_Builtin.add_builtin_fun smtlibC (Term.dest_Const t, K (f m n)) end val mk_nat = HOLogic.mk_number \<^typ>\nat\ fun mk_shift c [u, t] = Const c $ mk_nat (snd (HOLogic.dest_number u)) $ t | mk_shift c ts = raise TERM ("bad arguments", Const c :: ts) fun shift m n T ts = let val U = Term.domain_type (Term.range_type T) in (case (can dest_wordT U, try (snd o HOLogic.dest_number o hd) ts) of (true, SOME i) => SOME (n, 2, [hd (tl ts), HOLogic.mk_number U i], mk_shift (m, T)) | _ => NONE) (* FIXME: also support non-numerical shifts *) end fun mk_shift' c [t, u] = Const c $ t $ mk_nat (snd (HOLogic.dest_number u)) | mk_shift' c ts = raise TERM ("bad arguments", Const c :: ts) fun shift' m n T ts = let val U = Term.domain_type T in (case (can dest_wordT U, try (snd o HOLogic.dest_number o hd o tl) ts) of (true, SOME i) => SOME (n, 2, [hd ts, HOLogic.mk_number U i], mk_shift' (m, T)) | _ => NONE) (* FIXME: also support non-numerical shifts *) end fun mk_extract c i ts = Term.list_comb (Const c, mk_nat i :: ts) fun extract m n T ts = let val U = Term.range_type (Term.range_type T) in (case (try (snd o HOLogic.dest_number o hd) ts, try dest_wordT U) of (SOME lb, SOME i) => SOME (index2 n (i + lb - 1) lb, 1, tl ts, mk_extract (m, T) lb) | _ => NONE) end fun mk_extend c ts = Term.list_comb (Const c, ts) fun extend m n T ts = let val (U1, U2) = Term.dest_funT T in (case (try dest_wordT U1, try dest_wordT U2) of (SOME i, SOME j) => if j-i >= 0 then SOME (index1 n (j-i), 1, ts, mk_extend (m, T)) else NONE | _ => NONE) end fun mk_rotate c i ts = Term.list_comb (Const c, mk_nat i :: ts) fun rotate m n T ts = let val U = Term.domain_type (Term.range_type T) in (case (can dest_wordT U, try (snd o HOLogic.dest_number o hd) ts) of (true, SOME i) => SOME (index1 n i, 1, tl ts, mk_rotate (m, T) i) | _ => NONE) end in val setup_builtins = SMT_Builtin.add_builtin_typ smtlibC (wordT, word_typ, word_num) #> fold (add_word_fun if_fixed_all) [ (\<^term>\uminus :: 'a::len word \ _\, "bvneg"), (\<^term>\plus :: 'a::len word \ _\, "bvadd"), (\<^term>\minus :: 'a::len word \ _\, "bvsub"), (\<^term>\times :: 'a::len word \ _\, "bvmul"), (\<^term>\NOT :: 'a::len word \ _\, "bvnot"), (\<^term>\(AND) :: 'a::len word \ _\, "bvand"), (\<^term>\(OR) :: 'a::len word \ _\, "bvor"), (\<^term>\(XOR) :: 'a::len word \ _\, "bvxor"), (\<^term>\word_cat :: 'a::len word \ _\, "concat") ] #> fold (add_word_fun shift) [ (\<^term>\push_bit :: nat \ 'a::len word \ _ \, "bvshl"), (\<^term>\drop_bit :: nat \ 'a::len word \ _\, "bvlshr"), (\<^term>\signed_drop_bit :: nat \ 'a::len word \ _\, "bvashr") ] #> add_word_fun extract (\<^term>\slice :: _ \ 'a::len word \ _\, "extract") #> fold (add_word_fun extend) [ (\<^term>\ucast :: 'a::len word \ _\, "zero_extend"), (\<^term>\scast :: 'a::len word \ _\, "sign_extend") ] #> fold (add_word_fun rotate) [ (\<^term>\word_rotl\, "rotate_left"), (\<^term>\word_rotr\, "rotate_right") ] #> fold (add_word_fun if_fixed_args) [ (\<^term>\less :: 'a::len word \ _\, "bvult"), (\<^term>\less_eq :: 'a::len word \ _\, "bvule"), (\<^term>\word_sless\, "bvslt"), (\<^term>\word_sle\, "bvsle") ] val add_word_shift' = add_word_fun shift' end (* setup *) val _ = Theory.setup (Context.theory_map ( SMTLIB_Interface.add_logic (20, smtlib_logic) #> setup_builtins)) end; diff --git a/src/HOL/SMT_Examples/SMT_Examples_Verit.thy b/src/HOL/SMT_Examples/SMT_Examples_Verit.thy --- a/src/HOL/SMT_Examples/SMT_Examples_Verit.thy +++ b/src/HOL/SMT_Examples/SMT_Examples_Verit.thy @@ -1,741 +1,741 @@ (* Title: HOL/SMT_Examples/SMT_Examples_Verit.thy Author: Sascha Boehme, TU Muenchen Author: Mathias Fleury, JKU Half of the examples come from the corresponding file for z3, the others come from the Isabelle distribution or the AFP. *) section \Examples for the (smt (verit)) binding\ theory SMT_Examples_Verit imports Complex_Main begin external_file \SMT_Examples_Verit.certs\ declare [[smt_certificates = "SMT_Examples_Verit.certs"]] declare [[smt_read_only_certificates = true]] section \Propositional and first-order logic\ lemma "True" by (smt (verit)) lemma "p \ \p" by (smt (verit)) lemma "(p \ True) = p" by (smt (verit)) lemma "(p \ q) \ \p \ q" by (smt (verit)) lemma "(a \ b) \ (c \ d) \ (a \ b) \ (c \ d)" by (smt (verit)) lemma "(p1 \ p2) \ p3 \ (p1 \ (p3 \ p2) \ (p1 \ p3)) \ p1" by (smt (verit)) lemma "P = P = P = P = P = P = P = P = P = P" by (smt (verit)) lemma assumes "a \ b \ c \ d" and "e \ f \ (a \ d)" and "\ (a \ (c \ ~c)) \ b" and "\ (b \ (x \ \ x)) \ c" and "\ (d \ False) \ c" and "\ (c \ (\ p \ (p \ (q \ \ q))))" shows False using assms by (smt (verit)) axiomatization symm_f :: "'a \ 'a \ 'a" where symm_f: "symm_f x y = symm_f y x" lemma "a = a \ symm_f a b = symm_f b a" by (smt (verit) symm_f) (* Taken from ~~/src/HOL/ex/SAT_Examples.thy. Translated from TPTP problem library: PUZ015-2.006.dimacs *) lemma assumes "~x0" and "~x30" and "~x29" and "~x59" and "x1 \ x31 \ x0" and "x2 \ x32 \ x1" and "x3 \ x33 \ x2" and "x4 \ x34 \ x3" and "x35 \ x4" and "x5 \ x36 \ x30" and "x6 \ x37 \ x5 \ x31" and "x7 \ x38 \ x6 \ x32" and "x8 \ x39 \ x7 \ x33" and "x9 \ x40 \ x8 \ x34" and "x41 \ x9 \ x35" and "x10 \ x42 \ x36" and "x11 \ x43 \ x10 \ x37" and "x12 \ x44 \ x11 \ x38" and "x13 \ x45 \ x12 \ x39" and "x14 \ x46 \ x13 \ x40" and "x47 \ x14 \ x41" and "x15 \ x48 \ x42" and "x16 \ x49 \ x15 \ x43" and "x17 \ x50 \ x16 \ x44" and "x18 \ x51 \ x17 \ x45" and "x19 \ x52 \ x18 \ x46" and "x53 \ x19 \ x47" and "x20 \ x54 \ x48" and "x21 \ x55 \ x20 \ x49" and "x22 \ x56 \ x21 \ x50" and "x23 \ x57 \ x22 \ x51" and "x24 \ x58 \ x23 \ x52" and "x59 \ x24 \ x53" and "x25 \ x54" and "x26 \ x25 \ x55" and "x27 \ x26 \ x56" and "x28 \ x27 \ x57" and "x29 \ x28 \ x58" and "~x1 \ ~x31" and "~x1 \ ~x0" and "~x31 \ ~x0" and "~x2 \ ~x32" and "~x2 \ ~x1" and "~x32 \ ~x1" and "~x3 \ ~x33" and "~x3 \ ~x2" and "~x33 \ ~x2" and "~x4 \ ~x34" and "~x4 \ ~x3" and "~x34 \ ~x3" and "~x35 \ ~x4" and "~x5 \ ~x36" and "~x5 \ ~x30" and "~x36 \ ~x30" and "~x6 \ ~x37" and "~x6 \ ~x5" and "~x6 \ ~x31" and "~x37 \ ~x5" and "~x37 \ ~x31" and "~x5 \ ~x31" and "~x7 \ ~x38" and "~x7 \ ~x6" and "~x7 \ ~x32" and "~x38 \ ~x6" and "~x38 \ ~x32" and "~x6 \ ~x32" and "~x8 \ ~x39" and "~x8 \ ~x7" and "~x8 \ ~x33" and "~x39 \ ~x7" and "~x39 \ ~x33" and "~x7 \ ~x33" and "~x9 \ ~x40" and "~x9 \ ~x8" and "~x9 \ ~x34" and "~x40 \ ~x8" and "~x40 \ ~x34" and "~x8 \ ~x34" and "~x41 \ ~x9" and "~x41 \ ~x35" and "~x9 \ ~x35" and "~x10 \ ~x42" and "~x10 \ ~x36" and "~x42 \ ~x36" and "~x11 \ ~x43" and "~x11 \ ~x10" and "~x11 \ ~x37" and "~x43 \ ~x10" and "~x43 \ ~x37" and "~x10 \ ~x37" and "~x12 \ ~x44" and "~x12 \ ~x11" and "~x12 \ ~x38" and "~x44 \ ~x11" and "~x44 \ ~x38" and "~x11 \ ~x38" and "~x13 \ ~x45" and "~x13 \ ~x12" and "~x13 \ ~x39" and "~x45 \ ~x12" and "~x45 \ ~x39" and "~x12 \ ~x39" and "~x14 \ ~x46" and "~x14 \ ~x13" and "~x14 \ ~x40" and "~x46 \ ~x13" and "~x46 \ ~x40" and "~x13 \ ~x40" and "~x47 \ ~x14" and "~x47 \ ~x41" and "~x14 \ ~x41" and "~x15 \ ~x48" and "~x15 \ ~x42" and "~x48 \ ~x42" and "~x16 \ ~x49" and "~x16 \ ~x15" and "~x16 \ ~x43" and "~x49 \ ~x15" and "~x49 \ ~x43" and "~x15 \ ~x43" and "~x17 \ ~x50" and "~x17 \ ~x16" and "~x17 \ ~x44" and "~x50 \ ~x16" and "~x50 \ ~x44" and "~x16 \ ~x44" and "~x18 \ ~x51" and "~x18 \ ~x17" and "~x18 \ ~x45" and "~x51 \ ~x17" and "~x51 \ ~x45" and "~x17 \ ~x45" and "~x19 \ ~x52" and "~x19 \ ~x18" and "~x19 \ ~x46" and "~x52 \ ~x18" and "~x52 \ ~x46" and "~x18 \ ~x46" and "~x53 \ ~x19" and "~x53 \ ~x47" and "~x19 \ ~x47" and "~x20 \ ~x54" and "~x20 \ ~x48" and "~x54 \ ~x48" and "~x21 \ ~x55" and "~x21 \ ~x20" and "~x21 \ ~x49" and "~x55 \ ~x20" and "~x55 \ ~x49" and "~x20 \ ~x49" and "~x22 \ ~x56" and "~x22 \ ~x21" and "~x22 \ ~x50" and "~x56 \ ~x21" and "~x56 \ ~x50" and "~x21 \ ~x50" and "~x23 \ ~x57" and "~x23 \ ~x22" and "~x23 \ ~x51" and "~x57 \ ~x22" and "~x57 \ ~x51" and "~x22 \ ~x51" and "~x24 \ ~x58" and "~x24 \ ~x23" and "~x24 \ ~x52" and "~x58 \ ~x23" and "~x58 \ ~x52" and "~x23 \ ~x52" and "~x59 \ ~x24" and "~x59 \ ~x53" and "~x24 \ ~x53" and "~x25 \ ~x54" and "~x26 \ ~x25" and "~x26 \ ~x55" and "~x25 \ ~x55" and "~x27 \ ~x26" and "~x27 \ ~x56" and "~x26 \ ~x56" and "~x28 \ ~x27" and "~x28 \ ~x57" and "~x27 \ ~x57" and "~x29 \ ~x28" and "~x29 \ ~x58" and "~x28 \ ~x58" shows False using assms by (smt (verit)) lemma "\x::int. P x \ (\y::int. P x \ P y)" by (smt (verit)) lemma assumes "(\x y. P x y = x)" shows "(\y. P x y) = P x c" using assms by (smt (verit)) lemma assumes "(\x y. P x y = x)" and "(\x. \y. P x y) = (\x. P x c)" shows "(\y. P x y) = P x c" using assms by (smt (verit)) lemma assumes "if P x then \(\y. P y) else (\y. \P y)" shows "P x \ P y" using assms by (smt (verit)) section \Arithmetic\ subsection \Linear arithmetic over integers and reals\ lemma "(3::int) = 3" by (smt (verit)) lemma "(3::real) = 3" by (smt (verit)) lemma "(3 :: int) + 1 = 4" by (smt (verit)) lemma "x + (y + z) = y + (z + (x::int))" by (smt (verit)) lemma "max (3::int) 8 > 5" by (smt (verit)) lemma "\x :: real\ + \y\ \ \x + y\" by (smt (verit)) lemma "P ((2::int) < 3) = P True" supply[[smt_trace]] by (smt (verit)) lemma "x + 3 \ 4 \ x < (1::int)" by (smt (verit)) lemma assumes "x \ (3::int)" and "y = x + 4" shows "y - x > 0" using assms by (smt (verit)) lemma "let x = (2 :: int) in x + x \ 5" by (smt (verit)) lemma fixes x :: int assumes "3 * x + 7 * a < 4" and "3 < 2 * x" shows "a < 0" using assms by (smt (verit)) lemma "(0 \ y + -1 * x \ \ 0 \ x \ 0 \ (x::int)) = (\ False)" by (smt (verit)) lemma " (n < m \ m < n') \ (n < m \ m = n') \ (n < n' \ n' < m) \ (n = n' \ n' < m) \ (n = m \ m < n') \ (n' < m \ m < n) \ (n' < m \ m = n) \ (n' < n \ n < m) \ (n' = n \ n < m) \ (n' = m \ m < n) \ (m < n \ n < n') \ (m < n \ n' = n) \ (m < n' \ n' < n) \ (m = n \ n < n') \ (m = n' \ n' < n) \ (n' = m \ m = (n::int))" by (smt (verit)) text\ The following example was taken from HOL/ex/PresburgerEx.thy, where it says: This following theorem proves that all solutions to the recurrence relation $x_{i+2} = |x_{i+1}| - x_i$ are periodic with period 9. The example was brought to our attention by John Harrison. It does does not require Presburger arithmetic but merely quantifier-free linear arithmetic and holds for the rationals as well. Warning: it takes (in 2006) over 4.2 minutes! There, it is proved by "arith". (smt (verit)) is able to prove this within a fraction of one second. With proof reconstruction, it takes about 13 seconds on a Core2 processor. \ lemma "\ x3 = \x2\ - x1; x4 = \x3\ - x2; x5 = \x4\ - x3; x6 = \x5\ - x4; x7 = \x6\ - x5; x8 = \x7\ - x6; x9 = \x8\ - x7; x10 = \x9\ - x8; x11 = \x10\ - x9 \ \ x1 = x10 \ x2 = (x11::int)" supply [[smt_timeout=360]] by (smt (verit)) lemma "let P = 2 * x + 1 > x + (x::real) in P \ False \ P" by (smt (verit)) subsection \Linear arithmetic with quantifiers\ lemma "~ (\x::int. False)" by (smt (verit)) lemma "~ (\x::real. False)" by (smt (verit)) lemma "\x y::int. (x = 0 \ y = 1) \ x \ y" by (smt (verit)) lemma "\x y::int. x < y \ (2 * x + 1) < (2 * y)" by (smt (verit)) lemma "\x y::int. x + y > 2 \ x + y = 2 \ x + y < 2" by (smt (verit)) lemma "\x::int. if x > 0 then x + 1 > 0 else 1 > x" by (smt (verit)) lemma "(if (\x::int. x < 0 \ x > 0) then -1 else 3) > (0::int)" by (smt (verit)) lemma "\x::int. \x y. 0 < x \ 0 < y \ (0::int) < x + y" by (smt (verit)) lemma "\u::int. \(x::int) y::real. 0 < x \ 0 < y \ -1 < x" by (smt (verit)) lemma "\(a::int) b::int. 0 < b \ b < 1" by (smt (verit)) subsection \Linear arithmetic for natural numbers\ declare [[smt_nat_as_int]] lemma "2 * (x::nat) \ 1" by (smt (verit)) lemma "a < 3 \ (7::nat) > 2 * a" by (smt (verit)) lemma "let x = (1::nat) + y in x - y > 0 * x" by (smt (verit)) lemma "let x = (1::nat) + y in let P = (if x > 0 then True else False) in False \ P = (x - 1 = y) \ (\P \ False)" by (smt (verit)) lemma "int (nat \x::int\) = \x\" by (smt (verit) int_nat_eq) definition prime_nat :: "nat \ bool" where "prime_nat p = (1 < p \ (\m. m dvd p --> m = 1 \ m = p))" lemma "prime_nat (4*m + 1) \ m \ (1::nat)" by (smt (verit) prime_nat_def) lemma "2 * (x::nat) \ 1" by (smt (verit)) lemma \2*(x :: int) \ 1\ by (smt (verit)) declare [[smt_nat_as_int = false]] section \Pairs\ lemma "fst (x, y) = a \ x = a" using fst_conv by (smt (verit)) lemma "p1 = (x, y) \ p2 = (y, x) \ fst p1 = snd p2" using fst_conv snd_conv by (smt (verit)) section \Higher-order problems and recursion\ lemma "i \ i1 \ i \ i2 \ (f (i1 := v1, i2 := v2)) i = f i" using fun_upd_same fun_upd_apply by (smt (verit)) lemma "(f g (x::'a::type) = (g x \ True)) \ (f g x = True) \ (g x = True)" by (smt (verit)) lemma "id x = x \ id True = True" by (smt (verit) id_def) lemma "i \ i1 \ i \ i2 \ ((f (i1 := v1)) (i2 := v2)) i = f i" using fun_upd_same fun_upd_apply by (smt (verit)) lemma "f (\x. g x) \ True" "f (\x. g x) \ True" by (smt (verit))+ lemma True using let_rsp by (smt (verit)) lemma "le = (\) \ le (3::int) 42" by (smt (verit)) lemma "map (\i::int. i + 1) [0, 1] = [1, 2]" by (smt (verit) list.map) lemma "(\x. P x) \ \ All P" by (smt (verit)) fun dec_10 :: "int \ int" where "dec_10 n = (if n < 10 then n else dec_10 (n - 10))" lemma "dec_10 (4 * dec_10 4) = 6" by (smt (verit) dec_10.simps) context complete_lattice begin lemma assumes "Sup {a | i::bool. True} \ Sup {b | i::bool. True}" and "Sup {b | i::bool. True} \ Sup {a | i::bool. True}" shows "Sup {a | i::bool. True} \ Sup {a | i::bool. True}" using assms by (smt (verit) order_trans) end lemma "eq_set (List.coset xs) (set ys) = rhs" if "\ys. subset' (List.coset xs) (set ys) = (let n = card (UNIV::'a set) in 0 < n \ card (set (xs @ ys)) = n)" and "\uu A. (uu::'a) \ - A \ uu \ A" and "\uu. card (set (uu::'a list)) = length (remdups uu)" and "\uu. finite (set (uu::'a list))" and "\uu. (uu::'a) \ UNIV" and "(UNIV::'a set) \ {}" and "\c A B P. \(c::'a) \ A \ B; c \ A \ P; c \ B \ P\ \ P" and "\a b. (a::nat) + b = b + a" and "\a b. ((a::nat) = a + b) = (b = 0)" and "card' (set xs) = length (remdups xs)" and "card' = (card :: 'a set \ nat)" and "\A B. \finite (A::'a set); finite B\ \ card A + card B = card (A \ B) + card (A \ B)" and "\A. (card (A::'a set) = 0) = (A = {} \ infinite A)" and "\A. \finite (UNIV::'a set); card (A::'a set) = card (UNIV::'a set)\ \ A = UNIV" and "\xs. - List.coset (xs::'a list) = set xs" and "\xs. - set (xs::'a list) = List.coset xs" and "\A B. (A \ B = {}) = (\x. (x::'a) \ A \ x \ B)" and "eq_set = (=)" and "\A. finite (A::'a set) \ finite (- A) = finite (UNIV::'a set)" and "rhs \ let n = card (UNIV::'a set) in if n = 0 then False else let xs' = remdups xs; ys' = remdups ys in length xs' + length ys' = n \ (\x\set xs'. x \ set ys') \ (\y\set ys'. y \ set xs')" and "\xs ys. set ((xs::'a list) @ ys) = set xs \ set ys" and "\A B. ((A::'a set) = B) = (A \ B \ B \ A)" and "\xs. set (remdups (xs::'a list)) = set xs" and "subset' = (\)" and "\A B. (\x. (x::'a) \ A \ x \ B) \ A \ B" and "\A B. \(A::'a set) \ B; B \ A\ \ A = B" and "\A ys. (A \ List.coset ys) = (\y\set ys. (y::'a) \ A)" using that by (smt (verit, default)) notepad begin have "line_integral F {i, j} g = line_integral F {i} g + line_integral F {j} g" if \(k, g) \ one_chain_typeI\ \\A b B. ({} = (A::(real \ real) set) \ insert (b::real \ real) (B::(real \ real) set)) = (b \ A \ {} = A \ B)\ \finite ({} :: (real \ real) set)\ \\a A. finite (A::(real \ real) set) \ finite (insert (a::real \ real) A)\ \(i::real \ real) = (1::real, 0::real)\ \ \a A. (a::real \ real) \ (A::(real \ real) set) \ insert a A = A\ \j = (0, 1)\ \\x. (x::(real \ real) set) \ {} = {}\ \\y x A. insert (x::real \ real) (insert (y::real \ real) (A::(real \ real) set)) = insert y (insert x A)\ \\a A. insert (a::real \ real) (A::(real \ real) set) = {a} \ A\ \\F u basis2 basis1 \. finite (u :: (real \ real) set) \ line_integral_exists F basis1 \ \ line_integral_exists F basis2 \ \ basis1 \ basis2 = u \ basis1 \ basis2 = {} \ line_integral F u \ = line_integral F basis1 \ + line_integral F basis2 \\ \one_chain_line_integral F {i} one_chain_typeI = one_chain_line_integral F {i} one_chain_typeII \ (\(k, \)\one_chain_typeI. line_integral_exists F {i} \) \ (\(k, \)\one_chain_typeII. line_integral_exists F {i} \)\ \ one_chain_line_integral (F::real \ real \ real \ real) {j::real \ real} (one_chain_typeII::(int \ (real \ real \ real)) set) = one_chain_line_integral F {j} (one_chain_typeI::(int \ (real \ real \ real)) set) \ (\(k::int, \::real \ real \ real)\one_chain_typeII. line_integral_exists F {j} \) \ (\(k::int, \::real \ real \ real)\one_chain_typeI. line_integral_exists F {j} \)\ for F i j g one_chain_typeI one_chain_typeII and line_integral :: \(real \ real \ real \ real) \ (real \ real) set \ (real \ real \ real) \ real\ and line_integral_exists :: \(real \ real \ real \ real) \ (real \ real) set \ (real \ real \ real) \ bool\ and one_chain_line_integral :: \(real \ real \ real \ real) \ (real \ real) set \ (int \ (real \ real \ real)) set \ real\ and k using prod.case_eq_if singleton_inject snd_conv that by (smt (verit)) end lemma fixes x y z :: real assumes \x + 2 * y > 0\ and \x - 2 * y > 0\ and \x < 0\ shows False using assms by (smt (verit)) (*test for arith reconstruction*) lemma fixes d :: real assumes \0 < d\ \diamond_y \ \t. d / 2 - \t\\ \\a b c :: real. (a / c < b / c) = ((0 < c \ a < b) \ (c < 0 \ b < a) \ c \ 0)\ \\a b c :: real. (a / c < b / c) = ((0 < c \ a < b) \ (c < 0 \ b < a) \ c \ 0)\ \\a b :: real. - a / b = - (a / b)\ \\a b :: real. - a * b = - (a * b)\ \\(x1 :: real) x2 y1 y2 :: real. ((x1, x2) = (y1, y2)) = (x1 = y1 \ x2 = y2)\ shows \(\y. (d / 2, (2 * y - 1) * diamond_y (d / 2))) \ (\x. ((x - 1 / 2) * d, - diamond_y ((x - 1 / 2) * d))) \ (\y. (- (d / 2), (2 * y - 1) * diamond_y (- (d / 2)))) = (\x. ((x - 1 / 2) * d, diamond_y ((x - 1 / 2) * d))) \ False\ using assms by (smt (verit,del_insts)) lemma fixes d :: real assumes \0 < d\ \diamond_y \ \t. d / 2 - \t\\ \\a b c :: real. (a / c < b / c) = ((0 < c \ a < b) \ (c < 0 \ b < a) \ c \ 0)\ \\a b c :: real. (a / c < b / c) = ((0 < c \ a < b) \ (c < 0 \ b < a) \ c \ 0)\ \\a b :: real. - a / b = - (a / b)\ \\a b :: real. - a * b = - (a * b)\ \\(x1 :: real) x2 y1 y2 :: real. ((x1, x2) = (y1, y2)) = (x1 = y1 \ x2 = y2)\ shows \(\y. (d / 2, (2 * y - 1) * diamond_y (d / 2))) \ (\x. ((x - 1 / 2) * d, - diamond_y ((x - 1 / 2) * d))) \ (\y. (- (d / 2), (2 * y - 1) * diamond_y (- (d / 2)))) = (\x. ((x - 1 / 2) * d, diamond_y ((x - 1 / 2) * d))) \ False\ using assms by (smt (verit,ccfv_threshold)) (*qnt_rm_unused example*) lemma assumes \\z y x. P z y\ \P z y \ False\ shows False using assms by (smt (verit)) lemma "max (x::int) y \ y" supply [[smt_trace]] by (smt (verit))+ context begin abbreviation finite' :: "'a set \ bool" where "finite' A \ finite A \ A \ {}" lemma fixes f :: "'b \ 'c :: linorder" assumes \\(S::'b::type set) f::'b::type \ 'c::linorder. finite' S \ arg_min_on f S \ S\ \\(S::'a::type set) f::'a::type \ 'c::linorder. finite' S \ arg_min_on f S \ S\ \\(S::'b::type set) (y::'b::type) f::'b::type \ 'c::linorder. finite S \ S \ {} \ y \ S \ f (arg_min_on f S) \ f y\ \\(S::'a::type set) (y::'a::type) f::'a::type \ 'c::linorder. finite S \ S \ {} \ y \ S \ f (arg_min_on f S) \ f y\ \\(f::'b::type \ 'c::linorder) (g::'a::type \ 'b::type) x::'a::type. (f \ g) x = f (g x)\ \\(F::'b::type set) h::'b::type \ 'a::type. finite F \ finite (h ` F)\ \\(F::'b::type set) h::'b::type \ 'b::type. finite F \ finite (h ` F)\ \\(F::'a::type set) h::'a::type \ 'b::type. finite F \ finite (h ` F)\ \\(F::'a::type set) h::'a::type \ 'a::type. finite F \ finite (h ` F)\ \\(b::'a::type) (f::'b::type \ 'a::type) A::'b::type set. b \ f ` A \ (\x::'b::type. b = f x \ x \ A \ False) \ False\ \\(b::'b::type) (f::'b::type \ 'b::type) A::'b::type set. b \ f ` A \ (\x::'b::type. b = f x \ x \ A \ False) \ False\ \\(b::'b::type) (f::'a::type \ 'b::type) A::'a::type set. b \ f ` A \ (\x::'a::type. b = f x \ x \ A \ False) \ False\ \\(b::'a::type) (f::'a::type \ 'a::type) A::'a::type set. b \ f ` A \ (\x::'a::type. b = f x \ x \ A \ False) \ False\ \\(b::'a::type) (f::'b::type \ 'a::type) (x::'b::type) A::'b::type set. b = f x \ x \ A \ b \ f ` A \ \\(b::'b::type) (f::'b::type \ 'b::type) (x::'b::type) A::'b::type set. b = f x \ x \ A \ b \ f ` A \ \\(b::'b::type) (f::'a::type \ 'b::type) (x::'a::type) A::'a::type set. b = f x \ x \ A \ b \ f ` A \ \\(b::'a::type) (f::'a::type \ 'a::type) (x::'a::type) A::'a::type set. b = f x \ x \ A \ b \ f ` A \ \\(f::'b::type \ 'a::type) A::'b::type set. (f ` A = {}) = (A = {}) \ \\(f::'b::type \ 'b::type) A::'b::type set. (f ` A = {}) = (A = {}) \ \\(f::'a::type \ 'b::type) A::'a::type set. (f ` A = {}) = (A = {}) \ \\(f::'a::type \ 'a::type) A::'a::type set. (f ` A = {}) = (A = {}) \ \\(f::'b::type \ 'c::linorder) (A::'b::type set) (x::'b::type) y::'b::type. inj_on f A \ f x = f y \ x \ A \ y \ A \ x = y\ \\(x::'c::linorder) y::'c::linorder. (x < y) = (x \ y \ x \ y)\ \inj_on (f::'b::type \ 'c::linorder) ((g::'a::type \ 'b::type) ` (B::'a::type set))\ \finite (B::'a::type set)\ \(B::'a::type set) \ {}\ \arg_min_on ((f::'b::type \ 'c::linorder) \ (g::'a::type \ 'b::type)) (B::'a::type set) \ B\ \\x::'a::type. x \ (B::'a::type set) \ ((f::'b::type \ 'c::linorder) \ (g::'a::type \ 'b::type)) x < (f \ g) (arg_min_on (f \ g) B)\ \\(f::'b::type \ 'c::linorder) (P::'b::type \ bool) a::'b::type. inj_on f (Collect P) \ P a \ (\y::'b::type. P y \ f a \ f y) \ arg_min f P = a\ \\(S::'b::type set) f::'b::type \ 'c::linorder. finite' S \ arg_min_on f S \ S\ \\(S::'a::type set) f::'a::type \ 'c::linorder. finite' S \ arg_min_on f S \ S\ \\(S::'b::type set) (y::'b::type) f::'b::type \ 'c::linorder. finite S \ S \ {} \ y \ S \ f (arg_min_on f S) \ f y\ \\(S::'a::type set) (y::'a::type) f::'a::type \ 'c::linorder. finite S \ S \ {} \ y \ S \ f (arg_min_on f S) \ f y\ \\(f::'b::type \ 'c::linorder) (g::'a::type \ 'b::type) x::'a::type. (f \ g) x = f (g x)\ \\(F::'b::type set) h::'b::type \ 'a::type. finite F \ finite (h ` F)\ \\(F::'b::type set) h::'b::type \ 'b::type. finite F \ finite (h ` F)\ \\(F::'a::type set) h::'a::type \ 'b::type. finite F \ finite (h ` F)\ \\(F::'a::type set) h::'a::type \ 'a::type. finite F \ finite (h ` F)\ \\(b::'a::type) (f::'b::type \ 'a::type) A::'b::type set. b \ f ` A \ (\x::'b::type. b = f x \ x \ A \ False) \ False\ \\(b::'b::type) (f::'b::type \ 'b::type) A::'b::type set. b \ f ` A \ (\x::'b::type. b = f x \ x \ A \ False) \ False\ \\(b::'b::type) (f::'a::type \ 'b::type) A::'a::type set. b \ f ` A \ (\x::'a::type. b = f x \ x \ A \ False) \ False\ \\(b::'a::type) (f::'a::type \ 'a::type) A::'a::type set. b \ f ` A \ (\x::'a::type. b = f x \ x \ A \ False) \ False\ \\(b::'a::type) (f::'b::type \ 'a::type) (x::'b::type) A::'b::type set. b = f x \ x \ A \ b \ f ` A \ \\(b::'b::type) (f::'b::type \ 'b::type) (x::'b::type) A::'b::type set. b = f x \ x \ A \ b \ f ` A \ \\(b::'b::type) (f::'a::type \ 'b::type) (x::'a::type) A::'a::type set. b = f x \ x \ A \ b \ f ` A \ \\(b::'a::type) (f::'a::type \ 'a::type) (x::'a::type) A::'a::type set. b = f x \ x \ A \ b \ f ` A \ \\(f::'b::type \ 'a::type) A::'b::type set. (f ` A = {}) = (A = {}) \ \\(f::'b::type \ 'b::type) A::'b::type set. (f ` A = {}) = (A = {}) \ \\(f::'a::type \ 'b::type) A::'a::type set. (f ` A = {}) = (A = {}) \ \\(f::'a::type \ 'a::type) A::'a::type set. (f ` A = {}) = (A = {})\ \\(f::'b::type \ 'c::linorder) (A::'b::type set) (x::'b::type) y::'b::type. inj_on f A \ f x = f y \ x \ A \ y \ A \ x = y\ \\(x::'c::linorder) y::'c::linorder. (x < y) = (x \ y \ x \ y)\ \arg_min_on (f::'b::type \ 'c::linorder) ((g::'a::type \ 'b::type) ` (B::'a::type set)) \ g (arg_min_on (f \ g) B) \ shows False using assms by (smt (verit)) end experiment begin private datatype abort = Rtype_error | Rtimeout_error private datatype ('a) error_result = Rraise " 'a " \ \\ Should only be a value of type exn \\ | Rabort " abort " private datatype( 'a, 'b) result = Rval " 'a " | Rerr " ('b) error_result " lemma fixes clock :: \'astate \ nat\ and -fun_evaluate_match :: \'astate \ 'vsemv_env \ _ \ ('pat \ 'exp0) list \ _ \ + fun_evaluate_match :: \'astate \ 'vsemv_env \ _ \ ('pat \ 'exp0) list \ _ \ 'astate*((('v)list),('v))result\ assumes " fix_clock (st::'astate) (fun_evaluate st (env::'vsemv_env) [e::'exp0]) = (st'::'astate, r::('v list, 'v) result)" " clock (fst (fun_evaluate (st::'astate) (env::'vsemv_env) [e::'exp0])) \ clock st" "\(b::nat) (a::nat) c::nat. b \ a \ c \ b \ c \ a" "\(a::'astate) p::'astate \ ('v list, 'v) result. (a = fst p) = (\b::('v list, 'v) result. p = (a, b))" "\y::'v error_result. (\x1::'v. y = Rraise x1 \ False) \ (\x2::abort. y = Rabort x2 \ False) \ False" "\(f1::'v \ 'astate \ ('v list, 'v) result) (f2::abort \ 'astate \ ('v list, 'v) result) x1::'v. (case Rraise x1 of Rraise (x::'v) \ f1 x | Rabort (x::abort) \ f2 x) = f1 x1" " \(f1::'v \ 'astate \ ('v list, 'v) result) (f2::abort \ 'astate \ ('v list, 'v) result) x2::abort. (case Rabort x2 of Rraise (x::'v) \ f1 x | Rabort (x::abort) \ f2 x) = f2 x2" "\(s1::'astate) (s2::'astate) (x::('v list, 'v) result) s::'astate. fix_clock s1 (s2, x) = (s, x) \ clock s \ clock s2" "\(s::'astate) (s'::'astate) res::('v list, 'v) result. fix_clock s (s', res) = (update_clock (\_::nat. if clock s' \ clock s then clock s' else clock s) s', res)" "\(x2::'v error_result) x1::'v. (r::('v list, 'v) result) = Rerr x2 \ x2 = Rraise x1 \ clock (fst (fun_evaluate_match (st'::'astate) (env::'vsemv_env) x1 (pes::('pat \ 'exp0) list) x1)) \ clock st'" shows "((r::('v list, 'v) result) = Rerr (x2::'v error_result) \ clock (fst (case x2 of Rraise (v2::'v) \ fun_evaluate_match (st'::'astate) (env::'vsemv_env) v2 (pes::('pat \ 'exp0) list) v2 | Rabort (abort::abort) \ (st', Rerr (Rabort abort)))) \ clock (st::'astate)) " using assms by (smt (verit)) end context fixes piecewise_C1 :: "('real :: {one,zero,ord} \ 'a :: {one,zero,ord}) \ 'real set \ bool" and joinpaths :: "('real \ 'a) \ ('real \ 'a) \ 'real \ 'a" begin notation piecewise_C1 (infixr "piecewise'_C1'_differentiable'_on" 50) notation joinpaths (infixr "+++" 75) lemma \(\v1. \v0. (rec_join v0 = v1 \ (v0 = [] \ (\uu. 0) = v1 \ False) \ (\v2. v0 = [v2] \ v1 = coeff_cube_to_path v2 \ False) \ (\v2 v3 v4. v0 = v2 # v3 # v4 \ v1 = coeff_cube_to_path v2 +++ rec_join (v3 # v4) \ False) \ False) = (rec_join v0 = rec_join v0 \ (v0 = [] \ (\uu. 0) = rec_join v0 \ False) \ (\v2. v0 = [v2] \ rec_join v0 = coeff_cube_to_path v2 \ False) \ (\v2 v3 v4. v0 = v2 # v3 # v4 \ rec_join v0 = coeff_cube_to_path v2 +++ rec_join (v3 # v4) \ False) \ False)) \ (\v0 v1. rec_join v0 = v1 \ (v0 = [] \ (\uu. 0) = v1 \ False) \ (\v2. v0 = [v2] \ v1 = coeff_cube_to_path v2 \ False) \ (\v2 v3 v4. v0 = v2 # v3 # v4 \ v1 = coeff_cube_to_path v2 +++ rec_join (v3 # v4) \ False) \ False) = (\v0. rec_join v0 = rec_join v0 \ (v0 = [] \ (\uu. 0) = rec_join v0 \ False) \ (\v2. v0 = [v2] \ rec_join v0 = coeff_cube_to_path v2 \ False) \ (\v2 v3 v4. v0 = v2 # v3 # v4 \ rec_join v0 = coeff_cube_to_path v2 +++ rec_join (v3 # v4) \ False) \ False)\ by (smt (verit)) end section \Monomorphization examples\ definition Pred :: "'a \ bool" where "Pred x = True" lemma poly_Pred: "Pred x \ (Pred [x] \ \ Pred [x])" by (simp add: Pred_def) lemma "Pred (1::int)" by (smt (verit) poly_Pred) axiomatization g :: "'a \ nat" axiomatization where g1: "g (Some x) = g [x]" and g2: "g None = g []" and g3: "g xs = length xs" lemma "g (Some (3::int)) = g (Some True)" by (smt (verit) g1 g2 g3 list.size) end \ No newline at end of file diff --git a/src/HOL/SMT_Examples/SMT_Word_Examples.certs b/src/HOL/SMT_Examples/SMT_Word_Examples.certs --- a/src/HOL/SMT_Examples/SMT_Word_Examples.certs +++ b/src/HOL/SMT_Examples/SMT_Word_Examples.certs @@ -1,747 +1,365 @@ -8e6fd56de8adc20c29f4bdb8c2c55e63988185a8 8 0 -unsat -((set-logic ) -(proof -(let ((@x38 (monotonicity (rewrite (= (bvneg (_ bv5 4)) (_ bv11 4))) (= (= (_ bv11 4) (bvneg (_ bv5 4))) (= (_ bv11 4) (_ bv11 4)))))) -(let ((@x42 (trans @x38 (rewrite (= (= (_ bv11 4) (_ bv11 4)) true)) (= (= (_ bv11 4) (bvneg (_ bv5 4))) true)))) -(let ((@x49 (trans (monotonicity @x42 (= (not (= (_ bv11 4) (bvneg (_ bv5 4)))) (not true))) (rewrite (= (not true) false)) (= (not (= (_ bv11 4) (bvneg (_ bv5 4)))) false)))) -(mp (asserted (not (= (_ bv11 4) (bvneg (_ bv5 4))))) @x49 false)))))) - -aa1cdd144e99278cb2bdb51d68a75ec8d25b433d 7 0 +152f808e76881b6ae41a49c63654f988bc675b52 7 0 unsat ((set-logic ) (proof (let ((@x35 (monotonicity (rewrite (= (= (_ bv11 4) (_ bv11 4)) true)) (= (not (= (_ bv11 4) (_ bv11 4))) (not true))))) (let ((@x39 (trans @x35 (rewrite (= (not true) false)) (= (not (= (_ bv11 4) (_ bv11 4))) false)))) (mp (asserted (not (= (_ bv11 4) (_ bv11 4)))) @x39 false))))) -a14afea8a52a1586ff44eff03b88f1717144d17a 7 0 -unsat -((set-logic ) -(proof -(let ((@x38 (monotonicity (rewrite (= (bvult (_ bv23 8) (_ bv27 8)) true)) (= (not (bvult (_ bv23 8) (_ bv27 8))) (not true))))) -(let ((@x42 (trans @x38 (rewrite (= (not true) false)) (= (not (bvult (_ bv23 8) (_ bv27 8))) false)))) -(mp (asserted (not (bvult (_ bv23 8) (_ bv27 8)))) @x42 false))))) - -282d94be68c87485ea9ec13e80f6f2a51b18f5bd 9 0 -unsat -((set-logic ) -(proof -(let ((@x38 (monotonicity (rewrite (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5))) (= (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5)) (= (_ bv6 5) (_ bv6 5)))))) -(let ((@x42 (trans @x38 (rewrite (= (= (_ bv6 5) (_ bv6 5)) true)) (= (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5)) true)))) -(let ((@x45 (monotonicity @x42 (= (not (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5))) (not true))))) -(let ((@x49 (trans @x45 (rewrite (= (not true) false)) (= (not (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5))) false)))) -(mp (asserted (not (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5)))) @x49 false))))))) - -4df99826f79b2c96079a4c58ea51a58b8cc6199c 9 0 -unsat -((set-logic ) -(proof -(let ((@x38 (monotonicity (rewrite (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8))) (= (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8)) (= (_ bv21 8) (_ bv21 8)))))) -(let ((@x42 (trans @x38 (rewrite (= (= (_ bv21 8) (_ bv21 8)) true)) (= (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8)) true)))) -(let ((@x45 (monotonicity @x42 (= (not (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8))) (not true))))) -(let ((@x49 (trans @x45 (rewrite (= (not true) false)) (= (not (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8))) false)))) -(mp (asserted (not (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8)))) @x49 false))))))) - -45bf9e0a746f7dde46f8242e5851928c2671c7f2 9 0 -unsat -((set-logic ) -(proof -(let ((@x43 (monotonicity (rewrite (= (bvsub (_ bv11 8) (_ bv27 8)) (_ bv240 8))) (rewrite (= (bvneg (_ bv16 8)) (_ bv240 8))) (= (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8))) (= (_ bv240 8) (_ bv240 8)))))) -(let ((@x47 (trans @x43 (rewrite (= (= (_ bv240 8) (_ bv240 8)) true)) (= (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8))) true)))) -(let ((@x50 (monotonicity @x47 (= (not (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8)))) (not true))))) -(let ((@x54 (trans @x50 (rewrite (= (not true) false)) (= (not (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8)))) false)))) -(mp (asserted (not (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8))))) @x54 false))))))) - -6dd848d7b26e0521039e21a5e2bafebc1fee8c9b 7 0 -unsat -((set-logic ) -(proof -(let ((@x35 (monotonicity (rewrite (= (= (_ bv11 5) (_ bv11 5)) true)) (= (not (= (_ bv11 5) (_ bv11 5))) (not true))))) -(let ((@x39 (trans @x35 (rewrite (= (not true) false)) (= (not (= (_ bv11 5) (_ bv11 5))) false)))) -(mp (asserted (not (= (_ bv11 5) (_ bv11 5)))) @x39 false))))) - -00a7ff287d9c23d984163ea8e0cac8ac61008afd 11 0 -unsat -((set-logic ) -(proof -(let ((@x42 (monotonicity (rewrite (= (bvneg (_ bv40 7)) (_ bv88 7))) (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvadd (_ bv88 7) (_ bv1 7)))))) -(let ((@x47 (trans @x42 (rewrite (= (bvadd (_ bv88 7) (_ bv1 7)) (_ bv89 7))) (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (_ bv89 7))))) -(let ((@x52 (monotonicity @x47 (rewrite (= (bvneg (_ bv39 7)) (_ bv89 7))) (= (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7))) (= (_ bv89 7) (_ bv89 7)))))) -(let ((@x56 (trans @x52 (rewrite (= (= (_ bv89 7) (_ bv89 7)) true)) (= (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7))) true)))) -(let ((@x59 (monotonicity @x56 (= (not (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7)))) (not true))))) -(let ((@x63 (trans @x59 (rewrite (= (not true) false)) (= (not (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7)))) false)))) -(mp (asserted (not (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7))))) @x63 false))))))))) - -9673ca576ccae343db48aa68f876fd3a2515cc33 19 0 -unsat -((set-logic ) -(proof -(let ((?x35 (bvadd b$ c$))) -(let ((?x36 (bvadd ?x35 a$))) -(let ((?x30 (bvmul (_ bv2 32) b$))) -(let ((?x31 (bvadd a$ ?x30))) -(let ((?x33 (bvadd ?x31 c$))) -(let ((?x34 (bvsub ?x33 b$))) -(let (($x37 (= ?x34 ?x36))) -(let (($x38 (not $x37))) -(let ((@x58 (rewrite (= (= (bvadd a$ b$ c$) (bvadd a$ b$ c$)) true)))) -(let ((@x48 (rewrite (= (bvsub (bvadd a$ ?x30 c$) b$) (bvadd a$ b$ c$))))) -(let ((@x46 (monotonicity (rewrite (= ?x33 (bvadd a$ ?x30 c$))) (= ?x34 (bvsub (bvadd a$ ?x30 c$) b$))))) -(let ((@x56 (monotonicity (trans @x46 @x48 (= ?x34 (bvadd a$ b$ c$))) (rewrite (= ?x36 (bvadd a$ b$ c$))) (= $x37 (= (bvadd a$ b$ c$) (bvadd a$ b$ c$)))))) -(let ((@x63 (monotonicity (trans @x56 @x58 (= $x37 true)) (= $x38 (not true))))) -(let ((@x67 (trans @x63 (rewrite (= (not true) false)) (= $x38 false)))) -(mp (asserted $x38) @x67 false))))))))))))))))) - -b4600e6d14c88b633ac7bcc5b2e24af8539b0218 18 0 -unsat -((set-logic ) -(proof -(let ((?x31 (bvmul (_ bv4 4) x$))) -(let (($x32 (= ?x31 (_ bv4 4)))) -(let (($x43 (= (_ bv5 4) x$))) -(let (($x56 (not (or (not $x43) (= (_ bv4 4) ?x31))))) -(let ((@x48 (monotonicity (rewrite (= (= x$ (_ bv5 4)) $x43)) (= (not (= x$ (_ bv5 4))) (not $x43))))) -(let ((@x55 (monotonicity @x48 (rewrite (= $x32 (= (_ bv4 4) ?x31))) (= (or (not (= x$ (_ bv5 4))) $x32) (or (not $x43) (= (_ bv4 4) ?x31)))))) -(let (($x34 (not (=> (= x$ (_ bv5 4)) $x32)))) -(let ((@x39 (rewrite (= (=> (= x$ (_ bv5 4)) $x32) (or (not (= x$ (_ bv5 4))) $x32))))) -(let ((@x60 (trans (monotonicity @x39 (= $x34 (not (or (not (= x$ (_ bv5 4))) $x32)))) (monotonicity @x55 (= (not (or (not (= x$ (_ bv5 4))) $x32)) $x56)) (= $x34 $x56)))) -(let ((@x67 (monotonicity (not-or-elim (mp (asserted $x34) @x60 $x56) $x43) (= ?x31 (bvmul (_ bv4 4) (_ bv5 4)))))) -(let ((@x73 (monotonicity (trans @x67 (rewrite (= (bvmul (_ bv4 4) (_ bv5 4)) (_ bv4 4))) $x32) (= (= (_ bv4 4) ?x31) (= (_ bv4 4) (_ bv4 4)))))) -(let ((@x77 (trans @x73 (rewrite (= (= (_ bv4 4) (_ bv4 4)) true)) (= (= (_ bv4 4) ?x31) true)))) -(let ((@x84 (trans (monotonicity @x77 (= (not (= (_ bv4 4) ?x31)) (not true))) (rewrite (= (not true) false)) (= (not (= (_ bv4 4) ?x31)) false)))) -(mp (not-or-elim (mp (asserted $x34) @x60 $x56) (not (= (_ bv4 4) ?x31))) @x84 false)))))))))))))))) - -d150015a66b6757a72346710966844993c0f3c27 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32))) (= (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32)) (= (_ bv4 32) (_ bv4 32)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv4 32) (_ bv4 32)) true)) (= (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32))) false)))) -(mp (asserted (not (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32)))) @x48 false))))))) - -200e29aa9f19844d244c5c9755155eb956c5cf7c 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8))) (= (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8)) (= (_ bv7 8) (_ bv7 8)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv7 8) (_ bv7 8)) true)) (= (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8))) false)))) -(mp (asserted (not (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8)))) @x48 false))))))) - -d7cc0827eb340c29b0f489145022e4b3e3610818 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8))) (= (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8)) (= (_ bv15 8) (_ bv15 8)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv15 8) (_ bv15 8)) true)) (= (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8))) false)))) -(mp (asserted (not (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8)))) @x48 false))))))) - -3838eb33edcd292c3a0ecbf1662b54af3940189f 8 0 -unsat -((set-logic ) -(proof -(let ((@x36 (monotonicity (rewrite (= (bvnot (_ bv240 16)) (_ bv65295 16))) (= (= (bvnot (_ bv240 16)) (_ bv65295 16)) (= (_ bv65295 16) (_ bv65295 16)))))) -(let ((@x40 (trans @x36 (rewrite (= (= (_ bv65295 16) (_ bv65295 16)) true)) (= (= (bvnot (_ bv240 16)) (_ bv65295 16)) true)))) -(let ((@x47 (trans (monotonicity @x40 (= (not (= (bvnot (_ bv240 16)) (_ bv65295 16))) (not true))) (rewrite (= (not true) false)) (= (not (= (bvnot (_ bv240 16)) (_ bv65295 16))) false)))) -(mp (asserted (not (= (bvnot (_ bv240 16)) (_ bv65295 16)))) @x47 false)))))) - -14431ccb33137348161eb6ca6cfb2e57942c3f9d 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12))) (= (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12)) (= (_ bv2843 12) (_ bv2843 12)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv2843 12) (_ bv2843 12)) true)) (= (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12))) false)))) -(mp (asserted (not (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12)))) @x48 false))))))) - -880bee16a8f6469b14122277b92e87533ef6a071 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10))) (= (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10)) (= (_ bv207 10) (_ bv207 10)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv207 10) (_ bv207 10)) true)) (= (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10))) false)))) -(mp (asserted (not (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10)))) @x48 false))))))) - -b48f55cefc567df166d8e9967c53372c30620183 8 0 -unsat -((set-logic ) -(proof -(let ((@x36 (monotonicity (rewrite (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) (= (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)) (= (_ bv3 2) (_ bv3 2)))))) -(let ((@x40 (trans @x36 (rewrite (= (= (_ bv3 2) (_ bv3 2)) true)) (= (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)) true)))) -(let ((@x47 (trans (monotonicity @x40 (= (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) (not true))) (rewrite (= (not true) false)) (= (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) false)))) -(mp (asserted (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)))) @x47 false)))))) - -446b3cb9d63aa1f488dc092ed3fb111d2ad50b4e 9 0 -unsat -((set-logic ) -(proof -(let ((@x36 (monotonicity (rewrite (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10))) (= (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10)) (= (_ bv10 10) (_ bv10 10)))))) -(let ((@x40 (trans @x36 (rewrite (= (= (_ bv10 10) (_ bv10 10)) true)) (= (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10)) true)))) -(let ((@x43 (monotonicity @x40 (= (not (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10))) (not true))))) -(let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10))) false)))) -(mp (asserted (not (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10)))) @x47 false))))))) - -956d8b6229140c8c4aa869ab0f3765697ab8ff25 9 0 -unsat -((set-logic ) -(proof -(let ((@x36 (monotonicity (rewrite (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6))) (= (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6)) (= (_ bv58 6) (_ bv58 6)))))) -(let ((@x40 (trans @x36 (rewrite (= (= (_ bv58 6) (_ bv58 6)) true)) (= (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6)) true)))) -(let ((@x43 (monotonicity @x40 (= (not (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6))) (not true))))) -(let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6))) false)))) -(mp (asserted (not (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6)))) @x47 false))))))) - -24e98aaba1a95c03812c938201b3faa04d97c341 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8))) (= (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8)) (= (_ bv76 8) (_ bv76 8)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv76 8) (_ bv76 8)) true)) (= (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8))) false)))) -(mp (asserted (not (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8)))) @x48 false))))))) - -c13d08f3c98afca39a5c9317ed8ca7b7d4e35b5a 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8))) (= (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8)) (= (_ bv6 8) (_ bv6 8)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv6 8) (_ bv6 8)) true)) (= (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8))) false)))) -(mp (asserted (not (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8)))) @x48 false))))))) - -053f04ff749dbee44bfba8828181ab0a78473f75 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) (= (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)) (= (_ bv4 8) (_ bv4 8)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv4 8) (_ bv4 8)) true)) (= (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) false)))) -(mp (asserted (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)))) @x48 false))))))) - -42de7906f9755bf3d790213172b0ec7fab46237c 9 0 -unsat -((set-logic ) -(proof -(let ((@x36 (monotonicity (rewrite (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4))) (= (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4)) (= (_ bv9 4) (_ bv9 4)))))) -(let ((@x40 (trans @x36 (rewrite (= (= (_ bv9 4) (_ bv9 4)) true)) (= (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4)) true)))) -(let ((@x43 (monotonicity @x40 (= (not (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4))) (not true))))) -(let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4))) false)))) -(mp (asserted (not (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4)))) @x47 false))))))) - -6b83b0b418738896f8c64ad12f5670cb5bf96e0f 9 0 -unsat -((set-logic ) -(proof -(let ((@x36 (monotonicity (rewrite (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4))) (= (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4)) (= (_ bv13 4) (_ bv13 4)))))) -(let ((@x40 (trans @x36 (rewrite (= (= (_ bv13 4) (_ bv13 4)) true)) (= (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4)) true)))) -(let ((@x43 (monotonicity @x40 (= (not (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4))) (not true))))) -(let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4))) false)))) -(mp (asserted (not (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4)))) @x47 false))))))) - -5c4e275bed2d91897e820ccd6744b0a775a6e26e 17 0 -unsat -((set-logic ) -(proof -(let ((?x31 (bvand x$ (_ bv255 16)))) -(let ((?x29 (bvand x$ (_ bv65280 16)))) -(let ((?x32 (bvor ?x29 ?x31))) -(let (($x33 (= ?x32 x$))) -(let (($x34 (not $x33))) -(let ((@x59 (symm (commutativity (= (= x$ ?x32) $x33)) (= $x33 (= x$ ?x32))))) -(let ((@x35 (asserted $x34))) -(let ((@x63 (mp @x35 (monotonicity @x59 (= $x34 (not (= x$ ?x32)))) (not (= x$ ?x32))))) -(let (($x52 (= x$ ?x32))) -(let ((@x26 (true-axiom true))) -(let (($x53 (or $x52 false false false false false false false false false false false false false false false false))) -(let ((@x55 (unit-resolution ((_ th-lemma bv) $x53) @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 $x52))) -(unit-resolution @x55 @x63 false))))))))))))))) - -1d4a0e2a4449a8adbcf5a134bf7f2b0ee940d954 51 0 -unsat -((set-logic ) -(proof -(let ((?x31 (bvand w$ (_ bv255 16)))) -(let (($x32 (= ?x31 w$))) -(let (($x64 (not $x32))) -(let ((@x318 (symm (commutativity (= (= w$ ?x31) $x32)) (= $x32 (= w$ ?x31))))) -(let (($x57 (not (or (bvule (_ bv256 16) w$) $x32)))) -(let ((@x49 (monotonicity (rewrite (= (bvult w$ (_ bv256 16)) (not (bvule (_ bv256 16) w$)))) (= (not (bvult w$ (_ bv256 16))) (not (not (bvule (_ bv256 16) w$))))))) -(let ((@x53 (trans @x49 (rewrite (= (not (not (bvule (_ bv256 16) w$))) (bvule (_ bv256 16) w$))) (= (not (bvult w$ (_ bv256 16))) (bvule (_ bv256 16) w$))))) -(let ((@x56 (monotonicity @x53 (= (or (not (bvult w$ (_ bv256 16))) $x32) (or (bvule (_ bv256 16) w$) $x32))))) -(let ((@x59 (monotonicity @x56 (= (not (or (not (bvult w$ (_ bv256 16))) $x32)) $x57)))) -(let (($x34 (not (=> (bvult w$ (_ bv256 16)) $x32)))) -(let ((@x39 (rewrite (= (=> (bvult w$ (_ bv256 16)) $x32) (or (not (bvult w$ (_ bv256 16))) $x32))))) -(let ((@x42 (monotonicity @x39 (= $x34 (not (or (not (bvult w$ (_ bv256 16))) $x32)))))) -(let ((@x65 (not-or-elim (mp (asserted $x34) (trans @x42 @x59 (= $x34 $x57)) $x57) $x64))) -(let ((@x322 (mp @x65 (monotonicity @x318 (= $x64 (not (= w$ ?x31)))) (not (= w$ ?x31))))) -(let (($x300 (= w$ ?x31))) -(let (($x81 (= ((_ extract 15 15) w$) (_ bv1 1)))) -(let (($x264 (not $x81))) -(let (($x74 (= ((_ extract 8 8) w$) (_ bv1 1)))) -(let (($x75 (= ((_ extract 9 9) w$) (_ bv1 1)))) -(let (($x82 (and $x75 $x74))) -(let (($x83 (or $x75 $x74 $x82))) -(let (($x76 (= ((_ extract 10 10) w$) (_ bv1 1)))) -(let (($x84 (and $x76 $x83))) -(let (($x85 (or $x76 $x75 $x74 $x82 $x84))) -(let (($x77 (= ((_ extract 11 11) w$) (_ bv1 1)))) -(let (($x86 (and $x77 $x85))) -(let (($x87 (or $x77 $x76 $x75 $x74 $x82 $x84 $x86))) -(let (($x78 (= ((_ extract 12 12) w$) (_ bv1 1)))) -(let (($x88 (and $x78 $x87))) -(let (($x89 (or $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88))) -(let (($x79 (= ((_ extract 13 13) w$) (_ bv1 1)))) -(let (($x90 (and $x79 $x89))) -(let (($x91 (or $x79 $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88 $x90))) -(let (($x80 (= ((_ extract 14 14) w$) (_ bv1 1)))) -(let (($x92 (and $x80 $x91))) -(let (($x93 (or $x80 $x79 $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88 $x90 $x92))) -(let (($x94 (and $x81 $x93))) -(let (($x95 (or $x81 $x80 $x79 $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88 $x90 $x92 $x94))) -(let (($x297 (not $x95))) -(let (($x43 (bvule (_ bv256 16) w$))) -(let (($x44 (not $x43))) -(let ((@x63 (not-or-elim (mp (asserted $x34) (trans @x42 @x59 (= $x34 $x57)) $x57) $x44))) -(let ((@x303 (unit-resolution ((_ th-lemma bv) (or $x43 $x297)) @x63 $x297))) -(let ((@x26 (true-axiom true))) -(let (($x312 (or $x300 false false false false false false false false $x74 $x75 $x76 $x77 $x78 $x79 $x80 $x81))) -(let ((@x314 (unit-resolution ((_ th-lemma bv) $x312) @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 (unit-resolution (def-axiom (or $x95 (not $x74))) @x303 (not $x74)) (unit-resolution (def-axiom (or $x95 (not $x75))) @x303 (not $x75)) (unit-resolution (def-axiom (or $x95 (not $x76))) @x303 (not $x76)) (unit-resolution (def-axiom (or $x95 (not $x77))) @x303 (not $x77)) (unit-resolution (def-axiom (or $x95 (not $x78))) @x303 (not $x78)) (unit-resolution (def-axiom (or $x95 (not $x79))) @x303 (not $x79)) (unit-resolution (def-axiom (or $x95 (not $x80))) @x303 (not $x80)) (unit-resolution (def-axiom (or $x95 $x264)) @x303 $x264) $x300))) -(unit-resolution @x314 @x322 false))))))))))))))))))))))))))))))))))))))))))))))))) - -115ab22c9945d493b971e69a38d9e608c5b40a71 29 0 -unsat -((set-logic ) -(proof -(let ((?x28 (bv2int$ (_ bv0 2)))) -(let (($x183 (<= ?x28 0))) -(let (($x184 (not $x183))) -(let (($x175 (forall ((?v0 (_ BitVec 2)) )(! (let ((?x47 (bv2int$ ?v0))) -(let (($x53 (<= ?x47 0))) -(not $x53))) :pattern ( (bv2int$ ?v0) ) :qid k!9)) -)) -(let (($x57 (forall ((?v0 (_ BitVec 2)) )(! (let ((?x47 (bv2int$ ?v0))) -(let (($x53 (<= ?x47 0))) -(not $x53))) :qid k!9)) -)) -(let ((@x177 (refl (= (not (<= (bv2int$ ?0) 0)) (not (<= (bv2int$ ?0) 0)))))) -(let ((@x112 (refl (~ (not (<= (bv2int$ ?0) 0)) (not (<= (bv2int$ ?0) 0)))))) -(let (($x49 (forall ((?v0 (_ BitVec 2)) )(! (let ((?x47 (bv2int$ ?v0))) -(< 0 ?x47)) :qid k!9)) -)) -(let ((@x56 (rewrite (= (< 0 (bv2int$ ?0)) (not (<= (bv2int$ ?0) 0)))))) -(let ((@x115 (mp~ (mp (asserted $x49) (quant-intro @x56 (= $x49 $x57)) $x57) (nnf-pos @x112 (~ $x57 $x57)) $x57))) -(let ((@x180 (mp @x115 (quant-intro @x177 (= $x57 $x175)) $x175))) -(let (($x187 (not $x175))) -(let (($x188 (or $x187 $x184))) -(let ((@x189 ((_ quant-inst (_ bv0 2)) $x188))) -(let (($x29 (= ?x28 0))) -(let ((@x30 (asserted $x29))) -(unit-resolution ((_ th-lemma arith triangle-eq) (or (not $x29) $x183)) @x30 (unit-resolution @x189 @x180 $x184) false))))))))))))))))))) - -d14e7b8f0d1858316e700b4eb09e7d03e57cf9c3 16 0 -unsat -((set-logic ) -(proof -(let ((?x32 (p$ true))) -(let (($x29 (bvule (_ bv0 4) a$))) -(let (($x30 (ite $x29 true false))) -(let ((?x31 (p$ $x30))) -(let (($x33 (= ?x31 ?x32))) -(let (($x34 (not $x33))) -(let ((@x52 (monotonicity (monotonicity (rewrite (= $x29 true)) (= (p$ $x29) ?x32)) (= (= (p$ $x29) ?x32) (= ?x32 ?x32))))) -(let ((@x56 (trans @x52 (rewrite (= (= ?x32 ?x32) true)) (= (= (p$ $x29) ?x32) true)))) -(let ((@x63 (trans (monotonicity @x56 (= (not (= (p$ $x29) ?x32)) (not true))) (rewrite (= (not true) false)) (= (not (= (p$ $x29) ?x32)) false)))) -(let ((@x43 (monotonicity (monotonicity (rewrite (= $x30 $x29)) (= ?x31 (p$ $x29))) (= $x33 (= (p$ $x29) ?x32))))) -(let ((@x46 (monotonicity @x43 (= $x34 (not (= (p$ $x29) ?x32)))))) -(mp (asserted $x34) (trans @x46 @x63 (= $x34 false)) false)))))))))))))) - -6182523304a5597432fa1bb8dd16e804ddd8d7ee 12 0 -unsat -((set-logic ) -(proof -(let ((?x31 (p$ true))) -(let (($x29 (bvule (_ bv0 4) a$))) -(let ((?x30 (p$ $x29))) -(let (($x32 (= ?x30 ?x31))) -(let ((@x42 (monotonicity (monotonicity (rewrite (= $x29 true)) $x32) (= $x32 (= ?x31 ?x31))))) -(let ((@x49 (monotonicity (trans @x42 (rewrite (= (= ?x31 ?x31) true)) (= $x32 true)) (= (not $x32) (not true))))) -(let ((@x53 (trans @x49 (rewrite (= (not true) false)) (= (not $x32) false)))) -(mp (asserted (not $x32)) @x53 false)))))))))) - -9f7a96d88c6326ad836384c37d13934828ff726d 8 0 +9fbec967ab26119b905e134e9f6da22a94ff68aa 8 0 unsat ((set-logic ) (proof (let ((@x38 (monotonicity (rewrite (= (bvneg (_ bv5 4)) (_ bv11 4))) (= (= (_ bv11 4) (bvneg (_ bv5 4))) (= (_ bv11 4) (_ bv11 4)))))) (let ((@x42 (trans @x38 (rewrite (= (= (_ bv11 4) (_ bv11 4)) true)) (= (= (_ bv11 4) (bvneg (_ bv5 4))) true)))) (let ((@x49 (trans (monotonicity @x42 (= (not (= (_ bv11 4) (bvneg (_ bv5 4)))) (not true))) (rewrite (= (not true) false)) (= (not (= (_ bv11 4) (bvneg (_ bv5 4)))) false)))) (mp (asserted (not (= (_ bv11 4) (bvneg (_ bv5 4))))) @x49 false)))))) -6cad4ca9b92628993328e0c9cd5982fe4690567b 7 0 -unsat -((set-logic ) -(proof -(let ((@x35 (monotonicity (rewrite (= (= (_ bv11 4) (_ bv11 4)) true)) (= (not (= (_ bv11 4) (_ bv11 4))) (not true))))) -(let ((@x39 (trans @x35 (rewrite (= (not true) false)) (= (not (= (_ bv11 4) (_ bv11 4))) false)))) -(mp (asserted (not (= (_ bv11 4) (_ bv11 4)))) @x39 false))))) - 55b7bec34258b475381a754439390616488c924c 7 0 unsat ((set-logic ) (proof (let ((@x38 (monotonicity (rewrite (= (bvult (_ bv23 8) (_ bv27 8)) true)) (= (not (bvult (_ bv23 8) (_ bv27 8))) (not true))))) (let ((@x42 (trans @x38 (rewrite (= (not true) false)) (= (not (bvult (_ bv23 8) (_ bv27 8))) false)))) (mp (asserted (not (bvult (_ bv23 8) (_ bv27 8)))) @x42 false))))) fa462c1327b4231dc12d6f379b9bb280ea17bfd3 9 0 unsat ((set-logic ) (proof (let ((@x38 (monotonicity (rewrite (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5))) (= (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5)) (= (_ bv6 5) (_ bv6 5)))))) (let ((@x42 (trans @x38 (rewrite (= (= (_ bv6 5) (_ bv6 5)) true)) (= (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5)) true)))) (let ((@x45 (monotonicity @x42 (= (not (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5))) (not true))))) (let ((@x49 (trans @x45 (rewrite (= (not true) false)) (= (not (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5))) false)))) (mp (asserted (not (= (bvadd (_ bv27 5) (_ bv11 5)) (_ bv6 5)))) @x49 false))))))) bf6c2eb2daf9373dd063355969e25afc57fc44fe 9 0 unsat ((set-logic ) (proof (let ((@x38 (monotonicity (rewrite (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8))) (= (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8)) (= (_ bv21 8) (_ bv21 8)))))) (let ((@x42 (trans @x38 (rewrite (= (= (_ bv21 8) (_ bv21 8)) true)) (= (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8)) true)))) (let ((@x45 (monotonicity @x42 (= (not (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8))) (not true))))) (let ((@x49 (trans @x45 (rewrite (= (not true) false)) (= (not (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8))) false)))) (mp (asserted (not (= (bvmul (_ bv7 8) (_ bv3 8)) (_ bv21 8)))) @x49 false))))))) 21dcbc62e4a0d275653bc7c57a948d4bf6975168 9 0 unsat ((set-logic ) (proof (let ((@x43 (monotonicity (rewrite (= (bvsub (_ bv11 8) (_ bv27 8)) (_ bv240 8))) (rewrite (= (bvneg (_ bv16 8)) (_ bv240 8))) (= (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8))) (= (_ bv240 8) (_ bv240 8)))))) (let ((@x47 (trans @x43 (rewrite (= (= (_ bv240 8) (_ bv240 8)) true)) (= (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8))) true)))) (let ((@x50 (monotonicity @x47 (= (not (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8)))) (not true))))) (let ((@x54 (trans @x50 (rewrite (= (not true) false)) (= (not (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8)))) false)))) (mp (asserted (not (= (bvsub (_ bv11 8) (_ bv27 8)) (bvneg (_ bv16 8))))) @x54 false))))))) 6dd961e81bf75734a230f5a110b28edf98e90aaf 7 0 unsat ((set-logic ) (proof (let ((@x35 (monotonicity (rewrite (= (= (_ bv11 5) (_ bv11 5)) true)) (= (not (= (_ bv11 5) (_ bv11 5))) (not true))))) (let ((@x39 (trans @x35 (rewrite (= (not true) false)) (= (not (= (_ bv11 5) (_ bv11 5))) false)))) (mp (asserted (not (= (_ bv11 5) (_ bv11 5)))) @x39 false))))) 10d0fe43a5dca47373c59ffadf5d4a9049a8df88 11 0 unsat ((set-logic ) (proof (let ((@x42 (monotonicity (rewrite (= (bvneg (_ bv40 7)) (_ bv88 7))) (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvadd (_ bv88 7) (_ bv1 7)))))) (let ((@x47 (trans @x42 (rewrite (= (bvadd (_ bv88 7) (_ bv1 7)) (_ bv89 7))) (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (_ bv89 7))))) (let ((@x52 (monotonicity @x47 (rewrite (= (bvneg (_ bv39 7)) (_ bv89 7))) (= (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7))) (= (_ bv89 7) (_ bv89 7)))))) (let ((@x56 (trans @x52 (rewrite (= (= (_ bv89 7) (_ bv89 7)) true)) (= (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7))) true)))) (let ((@x59 (monotonicity @x56 (= (not (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7)))) (not true))))) (let ((@x63 (trans @x59 (rewrite (= (not true) false)) (= (not (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7)))) false)))) (mp (asserted (not (= (bvadd (bvneg (_ bv40 7)) (_ bv1 7)) (bvneg (_ bv39 7))))) @x63 false))))))))) de1bc26329091943d56ccf83cf9662c0b2001c97 19 0 unsat ((set-logic ) (proof (let ((?x35 (bvadd b$ c$))) (let ((?x36 (bvadd ?x35 a$))) (let ((?x30 (bvmul (_ bv2 32) b$))) (let ((?x31 (bvadd a$ ?x30))) (let ((?x33 (bvadd ?x31 c$))) (let ((?x34 (bvsub ?x33 b$))) (let (($x37 (= ?x34 ?x36))) (let (($x38 (not $x37))) (let ((@x58 (rewrite (= (= (bvadd a$ b$ c$) (bvadd a$ b$ c$)) true)))) (let ((@x48 (rewrite (= (bvsub (bvadd a$ ?x30 c$) b$) (bvadd a$ b$ c$))))) (let ((@x46 (monotonicity (rewrite (= ?x33 (bvadd a$ ?x30 c$))) (= ?x34 (bvsub (bvadd a$ ?x30 c$) b$))))) (let ((@x56 (monotonicity (trans @x46 @x48 (= ?x34 (bvadd a$ b$ c$))) (rewrite (= ?x36 (bvadd a$ b$ c$))) (= $x37 (= (bvadd a$ b$ c$) (bvadd a$ b$ c$)))))) (let ((@x63 (monotonicity (trans @x56 @x58 (= $x37 true)) (= $x38 (not true))))) (let ((@x67 (trans @x63 (rewrite (= (not true) false)) (= $x38 false)))) (mp (asserted $x38) @x67 false))))))))))))))))) 821acdf5acf235899fac29bcb5ad69c40cffe88f 18 0 unsat ((set-logic ) (proof (let ((?x31 (bvmul (_ bv4 4) x$))) (let (($x32 (= ?x31 (_ bv4 4)))) (let (($x43 (= (_ bv5 4) x$))) (let (($x56 (not (or (not $x43) (= (_ bv4 4) ?x31))))) (let ((@x48 (monotonicity (rewrite (= (= x$ (_ bv5 4)) $x43)) (= (not (= x$ (_ bv5 4))) (not $x43))))) (let ((@x55 (monotonicity @x48 (rewrite (= $x32 (= (_ bv4 4) ?x31))) (= (or (not (= x$ (_ bv5 4))) $x32) (or (not $x43) (= (_ bv4 4) ?x31)))))) (let (($x34 (not (=> (= x$ (_ bv5 4)) $x32)))) (let ((@x39 (rewrite (= (=> (= x$ (_ bv5 4)) $x32) (or (not (= x$ (_ bv5 4))) $x32))))) (let ((@x60 (trans (monotonicity @x39 (= $x34 (not (or (not (= x$ (_ bv5 4))) $x32)))) (monotonicity @x55 (= (not (or (not (= x$ (_ bv5 4))) $x32)) $x56)) (= $x34 $x56)))) (let ((@x67 (monotonicity (not-or-elim (mp (asserted $x34) @x60 $x56) $x43) (= ?x31 (bvmul (_ bv4 4) (_ bv5 4)))))) (let ((@x73 (monotonicity (trans @x67 (rewrite (= (bvmul (_ bv4 4) (_ bv5 4)) (_ bv4 4))) $x32) (= (= (_ bv4 4) ?x31) (= (_ bv4 4) (_ bv4 4)))))) (let ((@x77 (trans @x73 (rewrite (= (= (_ bv4 4) (_ bv4 4)) true)) (= (= (_ bv4 4) ?x31) true)))) (let ((@x84 (trans (monotonicity @x77 (= (not (= (_ bv4 4) ?x31)) (not true))) (rewrite (= (not true) false)) (= (not (= (_ bv4 4) ?x31)) false)))) (mp (not-or-elim (mp (asserted $x34) @x60 $x56) (not (= (_ bv4 4) ?x31))) @x84 false)))))))))))))))) fb4d74278af64850ed8084451a8ff7a7075dbdfe 9 0 unsat ((set-logic ) (proof (let ((@x37 (monotonicity (rewrite (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32))) (= (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32)) (= (_ bv4 32) (_ bv4 32)))))) (let ((@x41 (trans @x37 (rewrite (= (= (_ bv4 32) (_ bv4 32)) true)) (= (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32)) true)))) (let ((@x44 (monotonicity @x41 (= (not (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32))) (not true))))) (let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32))) false)))) (mp (asserted (not (= (bvand (_ bv6 32) (_ bv5 32)) (_ bv4 32)))) @x48 false))))))) 5a9d6d65605763b3b0286a0d4717a93a4da85a34 9 0 unsat ((set-logic ) (proof (let ((@x37 (monotonicity (rewrite (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8))) (= (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8)) (= (_ bv7 8) (_ bv7 8)))))) (let ((@x41 (trans @x37 (rewrite (= (= (_ bv7 8) (_ bv7 8)) true)) (= (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8)) true)))) (let ((@x44 (monotonicity @x41 (= (not (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8))) (not true))))) (let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8))) false)))) (mp (asserted (not (= (bvor (_ bv6 8) (_ bv3 8)) (_ bv7 8)))) @x48 false))))))) 71f993d99975ef37af8d8478a6f1c26548b6f4a7 9 0 unsat ((set-logic ) (proof (let ((@x37 (monotonicity (rewrite (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8))) (= (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8)) (= (_ bv15 8) (_ bv15 8)))))) (let ((@x41 (trans @x37 (rewrite (= (= (_ bv15 8) (_ bv15 8)) true)) (= (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8)) true)))) (let ((@x44 (monotonicity @x41 (= (not (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8))) (not true))))) (let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8))) false)))) (mp (asserted (not (= (bvxor (_ bv240 8) (_ bv255 8)) (_ bv15 8)))) @x48 false))))))) 353b2591bd8c22d0df29b19faf56739aac7b9b6d 8 0 unsat ((set-logic ) (proof (let ((@x36 (monotonicity (rewrite (= (bvnot (_ bv240 16)) (_ bv65295 16))) (= (= (bvnot (_ bv240 16)) (_ bv65295 16)) (= (_ bv65295 16) (_ bv65295 16)))))) (let ((@x40 (trans @x36 (rewrite (= (= (_ bv65295 16) (_ bv65295 16)) true)) (= (= (bvnot (_ bv240 16)) (_ bv65295 16)) true)))) (let ((@x47 (trans (monotonicity @x40 (= (not (= (bvnot (_ bv240 16)) (_ bv65295 16))) (not true))) (rewrite (= (not true) false)) (= (not (= (bvnot (_ bv240 16)) (_ bv65295 16))) false)))) (mp (asserted (not (= (bvnot (_ bv240 16)) (_ bv65295 16)))) @x47 false)))))) -f40271ef9e5c8b600036568090a9c30a30fba3c1 9 0 +88af7aeb0e9a24cb60cf70ebed32fe4a6b94a809 9 0 unsat ((set-logic ) (proof (let ((@x37 (monotonicity (rewrite (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12))) (= (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12)) (= (_ bv2843 12) (_ bv2843 12)))))) (let ((@x41 (trans @x37 (rewrite (= (= (_ bv2843 12) (_ bv2843 12)) true)) (= (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12)) true)))) (let ((@x44 (monotonicity @x41 (= (not (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12))) (not true))))) (let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12))) false)))) (mp (asserted (not (= (concat (_ bv11 4) (_ bv27 8)) (_ bv2843 12)))) @x48 false))))))) 98fd1bf6fea1dce9107b6a84cfa810d8ae0827ad 9 0 unsat ((set-logic ) (proof (let ((@x37 (monotonicity (rewrite (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10))) (= (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10)) (= (_ bv207 10) (_ bv207 10)))))) (let ((@x41 (trans @x37 (rewrite (= (= (_ bv207 10) (_ bv207 10)) true)) (= (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10)) true)))) (let ((@x44 (monotonicity @x41 (= (not (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10))) (not true))))) (let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10))) false)))) (mp (asserted (not (= (concat (_ bv3 4) (_ bv15 6)) (_ bv207 10)))) @x48 false))))))) -f5796d75c7b1d8ea9a2c70c40ab57315660fbcf3 8 0 -unsat -((set-logic ) -(proof -(let ((@x36 (monotonicity (rewrite (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) (= (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)) (= (_ bv3 2) (_ bv3 2)))))) -(let ((@x40 (trans @x36 (rewrite (= (= (_ bv3 2) (_ bv3 2)) true)) (= (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)) true)))) -(let ((@x47 (trans (monotonicity @x40 (= (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) (not true))) (rewrite (= (not true) false)) (= (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) false)))) -(mp (asserted (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)))) @x47 false)))))) - 44630a6139544aa8cc936f2dcdd464d5967b2876 9 0 unsat ((set-logic ) (proof (let ((@x36 (monotonicity (rewrite (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10))) (= (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10)) (= (_ bv10 10) (_ bv10 10)))))) (let ((@x40 (trans @x36 (rewrite (= (= (_ bv10 10) (_ bv10 10)) true)) (= (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10)) true)))) (let ((@x43 (monotonicity @x40 (= (not (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10))) (not true))))) (let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10))) false)))) (mp (asserted (not (= ((_ zero_extend 6) (_ bv10 4)) (_ bv10 10)))) @x47 false))))))) +36033c98ec9d88c28e82a4d5b423281f56a42859 8 0 +unsat +((set-logic ) +(proof +(let ((@x36 (monotonicity (rewrite (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) (= (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)) (= (_ bv3 2) (_ bv3 2)))))) +(let ((@x40 (trans @x36 (rewrite (= (= (_ bv3 2) (_ bv3 2)) true)) (= (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)) true)))) +(let ((@x47 (trans (monotonicity @x40 (= (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) (not true))) (rewrite (= (not true) false)) (= (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2))) false)))) +(mp (asserted (not (= ((_ extract 2 1) (_ bv6 4)) (_ bv3 2)))) @x47 false)))))) + 2b91c33c03a89b80ac6fb984f384bd9814c2b51d 9 0 unsat ((set-logic ) (proof (let ((@x36 (monotonicity (rewrite (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6))) (= (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6)) (= (_ bv58 6) (_ bv58 6)))))) (let ((@x40 (trans @x36 (rewrite (= (= (_ bv58 6) (_ bv58 6)) true)) (= (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6)) true)))) (let ((@x43 (monotonicity @x40 (= (not (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6))) (not true))))) (let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6))) false)))) (mp (asserted (not (= ((_ sign_extend 2) (_ bv10 4)) (_ bv58 6)))) @x47 false))))))) 80e93d77c56b62b509cae750a834ba3c2a6545e3 9 0 unsat ((set-logic ) (proof (let ((@x37 (monotonicity (rewrite (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8))) (= (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8)) (= (_ bv76 8) (_ bv76 8)))))) (let ((@x41 (trans @x37 (rewrite (= (= (_ bv76 8) (_ bv76 8)) true)) (= (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8)) true)))) (let ((@x44 (monotonicity @x41 (= (not (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8))) (not true))))) (let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8))) false)))) (mp (asserted (not (= (bvshl (_ bv19 8) (_ bv2 8)) (_ bv76 8)))) @x48 false))))))) 08e3a62c0a330f1ab742b05e694f723668925d10 9 0 unsat ((set-logic ) (proof (let ((@x37 (monotonicity (rewrite (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8))) (= (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8)) (= (_ bv6 8) (_ bv6 8)))))) (let ((@x41 (trans @x37 (rewrite (= (= (_ bv6 8) (_ bv6 8)) true)) (= (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8)) true)))) (let ((@x44 (monotonicity @x41 (= (not (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8))) (not true))))) (let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8))) false)))) (mp (asserted (not (= (bvlshr (_ bv25 8) (_ bv2 8)) (_ bv6 8)))) @x48 false))))))) +d1e9761fb935892f82a21268d39aac76f75ee282 9 0 +unsat +((set-logic ) +(proof +(let ((@x37 (monotonicity (rewrite (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) (= (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)) (= (_ bv4 8) (_ bv4 8)))))) +(let ((@x41 (trans @x37 (rewrite (= (= (_ bv4 8) (_ bv4 8)) true)) (= (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)) true)))) +(let ((@x44 (monotonicity @x41 (= (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) (not true))))) +(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) false)))) +(mp (asserted (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)))) @x48 false))))))) + 1b01af1c33961b4a329d46a526471313f71130ca 9 0 unsat ((set-logic ) (proof (let ((@x36 (monotonicity (rewrite (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4))) (= (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4)) (= (_ bv9 4) (_ bv9 4)))))) (let ((@x40 (trans @x36 (rewrite (= (= (_ bv9 4) (_ bv9 4)) true)) (= (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4)) true)))) (let ((@x43 (monotonicity @x40 (= (not (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4))) (not true))))) (let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4))) false)))) (mp (asserted (not (= ((_ rotate_right 2) (_ bv6 4)) (_ bv9 4)))) @x47 false))))))) -d1e9761fb935892f82a21268d39aac76f75ee282 9 0 -unsat -((set-logic ) -(proof -(let ((@x37 (monotonicity (rewrite (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) (= (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)) (= (_ bv4 8) (_ bv4 8)))))) -(let ((@x41 (trans @x37 (rewrite (= (= (_ bv4 8) (_ bv4 8)) true)) (= (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)) true)))) -(let ((@x44 (monotonicity @x41 (= (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) (not true))))) -(let ((@x48 (trans @x44 (rewrite (= (not true) false)) (= (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8))) false)))) -(mp (asserted (not (= (bvashr (_ bv19 8) (_ bv2 8)) (_ bv4 8)))) @x48 false))))))) - a14e30a88e731b5e605d4726dbb1f583497ab894 9 0 unsat ((set-logic ) (proof (let ((@x36 (monotonicity (rewrite (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4))) (= (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4)) (= (_ bv13 4) (_ bv13 4)))))) (let ((@x40 (trans @x36 (rewrite (= (= (_ bv13 4) (_ bv13 4)) true)) (= (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4)) true)))) (let ((@x43 (monotonicity @x40 (= (not (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4))) (not true))))) (let ((@x47 (trans @x43 (rewrite (= (not true) false)) (= (not (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4))) false)))) (mp (asserted (not (= ((_ rotate_left 1) (_ bv14 4)) (_ bv13 4)))) @x47 false))))))) 08dd0af4f9cea470363f78957650260a900928c8 17 0 unsat ((set-logic ) (proof (let ((?x31 (bvand x$ (_ bv255 16)))) (let ((?x29 (bvand x$ (_ bv65280 16)))) (let ((?x32 (bvor ?x29 ?x31))) (let (($x33 (= ?x32 x$))) (let (($x34 (not $x33))) (let ((@x59 (symm (commutativity (= (= x$ ?x32) $x33)) (= $x33 (= x$ ?x32))))) (let ((@x35 (asserted $x34))) (let ((@x63 (mp @x35 (monotonicity @x59 (= $x34 (not (= x$ ?x32)))) (not (= x$ ?x32))))) (let (($x52 (= x$ ?x32))) (let ((@x26 (true-axiom true))) (let (($x53 (or $x52 false false false false false false false false false false false false false false false false))) (let ((@x55 (unit-resolution ((_ th-lemma bv) $x53) @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 $x52))) (unit-resolution @x55 @x63 false))))))))))))))) cffe711faa89f3f62e8e8e58173aaeb3cedc5d63 51 0 unsat ((set-logic ) (proof (let ((?x31 (bvand w$ (_ bv255 16)))) (let (($x32 (= ?x31 w$))) (let (($x64 (not $x32))) (let ((@x318 (symm (commutativity (= (= w$ ?x31) $x32)) (= $x32 (= w$ ?x31))))) (let (($x57 (not (or (bvule (_ bv256 16) w$) $x32)))) (let ((@x49 (monotonicity (rewrite (= (bvult w$ (_ bv256 16)) (not (bvule (_ bv256 16) w$)))) (= (not (bvult w$ (_ bv256 16))) (not (not (bvule (_ bv256 16) w$))))))) (let ((@x53 (trans @x49 (rewrite (= (not (not (bvule (_ bv256 16) w$))) (bvule (_ bv256 16) w$))) (= (not (bvult w$ (_ bv256 16))) (bvule (_ bv256 16) w$))))) (let ((@x56 (monotonicity @x53 (= (or (not (bvult w$ (_ bv256 16))) $x32) (or (bvule (_ bv256 16) w$) $x32))))) (let ((@x59 (monotonicity @x56 (= (not (or (not (bvult w$ (_ bv256 16))) $x32)) $x57)))) (let (($x34 (not (=> (bvult w$ (_ bv256 16)) $x32)))) (let ((@x39 (rewrite (= (=> (bvult w$ (_ bv256 16)) $x32) (or (not (bvult w$ (_ bv256 16))) $x32))))) (let ((@x42 (monotonicity @x39 (= $x34 (not (or (not (bvult w$ (_ bv256 16))) $x32)))))) (let ((@x65 (not-or-elim (mp (asserted $x34) (trans @x42 @x59 (= $x34 $x57)) $x57) $x64))) (let ((@x322 (mp @x65 (monotonicity @x318 (= $x64 (not (= w$ ?x31)))) (not (= w$ ?x31))))) (let (($x300 (= w$ ?x31))) (let (($x81 (= ((_ extract 15 15) w$) (_ bv1 1)))) (let (($x264 (not $x81))) (let (($x74 (= ((_ extract 8 8) w$) (_ bv1 1)))) (let (($x75 (= ((_ extract 9 9) w$) (_ bv1 1)))) (let (($x82 (and $x75 $x74))) (let (($x83 (or $x75 $x74 $x82))) (let (($x76 (= ((_ extract 10 10) w$) (_ bv1 1)))) (let (($x84 (and $x76 $x83))) (let (($x85 (or $x76 $x75 $x74 $x82 $x84))) (let (($x77 (= ((_ extract 11 11) w$) (_ bv1 1)))) (let (($x86 (and $x77 $x85))) (let (($x87 (or $x77 $x76 $x75 $x74 $x82 $x84 $x86))) (let (($x78 (= ((_ extract 12 12) w$) (_ bv1 1)))) (let (($x88 (and $x78 $x87))) (let (($x89 (or $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88))) (let (($x79 (= ((_ extract 13 13) w$) (_ bv1 1)))) (let (($x90 (and $x79 $x89))) (let (($x91 (or $x79 $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88 $x90))) (let (($x80 (= ((_ extract 14 14) w$) (_ bv1 1)))) (let (($x92 (and $x80 $x91))) (let (($x93 (or $x80 $x79 $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88 $x90 $x92))) (let (($x94 (and $x81 $x93))) (let (($x95 (or $x81 $x80 $x79 $x78 $x77 $x76 $x75 $x74 $x82 $x84 $x86 $x88 $x90 $x92 $x94))) (let (($x297 (not $x95))) (let (($x43 (bvule (_ bv256 16) w$))) (let (($x44 (not $x43))) (let ((@x63 (not-or-elim (mp (asserted $x34) (trans @x42 @x59 (= $x34 $x57)) $x57) $x44))) (let ((@x303 (unit-resolution ((_ th-lemma bv) (or $x43 $x297)) @x63 $x297))) (let ((@x26 (true-axiom true))) (let (($x312 (or $x300 false false false false false false false false $x74 $x75 $x76 $x77 $x78 $x79 $x80 $x81))) (let ((@x314 (unit-resolution ((_ th-lemma bv) $x312) @x26 @x26 @x26 @x26 @x26 @x26 @x26 @x26 (unit-resolution (def-axiom (or $x95 (not $x74))) @x303 (not $x74)) (unit-resolution (def-axiom (or $x95 (not $x75))) @x303 (not $x75)) (unit-resolution (def-axiom (or $x95 (not $x76))) @x303 (not $x76)) (unit-resolution (def-axiom (or $x95 (not $x77))) @x303 (not $x77)) (unit-resolution (def-axiom (or $x95 (not $x78))) @x303 (not $x78)) (unit-resolution (def-axiom (or $x95 (not $x79))) @x303 (not $x79)) (unit-resolution (def-axiom (or $x95 (not $x80))) @x303 (not $x80)) (unit-resolution (def-axiom (or $x95 $x264)) @x303 $x264) $x300))) (unit-resolution @x314 @x322 false))))))))))))))))))))))))))))))))))))))))))))))))) 024e51ae2c856c79195e59dfbc39c68dcf8ab939 29 0 unsat ((set-logic ) (proof (let ((?x28 (bv2int$ (_ bv0 2)))) (let (($x183 (<= ?x28 0))) (let (($x184 (not $x183))) (let (($x175 (forall ((?v0 (_ BitVec 2)) )(! (let ((?x47 (bv2int$ ?v0))) (let (($x53 (<= ?x47 0))) (not $x53))) :pattern ( (bv2int$ ?v0) ) :qid k!9)) )) (let (($x57 (forall ((?v0 (_ BitVec 2)) )(! (let ((?x47 (bv2int$ ?v0))) (let (($x53 (<= ?x47 0))) (not $x53))) :qid k!9)) )) (let ((@x177 (refl (= (not (<= (bv2int$ ?0) 0)) (not (<= (bv2int$ ?0) 0)))))) (let ((@x112 (refl (~ (not (<= (bv2int$ ?0) 0)) (not (<= (bv2int$ ?0) 0)))))) (let (($x49 (forall ((?v0 (_ BitVec 2)) )(! (let ((?x47 (bv2int$ ?v0))) (< 0 ?x47)) :qid k!9)) )) (let ((@x56 (rewrite (= (< 0 (bv2int$ ?0)) (not (<= (bv2int$ ?0) 0)))))) (let ((@x115 (mp~ (mp (asserted $x49) (quant-intro @x56 (= $x49 $x57)) $x57) (nnf-pos @x112 (~ $x57 $x57)) $x57))) (let ((@x180 (mp @x115 (quant-intro @x177 (= $x57 $x175)) $x175))) (let (($x187 (not $x175))) (let (($x188 (or $x187 $x184))) (let ((@x189 ((_ quant-inst (_ bv0 2)) $x188))) (let (($x29 (= ?x28 0))) (let ((@x30 (asserted $x29))) (unit-resolution ((_ th-lemma arith triangle-eq) (or (not $x29) $x183)) @x30 (unit-resolution @x189 @x180 $x184) false))))))))))))))))))) 20245d49b4c03da63c3124c5910beafc837f359a 12 0 unsat ((set-logic ) (proof (let ((?x31 (p$ true))) (let (($x29 (bvule (_ bv0 4) a$))) (let ((?x30 (p$ $x29))) (let (($x32 (= ?x30 ?x31))) (let ((@x42 (monotonicity (monotonicity (rewrite (= $x29 true)) $x32) (= $x32 (= ?x31 ?x31))))) (let ((@x49 (monotonicity (trans @x42 (rewrite (= (= ?x31 ?x31) true)) (= $x32 true)) (= (not $x32) (not true))))) (let ((@x53 (trans @x49 (rewrite (= (not true) false)) (= (not $x32) false)))) (mp (asserted (not $x32)) @x53 false)))))))))) diff --git a/src/HOL/Tools/SMT/smt_config.ML b/src/HOL/Tools/SMT/smt_config.ML --- a/src/HOL/Tools/SMT/smt_config.ML +++ b/src/HOL/Tools/SMT/smt_config.ML @@ -1,287 +1,287 @@ (* Title: HOL/Tools/SMT/smt_config.ML Author: Sascha Boehme, TU Muenchen Configuration options and diagnostic tools for SMT. *) signature SMT_CONFIG = sig (*solver*) type solver_info = { name: string, class: Proof.context -> SMT_Util.class, avail: unit -> bool, options: Proof.context -> string list } val add_solver: solver_info -> Context.generic -> Context.generic val set_solver_options: string * string -> Context.generic -> Context.generic val is_available: Proof.context -> string -> bool val available_solvers_of: Proof.context -> string list val select_solver: string -> Context.generic -> Context.generic val solver_of: Proof.context -> string val solver_class_of: Proof.context -> SMT_Util.class val solver_options_of: Proof.context -> string list (*options*) val oracle: bool Config.T val timeout: real Config.T val reconstruction_step_timeout: real Config.T val random_seed: int Config.T val read_only_certificates: bool Config.T val verbose: bool Config.T val trace: bool Config.T val statistics: bool Config.T val monomorph_limit: int Config.T val monomorph_instances: int Config.T val explicit_application: int Config.T val higher_order: bool Config.T val nat_as_int: bool Config.T val infer_triggers: bool Config.T val debug_files: string Config.T val sat_solver: string Config.T val compress_verit_proofs: Proof.context -> bool (*tools*) val with_time_limit: Proof.context -> real Config.T -> ('a -> 'b) -> 'a -> 'b val with_timeout: Proof.context -> ('a -> 'b) -> 'a -> 'b (*diagnostics*) val trace_msg: Proof.context -> ('a -> string) -> 'a -> unit val verbose_msg: Proof.context -> ('a -> string) -> 'a -> unit val statistics_msg: Proof.context -> ('a -> string) -> 'a -> unit val verit_msg: Proof.context -> (unit -> 'a) -> unit val verit_arith_msg: Proof.context -> (unit -> 'a) -> unit val spy_verit: Proof.context -> bool val spy_Z3: Proof.context -> bool (*certificates*) val select_certificates: string -> Context.generic -> Context.generic val certificates_of: Proof.context -> Cache_IO.cache option (*setup*) val print_setup: Proof.context -> unit end; structure SMT_Config: SMT_CONFIG = struct (* solver *) type solver_info = { name: string, class: Proof.context -> SMT_Util.class, avail: unit -> bool, options: Proof.context -> string list} type data = { solvers: (solver_info * string list) Symtab.table, solver: string option, certs: Cache_IO.cache option} fun mk_data solvers solver certs: data = {solvers=solvers, solver=solver, certs=certs} val empty_data = mk_data Symtab.empty NONE NONE fun solvers_of ({solvers, ...}: data) = solvers fun solver_of ({solver, ...}: data) = solver fun certs_of ({certs, ...}: data) = certs fun map_solvers f ({solvers, solver, certs}: data) = mk_data (f solvers) solver certs fun map_solver f ({solvers, solver, certs}: data) = mk_data solvers (f solver) certs fun put_certs c ({solvers, solver, ...}: data) = mk_data solvers solver c fun merge_data ({solvers=ss1,solver=s1,certs=c1}: data, {solvers=ss2,solver=s2,certs=c2}: data) = mk_data (Symtab.merge (K true) (ss1, ss2)) (merge_options (s1, s2)) (merge_options (c1, c2)) structure Data = Generic_Data ( type T = data val empty = empty_data val extend = I val merge = merge_data ) fun set_solver_options (name, options) = let val opts = String.tokens (Symbol.is_ascii_blank o str) options in Data.map (map_solvers (Symtab.map_entry name (apsnd (K opts)))) end fun add_solver (info as {name, ...} : solver_info) context = if Symtab.defined (solvers_of (Data.get context)) name then error ("Solver already registered: " ^ quote name) else context |> Data.map (map_solvers (Symtab.update (name, (info, [])))) |> Context.map_theory (Attrib.setup (Binding.name (name ^ "_options")) (Scan.lift (\<^keyword>\=\ |-- Args.name) >> (Thm.declaration_attribute o K o set_solver_options o pair name)) ("additional command line options for SMT solver " ^ quote name)) fun all_solvers_of ctxt = Symtab.keys (solvers_of (Data.get (Context.Proof ctxt))) fun solver_name_of ctxt = solver_of (Data.get (Context.Proof ctxt)) fun is_available ctxt name = (case Symtab.lookup (solvers_of (Data.get (Context.Proof ctxt))) name of SOME ({avail, ...}, _) => avail () | NONE => false) fun available_solvers_of ctxt = filter (is_available ctxt) (all_solvers_of ctxt) fun warn_solver (Context.Proof ctxt) name = if Context_Position.is_visible ctxt then warning ("The SMT solver " ^ quote name ^ " is not installed") else () | warn_solver _ _ = () fun select_solver name context = let val ctxt = Context.proof_of context val upd = Data.map (map_solver (K (SOME name))) in if not (member (op =) (all_solvers_of ctxt) name) then error ("Trying to select unknown solver: " ^ quote name) else if not (is_available ctxt name) then (warn_solver context name; upd context) else upd context end fun no_solver_err () = error "No SMT solver selected" fun solver_of ctxt = (case solver_name_of ctxt of SOME name => name | NONE => no_solver_err ()) fun solver_info_of default select ctxt = (case solver_name_of ctxt of NONE => default () | SOME name => select (Symtab.lookup (solvers_of (Data.get (Context.Proof ctxt))) name)) fun solver_class_of ctxt = let fun class_of ({class, ...}: solver_info, _) = class ctxt in solver_info_of no_solver_err (class_of o the) ctxt end fun solver_options_of ctxt = let fun all_options NONE = [] | all_options (SOME ({options, ...} : solver_info, opts)) = opts @ options ctxt in solver_info_of (K []) all_options ctxt end val setup_solver = Attrib.setup \<^binding>\smt_solver\ (Scan.lift (\<^keyword>\=\ |-- Args.name) >> (Thm.declaration_attribute o K o select_solver)) "SMT solver configuration" (* options *) val oracle = Attrib.setup_config_bool \<^binding>\smt_oracle\ (K true) val timeout = Attrib.setup_config_real \<^binding>\smt_timeout\ (K 1000000.0) val reconstruction_step_timeout = Attrib.setup_config_real \<^binding>\smt_reconstruction_step_timeout\ (K 10.0) val random_seed = Attrib.setup_config_int \<^binding>\smt_random_seed\ (K 1) val read_only_certificates = Attrib.setup_config_bool \<^binding>\smt_read_only_certificates\ (K false) val verbose = Attrib.setup_config_bool \<^binding>\smt_verbose\ (K true) val trace = Attrib.setup_config_bool \<^binding>\smt_trace\ (K false) val trace_verit = Attrib.setup_config_bool \<^binding>\smt_debug_verit\ (K false) val spy_verit_attr = Attrib.setup_config_bool \<^binding>\smt_spy_verit\ (K false) val spy_z3 = Attrib.setup_config_bool \<^binding>\smt_spy_z3\ (K false) val trace_arith_verit = Attrib.setup_config_bool \<^binding>\smt_debug_arith_verit\ (K false) -val trace_verit_compression = Attrib.setup_config_bool \<^binding>\verit_compress_proofs\ (K false) +val trace_verit_compression = Attrib.setup_config_bool \<^binding>\verit_compress_proofs\ (K true) val statistics = Attrib.setup_config_bool \<^binding>\smt_statistics\ (K false) val monomorph_limit = Attrib.setup_config_int \<^binding>\smt_monomorph_limit\ (K 10) val monomorph_instances = Attrib.setup_config_int \<^binding>\smt_monomorph_instances\ (K 500) val explicit_application = Attrib.setup_config_int \<^binding>\smt_explicit_application\ (K 1) val higher_order = Attrib.setup_config_bool \<^binding>\smt_higher_order\ (K false) val nat_as_int = Attrib.setup_config_bool \<^binding>\smt_nat_as_int\ (K false) val infer_triggers = Attrib.setup_config_bool \<^binding>\smt_infer_triggers\ (K false) val debug_files = Attrib.setup_config_string \<^binding>\smt_debug_files\ (K "") val sat_solver = Attrib.setup_config_string \<^binding>\smt_sat_solver\ (K "cdclite") (* diagnostics *) fun cond_trace flag f x = if flag then tracing ("SMT: " ^ f x) else () fun verbose_msg ctxt = cond_trace (Config.get ctxt verbose) fun trace_msg ctxt = cond_trace (Config.get ctxt trace) fun statistics_msg ctxt = cond_trace (Config.get ctxt statistics) fun verit_msg ctxt (x : unit -> 'a) = if (Config.get ctxt trace_verit) then ignore(x ()) else () fun verit_arith_msg ctxt (x : unit -> 'a) = if (Config.get ctxt trace_arith_verit) then ignore(x ()) else () fun spy_verit ctxt = Config.get ctxt spy_verit_attr fun spy_Z3 ctxt = Config.get ctxt spy_z3 fun compress_verit_proofs ctxt = Config.get ctxt trace_verit_compression (* tools *) fun with_time_limit ctxt timeout_config f x = Timeout.apply (seconds (Config.get ctxt timeout_config)) f x handle Timeout.TIMEOUT _ => raise SMT_Failure.SMT SMT_Failure.Time_Out fun with_timeout ctxt = with_time_limit ctxt timeout (* certificates *) val certificates_of = certs_of o Data.get o Context.Proof val get_certificates_path = Option.map (Cache_IO.cache_path_of) o certificates_of fun select_certificates name context = context |> Data.map (put_certs ( if name = "" then NONE else (Resources.master_directory (Context.theory_of context) + Path.explode name) |> SOME o Cache_IO.unsynchronized_init)) val setup_certificates = Attrib.setup \<^binding>\smt_certificates\ (Scan.lift (\<^keyword>\=\ |-- Args.name) >> (Thm.declaration_attribute o K o select_certificates)) "SMT certificates configuration" (* setup *) val _ = Theory.setup ( setup_solver #> setup_certificates) fun print_setup ctxt = let fun string_of_bool b = if b then "true" else "false" val names = available_solvers_of ctxt val ns = if null names then ["(none)"] else sort_strings names val n = the_default "(none)" (solver_name_of ctxt) val opts = solver_options_of ctxt val t = string_of_real (Config.get ctxt timeout) val certs_filename = (case get_certificates_path ctxt of SOME path => Path.print path | NONE => "(disabled)") in Pretty.writeln (Pretty.big_list "SMT setup:" [ Pretty.str ("Current SMT solver: " ^ n), Pretty.str ("Current SMT solver options: " ^ space_implode " " opts), Pretty.str_list "Available SMT solvers: " "" ns, Pretty.str ("Current timeout: " ^ t ^ " seconds"), Pretty.str ("With proofs: " ^ string_of_bool (not (Config.get ctxt oracle))), Pretty.str ("Certificates cache: " ^ certs_filename), Pretty.str ("Fixed certificates: " ^ string_of_bool (Config.get ctxt read_only_certificates))]) end val _ = Outer_Syntax.command \<^command_keyword>\smt_status\ "show the available SMT solvers, the currently selected SMT solver, \ \and the values of SMT configuration options" (Scan.succeed (Toplevel.keep (print_setup o Toplevel.context_of))) end; diff --git a/src/HOL/Tools/SMT/verit_proof.ML b/src/HOL/Tools/SMT/verit_proof.ML --- a/src/HOL/Tools/SMT/verit_proof.ML +++ b/src/HOL/Tools/SMT/verit_proof.ML @@ -1,859 +1,898 @@ (* Title: HOL/Tools/SMT/Verit_Proof.ML Author: Mathias Fleury, ENS Rennes Author: Sascha Boehme, TU Muenchen VeriT proofs: parsing and abstract syntax tree. *) signature VERIT_PROOF = sig (*proofs*) datatype veriT_step = VeriT_Step of { id: string, rule: string, prems: string list, proof_ctxt: term list, concl: term, fixes: string list} datatype veriT_replay_node = VeriT_Replay_Node of { id: string, rule: string, args: term list, prems: string list, proof_ctxt: term list, concl: term, bounds: (string * typ) list, declarations: (string * term) list, insts: term Symtab.table, subproof: (string * typ) list * term list * term list * veriT_replay_node list} (*proof parser*) val parse: typ Symtab.table -> term Symtab.table -> string list -> Proof.context -> veriT_step list * Proof.context val parse_replay: typ Symtab.table -> term Symtab.table -> string list -> Proof.context -> veriT_replay_node list * Proof.context val step_prefix : string val input_rule: string val keep_app_symbols: string -> bool val keep_raw_lifting: string -> bool val normalized_input_rule: string val la_generic_rule : string val rewrite_rule : string val simp_arith_rule : string val veriT_deep_skolemize_rule : string val veriT_def : string val subproof_rule : string val local_input_rule : string val not_not_rule : string val contract_rule : string val ite_intro_rule : string val eq_congruent_rule : string val eq_congruent_pred_rule : string val skolemization_steps : string list + val theory_resolution2_rule: string + val equiv_pos2_rule: string + val th_resolution_rule: string val is_skolemization: string -> bool val is_skolemization_step: veriT_replay_node -> bool val number_of_steps: veriT_replay_node list -> int (*Strategy related*) val veriT_strategy : string Config.T val veriT_current_strategy : Context.generic -> string list val all_veriT_stgies: Context.generic -> string list; val select_veriT_stgy: string -> Context.generic -> Context.generic; val valid_veriT_stgy: string -> Context.generic -> bool; val verit_add_stgy: string * string list -> Context.generic -> Context.generic val verit_rm_stgy: string -> Context.generic -> Context.generic (*Global tactic*) val verit_tac: Proof.context -> thm list -> int -> tactic val verit_tac_stgy: string -> Proof.context -> thm list -> int -> tactic end; structure Verit_Proof: VERIT_PROOF = struct open SMTLIB_Proof val veriT_strategy_default_name = "default"; (*FUDGE*) val veriT_strategy_del_insts_name = "del_insts"; (*FUDGE*) val veriT_strategy_rm_insts_name = "ccfv_SIG"; (*FUDGE*) val veriT_strategy_ccfv_insts_name = "ccfv_threshold"; (*FUDGE*) val veriT_strategy_best_name = "best"; (*FUDGE*) val veriT_strategy_best = ["--index-sorts", "--index-fresh-sorts", "--triggers-new", "--triggers-sel-rm-specific"]; val veriT_strategy_del_insts = ["--index-sorts", "--index-fresh-sorts", "--ccfv-breadth", "--inst-deletion", "--index-SAT-triggers", "--inst-deletion-loops", "--inst-deletion-track-vars", "--inst-deletion", "--index-SAT-triggers"]; val veriT_strategy_rm_insts = ["--index-SIG", "--triggers-new", "--triggers-sel-rm-specific"]; val veriT_strategy_ccfv_insts = ["--index-sorts", "--index-fresh-sorts", "--triggers-new", "--triggers-sel-rm-specific", "--triggers-restrict-combine", "--inst-deletion", "--index-SAT-triggers", "--inst-deletion-loops", "--inst-deletion-track-vars", "--inst-deletion", "--index-SAT-triggers", "--inst-sorts-threshold=100000", "--ematch-exp=10000000", "--ccfv-index=100000", "--ccfv-index-full=1000"] val veriT_strategy_default = []; type verit_strategy = {default_strategy: string, strategies: (string * string list) list} fun mk_verit_strategy default_strategy strategies : verit_strategy = {default_strategy=default_strategy,strategies=strategies} val empty_data = mk_verit_strategy veriT_strategy_best_name [(veriT_strategy_default_name, veriT_strategy_default), (veriT_strategy_del_insts_name, veriT_strategy_del_insts), (veriT_strategy_rm_insts_name, veriT_strategy_rm_insts), (veriT_strategy_ccfv_insts_name, veriT_strategy_ccfv_insts), (veriT_strategy_best_name, veriT_strategy_best)] fun merge_data ({strategies=strategies1,...}:verit_strategy, {default_strategy,strategies=strategies2}:verit_strategy) : verit_strategy = mk_verit_strategy default_strategy (AList.merge (op =) (op =) (strategies1, strategies2)) structure Data = Generic_Data ( type T = verit_strategy val empty = empty_data val extend = I val merge = merge_data ) fun veriT_current_strategy ctxt = let val {default_strategy,strategies} = (Data.get ctxt) in AList.lookup (op=) strategies default_strategy |> the end val veriT_strategy = Attrib.setup_config_string \<^binding>\smt_verit_strategy\ (K veriT_strategy_best_name); fun valid_veriT_stgy stgy context = let val {strategies,...} = Data.get context in AList.defined (op =) strategies stgy end fun select_veriT_stgy stgy context = let val {strategies,...} = Data.get context val upd = Data.map (K (mk_verit_strategy stgy strategies)) in if not (AList.defined (op =) strategies stgy) then error ("Trying to select unknown veriT strategy: " ^ quote stgy) else upd context end fun verit_add_stgy stgy context = let val {default_strategy,strategies} = Data.get context in - Data.map + Data.map (K (mk_verit_strategy default_strategy (AList.update (op =) stgy strategies))) context end fun verit_rm_stgy stgy context = let val {default_strategy,strategies} = Data.get context in - Data.map + Data.map (K (mk_verit_strategy default_strategy (AList.delete (op =) stgy strategies))) context end fun all_veriT_stgies context = let val {strategies,...} = Data.get context in map fst strategies end fun verit_tac ctxt = SMT_Solver.smt_tac (Context.proof_map (SMT_Config.select_solver "verit") ctxt) fun verit_tac_stgy stgy ctxt = verit_tac (Context.proof_of (select_veriT_stgy stgy (Context.Proof ctxt))) datatype raw_veriT_node = Raw_VeriT_Node of { id: string, rule: string, args: SMTLIB.tree, prems: string list, concl: SMTLIB.tree, declarations: (string * SMTLIB.tree) list, subproof: raw_veriT_node list} fun mk_raw_node id rule args prems declarations concl subproof = Raw_VeriT_Node {id = id, rule = rule, args = args, prems = prems, declarations = declarations, concl = concl, subproof = subproof} datatype veriT_node = VeriT_Node of { id: string, rule: string, prems: string list, proof_ctxt: term list, concl: term} fun mk_node id rule prems proof_ctxt concl = VeriT_Node {id = id, rule = rule, prems = prems, proof_ctxt = proof_ctxt, concl = concl} datatype veriT_replay_node = VeriT_Replay_Node of { id: string, rule: string, args: term list, prems: string list, proof_ctxt: term list, concl: term, bounds: (string * typ) list, insts: term Symtab.table, declarations: (string * term) list, subproof: (string * typ) list * term list * term list * veriT_replay_node list} fun mk_replay_node id rule args prems proof_ctxt concl bounds insts declarations subproof = VeriT_Replay_Node {id = id, rule = rule, args = args, prems = prems, proof_ctxt = proof_ctxt, concl = concl, bounds = bounds, insts = insts, declarations = declarations, subproof = subproof} datatype veriT_step = VeriT_Step of { id: string, rule: string, prems: string list, proof_ctxt: term list, concl: term, fixes: string list} fun mk_step id rule prems proof_ctxt concl fixes = VeriT_Step {id = id, rule = rule, prems = prems, proof_ctxt = proof_ctxt, concl = concl, fixes = fixes} val step_prefix = ".c" val input_rule = "input" val la_generic_rule = "la_generic" val normalized_input_rule = "__normalized_input" (*arbitrary*) val rewrite_rule = "__rewrite" (*arbitrary*) val subproof_rule = "subproof" val local_input_rule = "__local_input" (*arbitrary*) val simp_arith_rule = "simp_arith" val veriT_def = "__skolem_definition" (*arbitrary*) val not_not_rule = "not_not" val contract_rule = "contraction" val eq_congruent_pred_rule = "eq_congruent_pred" val eq_congruent_rule = "eq_congruent" val ite_intro_rule = "ite_intro" val default_skolem_rule = "sko_forall" (*arbitrary, but must be one of the skolems*) +val theory_resolution2_rule = "__theory_resolution2" (*arbitrary*) +val equiv_pos2_rule = "equiv_pos2" +val th_resolution_rule = "th_resolution" val skolemization_steps = ["sko_forall", "sko_ex"] val is_skolemization = member (op =) skolemization_steps val keep_app_symbols = member (op =) [eq_congruent_pred_rule, eq_congruent_rule, ite_intro_rule] val keep_raw_lifting = member (op =) [eq_congruent_pred_rule, eq_congruent_rule, ite_intro_rule] val is_SH_trivial = member (op =) [not_not_rule, contract_rule] fun is_skolemization_step (VeriT_Replay_Node {id, ...}) = is_skolemization id (* Even the veriT developers do not know if the following rule can still appear in proofs: *) val veriT_deep_skolemize_rule = "deep_skolemize" fun number_of_steps [] = 0 | number_of_steps ((VeriT_Replay_Node {subproof = (_, _, _, subproof), ...}) :: pf) = 1 + number_of_steps subproof + number_of_steps pf (* proof parser *) fun node_of p cx = ([], cx) ||>> `(with_fresh_names (term_of p)) |>> snd fun find_type_in_formula (Abs (v, T, u)) var_name = if String.isPrefix var_name v then SOME T else find_type_in_formula u var_name | find_type_in_formula (u $ v) var_name = (case find_type_in_formula u var_name of NONE => find_type_in_formula v var_name | some_T => some_T) | find_type_in_formula (Free(v, T)) var_name = if String.isPrefix var_name v then SOME T else NONE | find_type_in_formula _ _ = NONE fun synctactic_var_subst old_name new_name (u $ v) = (synctactic_var_subst old_name new_name u $ synctactic_var_subst old_name new_name v) | synctactic_var_subst old_name new_name (Abs (v, T, u)) = Abs (if String.isPrefix old_name v then new_name else v, T, synctactic_var_subst old_name new_name u) | synctactic_var_subst old_name new_name (Free (v, T)) = if String.isPrefix old_name v then Free (new_name, T) else Free (v, T) | synctactic_var_subst _ _ t = t fun synctatic_rew_in_lhs_subst old_name new_name (Const(\<^const_name>\HOL.eq\, T) $ t1 $ t2) = Const(\<^const_name>\HOL.eq\, T) $ synctactic_var_subst old_name new_name t1 $ t2 | synctatic_rew_in_lhs_subst old_name new_name (Const(\<^const_name>\Trueprop\, T) $ t1) = Const(\<^const_name>\Trueprop\, T) $ (synctatic_rew_in_lhs_subst old_name new_name t1) | synctatic_rew_in_lhs_subst _ _ t = t fun add_bound_variables_to_ctxt concl = fold (update_binding o (fn s => (s, Term (Free (s, the_default dummyT (find_type_in_formula concl s)))))) local fun remove_Sym (SMTLIB.Sym y) = y | remove_Sym y = (@{print} y; raise (Fail "failed to match")) fun extract_symbols bds = bds |> map (fn SMTLIB.S [SMTLIB.Sym "=", SMTLIB.Sym x, SMTLIB.Sym y] => [[x, y]] | SMTLIB.S [SMTLIB.Key "=", SMTLIB.Sym x, SMTLIB.Sym y] => [[x, y]] | SMTLIB.S syms => map (single o remove_Sym) syms | SMTLIB.Sym x => [[x]] | t => raise (Fail ("match error " ^ @{make_string} t))) |> flat (* onepoint can bind a variable to another variable or to a constant *) fun extract_qnt_symbols cx bds = bds |> map (fn SMTLIB.S [SMTLIB.Sym "=", SMTLIB.Sym x, SMTLIB.Sym y] => (case node_of (SMTLIB.Sym y) cx of ((_, []), _) => [[x]] | _ => [[x, y]]) | SMTLIB.S [SMTLIB.Key "=", SMTLIB.Sym x, SMTLIB.Sym y] => (case node_of (SMTLIB.Sym y) cx of ((_, []), _) => [[x]] | _ => [[x, y]]) | SMTLIB.S (SMTLIB.Sym "=" :: SMTLIB.Sym x :: _) => [[x]] | SMTLIB.S (SMTLIB.Key "=" :: SMTLIB.Sym x :: _) => [[x]] | SMTLIB.S syms => map (single o remove_Sym) syms | SMTLIB.Sym x => [[x]] | t => raise (Fail ("match error " ^ @{make_string} t))) |> flat fun extract_symbols_map bds = bds |> map (fn SMTLIB.S [SMTLIB.Sym "=", SMTLIB.Sym x, _] => [[x]] | SMTLIB.S syms => map (single o remove_Sym) syms) |> flat in fun declared_csts _ "__skolem_definition" (SMTLIB.S [SMTLIB.Sym x, typ, _]) = [(x, typ)] | declared_csts _ _ _ = [] fun skolems_introduced_by_rule (SMTLIB.S bds) = fold (fn (SMTLIB.S [SMTLIB.Sym "=", SMTLIB.Sym _, SMTLIB.Sym y]) => curry (op ::) y) bds [] (*FIXME there is probably a way to use the information given by onepoint*) fun bound_vars_by_rule _ "bind" (SMTLIB.S bds) = extract_symbols bds | bound_vars_by_rule cx "onepoint" (SMTLIB.S bds) = extract_qnt_symbols cx bds | bound_vars_by_rule _ "sko_forall" (SMTLIB.S bds) = extract_symbols_map bds | bound_vars_by_rule _ "sko_ex" (SMTLIB.S bds) = extract_symbols_map bds | bound_vars_by_rule _ "__skolem_definition" (SMTLIB.S [SMTLIB.Sym x, _, _]) = [[x]] | bound_vars_by_rule _ _ _ = [] (* VeriT adds "?" before some variables. *) fun remove_all_qm (SMTLIB.Sym v :: l) = SMTLIB.Sym (perhaps (try (unprefix "?")) v) :: remove_all_qm l | remove_all_qm (SMTLIB.S l :: l') = SMTLIB.S (remove_all_qm l) :: remove_all_qm l' | remove_all_qm (SMTLIB.Key v :: l) = SMTLIB.Key v :: remove_all_qm l | remove_all_qm (v :: l) = v :: remove_all_qm l | remove_all_qm [] = [] fun remove_all_qm2 (SMTLIB.Sym v) = SMTLIB.Sym (perhaps (try (unprefix "?")) v) | remove_all_qm2 (SMTLIB.S l) = SMTLIB.S (remove_all_qm l) | remove_all_qm2 (SMTLIB.Key v) = SMTLIB.Key v | remove_all_qm2 v = v end datatype step_kind = ASSUME | ANCHOR | NO_STEP | NORMAL_STEP | SKOLEM fun parse_raw_proof_steps (limit : string option) (ls : SMTLIB.tree list) (cx : name_bindings) : (raw_veriT_node list * SMTLIB.tree list * name_bindings) = let fun rotate_pair (a, (b, c)) = ((a, b), c) fun step_kind [] = (NO_STEP, SMTLIB.S [], []) | step_kind ((p as SMTLIB.S (SMTLIB.Sym "anchor" :: _)) :: l) = (ANCHOR, p, l) | step_kind ((p as SMTLIB.S (SMTLIB.Sym "assume" :: _)) :: l) = (ASSUME, p, l) | step_kind ((p as SMTLIB.S (SMTLIB.Sym "step" :: _)) :: l) = (NORMAL_STEP, p, l) | step_kind ((p as SMTLIB.S (SMTLIB.Sym "define-fun" :: _)) :: l) = (SKOLEM, p, l) fun parse_skolem (SMTLIB.S [SMTLIB.Sym "define-fun", SMTLIB.Sym id, _, typ, SMTLIB.S (SMTLIB.Sym "!" :: t :: [SMTLIB.Key _, SMTLIB.Sym name])]) cx = (*replace the name binding by the constant instead of the full term in order to reduce the size of the generated terms and therefore the reconstruction time*) let val (l, cx) = (fst oo SMTLIB_Proof.extract_and_update_name_bindings) t cx |> apsnd (SMTLIB_Proof.update_name_binding (name, SMTLIB.Sym id)) in (mk_raw_node (id ^ veriT_def) veriT_def (SMTLIB.S [SMTLIB.Sym id, typ, l]) [] [] (SMTLIB.S [SMTLIB.Sym "=", SMTLIB.Sym id, l]) [], cx) end | parse_skolem (SMTLIB.S [SMTLIB.Sym "define-fun", SMTLIB.Sym id, _, typ, SMTLIB.S l]) cx = let val (l, cx) = (fst oo SMTLIB_Proof.extract_and_update_name_bindings) (SMTLIB.S l ) cx in (mk_raw_node (id ^ veriT_def) veriT_def (SMTLIB.S [SMTLIB.Sym id, typ, l]) [] [] (SMTLIB.S [SMTLIB.Sym "=", SMTLIB.Sym id, l]) [], cx) end | parse_skolem t _ = raise Fail ("unrecognized VeriT proof " ^ \<^make_string> t) fun get_id_cx (SMTLIB.S ((SMTLIB.Sym _) :: (SMTLIB.Sym id) :: l), cx) = (id, (l, cx)) | get_id_cx t = raise Fail ("unrecognized VeriT proof " ^ \<^make_string> t) fun get_id (SMTLIB.S ((SMTLIB.Sym _) :: (SMTLIB.Sym id) :: l)) = (id, l) | get_id t = raise Fail ("unrecognized VeriT proof " ^ \<^make_string> t) fun parse_source (SMTLIB.Key "premises" :: SMTLIB.S source ::l, cx) = (SOME (map (fn (SMTLIB.Sym id) => id) source), (l, cx)) | parse_source (l, cx) = (NONE, (l, cx)) fun parse_rule (SMTLIB.Key "rule" :: SMTLIB.Sym r :: l, cx) = (r, (l, cx)) | parse_rule t = raise Fail ("unrecognized VeriT proof " ^ \<^make_string> t) fun parse_anchor_step (SMTLIB.S (SMTLIB.Sym "anchor" :: SMTLIB.Key "step" :: SMTLIB.Sym r :: l), cx) = (r, (l, cx)) | parse_anchor_step t = raise Fail ("unrecognized VeriT proof " ^ \<^make_string> t) fun parse_args (SMTLIB.Key "args" :: args :: l, cx) = let val ((args, cx), _) = SMTLIB_Proof.extract_and_update_name_bindings args cx in (args, (l, cx)) end | parse_args (l, cx) = (SMTLIB.S [], (l, cx)) fun parse_and_clausify_conclusion (SMTLIB.S (SMTLIB.Sym "cl" :: []) :: l, cx) = (SMTLIB.Sym "false", (l, cx)) | parse_and_clausify_conclusion (SMTLIB.S (SMTLIB.Sym "cl" :: concl) :: l, cx) = let val (concl, cx) = fold_map (fst oo SMTLIB_Proof.extract_and_update_name_bindings) concl cx in (SMTLIB.S (SMTLIB.Sym "or" :: concl), (l, cx)) end | parse_and_clausify_conclusion t = raise Fail ("unrecognized VeriT proof " ^ \<^make_string> t) val parse_normal_step = get_id_cx ##> parse_and_clausify_conclusion #> rotate_pair ##> parse_rule #> rotate_pair ##> parse_source #> rotate_pair ##> parse_args #> rotate_pair fun to_raw_node subproof ((((id, concl), rule), prems), args) = mk_raw_node id rule args (the_default [] prems) [] concl subproof fun at_discharge NONE _ = false | at_discharge (SOME id) p = p |> get_id |> fst |> (fn id2 => id = id2) in case step_kind ls of (NO_STEP, _, _) => ([],[], cx) | (NORMAL_STEP, p, l) => if at_discharge limit p then ([], ls, cx) else let val (s, (_, cx)) = (p, cx) |> parse_normal_step ||> (fn i => i) |>> (to_raw_node []) val (rp, rl, cx) = parse_raw_proof_steps limit l cx in (s :: rp, rl, cx) end | (ASSUME, p, l) => let val (id, t :: []) = p |> get_id val ((t, cx), _) = SMTLIB_Proof.extract_and_update_name_bindings t cx val s = mk_raw_node id input_rule (SMTLIB.S []) [] [] t [] val (rp, rl, cx) = parse_raw_proof_steps limit l cx in (s :: rp, rl, cx) end | (ANCHOR, p, l) => let val (anchor_id, (anchor_args, (_, cx))) = (p, cx) |> (parse_anchor_step ##> parse_args) val (subproof, discharge_step :: remaining_proof, cx) = parse_raw_proof_steps (SOME anchor_id) l cx val (curss, (_, cx)) = parse_normal_step (discharge_step, cx) val s = to_raw_node subproof (fst curss, anchor_args) val (rp, rl, cx) = parse_raw_proof_steps limit remaining_proof cx in (s :: rp, rl, cx) end | (SKOLEM, p, l) => let val (s, cx) = parse_skolem p cx val (rp, rl, cx) = parse_raw_proof_steps limit l cx in (s :: rp, rl, cx) end end fun proof_ctxt_of_rule "bind" t = t | proof_ctxt_of_rule "sko_forall" t = t | proof_ctxt_of_rule "sko_ex" t = t | proof_ctxt_of_rule "let" t = t | proof_ctxt_of_rule "onepoint" t = t | proof_ctxt_of_rule _ _ = [] fun args_of_rule "bind" t = t | args_of_rule "la_generic" t = t | args_of_rule "lia_generic" t = t | args_of_rule _ _ = [] fun insts_of_forall_inst "forall_inst" t = map (fn SMTLIB.S [_, SMTLIB.Sym x, a] => (x, a)) t | insts_of_forall_inst _ _ = [] fun id_of_last_step prems = if null prems then [] else let val VeriT_Replay_Node {id, ...} = List.last prems in [id] end fun extract_assumptions_from_subproof subproof = let fun extract_assumptions_from_subproof (VeriT_Replay_Node {rule, concl, ...}) assms = if rule = local_input_rule then concl :: assms else assms in fold extract_assumptions_from_subproof subproof [] end fun normalized_rule_name id rule = (case (rule = input_rule, can (unprefix SMTLIB_Interface.assert_prefix) id) of (true, true) => normalized_input_rule | (true, _) => local_input_rule | _ => rule) fun is_assm_repetition id rule = rule = input_rule andalso can (unprefix SMTLIB_Interface.assert_prefix) id fun extract_skolem ([SMTLIB.Sym var, typ, choice]) = (var, typ, choice) | extract_skolem t = raise Fail ("fail to parse type" ^ @{make_string} t) (* The preprocessing takes care of: 1. unfolding the shared terms 2. extract the declarations of skolems to make sure that there are not unfolded *) fun preprocess compress step = let fun expand_assms cs = map (fn t => case AList.lookup (op =) cs t of NONE => t | SOME a => a) fun expand_lonely_arguments (args as SMTLIB.S [SMTLIB.Sym "=", _, _]) = [args] | expand_lonely_arguments (SMTLIB.S S) = map (fn x => SMTLIB.S [SMTLIB.Sym "=", x, x]) S | expand_lonely_arguments (x as SMTLIB.Sym _) = [SMTLIB.S [SMTLIB.Sym "=", x, x]] | expand_lonely_arguments t = [t] fun preprocess (Raw_VeriT_Node {id, rule, args, prems, concl, subproof, ...}) (cx, remap_assms) = let val stripped_args = args |> (fn SMTLIB.S args => args) |> map (fn SMTLIB.S [SMTLIB.Key "=", x, y] => SMTLIB.S [SMTLIB.Sym "=", x, y] | x => x) |> (rule = "bind" orelse rule = "onepoint") ? flat o (map expand_lonely_arguments) |> `(if rule = veriT_def then single o extract_skolem else K []) ||> SMTLIB.S val (subproof, (cx, _)) = fold_map preprocess subproof (cx, remap_assms) |> apfst flat val (skolem_names, stripped_args) = stripped_args val remap_assms = (if rule = "or" then (id, hd prems) :: remap_assms else remap_assms) (* declare variables in the context *) val declarations = if rule = veriT_def then skolem_names |> map (fn (name, _, choice) => (name, choice)) else [] in if compress andalso rule = "or" then ([], (cx, remap_assms)) else ([Raw_VeriT_Node {id = id, rule = rule, args = stripped_args, prems = expand_assms remap_assms prems, declarations = declarations, concl = concl, subproof = subproof}], (cx, remap_assms)) end in preprocess step end fun filter_split _ [] = ([], []) | filter_split f (a :: xs) = (if f a then apfst (curry op :: a) else apsnd (curry op :: a)) (filter_split f xs) fun collect_skolem_defs (Raw_VeriT_Node {rule, subproof = subproof, args, ...}) = (if is_skolemization rule then map (fn id => id ^ veriT_def) (skolems_introduced_by_rule args) else []) @ flat (map collect_skolem_defs subproof) (*The postprocessing does: 1. translate the terms to Isabelle syntax, taking care of free variables 2. remove the ambiguity in the proof terms: x \ y |- x = x means y = x. To remove ambiguity, we use the fact that y is a free variable and replace the term by: xy \ y |- xy = x. This is now does not have an ambiguity and we can safely move the "xy \ y" to the proof assumptions. *) fun postprocess_proof compress ctxt step cx = let fun postprocess (Raw_VeriT_Node {id, rule, args, prems, declarations, concl, subproof}) (cx, rew) = let val _ = (SMT_Config.verit_msg ctxt) (fn () => @{print} ("id =", id, "concl =", concl)) val globally_bound_vars = declared_csts cx rule args val cx = fold (update_binding o (fn (s, typ) => (s, Term (Free (s, type_of cx typ))))) globally_bound_vars cx (*find rebound variables specific to the LHS of the equivalence symbol*) val bound_vars = bound_vars_by_rule cx rule args val rhs_vars = fold (fn [t', t] => t <> t' ? (curry (op ::) t) | _ => fn x => x) bound_vars [] fun not_already_bound cx t = SMTLIB_Proof.lookup_binding cx t = None andalso not (member (op =) rhs_vars t) val (shadowing_vars, rebound_lhs_vars) = bound_vars |> filter_split (fn [t, _] => not_already_bound cx t | _ => true) |>> map (single o hd) |>> (fn vars => vars @ map (fn [_, t] => [t] | _ => []) bound_vars) |>> flat val subproof_rew = fold (fn [t, t'] => curry (op ::) (t, t ^ t')) rebound_lhs_vars rew val subproof_rewriter = fold (fn (t, t') => synctatic_rew_in_lhs_subst t t') subproof_rew val ((concl, bounds), cx') = node_of concl cx val extra_lhs_vars = map (fn [a,b] => (a, a^b)) rebound_lhs_vars (* postprocess conclusion *) val concl = SMTLIB_Isar.unskolemize_names ctxt (subproof_rewriter concl) val _ = (SMT_Config.verit_msg ctxt) (fn () => \<^print> ("id =", id, "concl =", concl)) val _ = (SMT_Config.verit_msg ctxt) (fn () => \<^print> ("id =", id, "cx' =", cx', "bound_vars =", bound_vars)) val bound_tvars = map (fn s => (s, the (find_type_in_formula concl s))) (shadowing_vars @ map snd extra_lhs_vars) val subproof_cx = add_bound_variables_to_ctxt concl (shadowing_vars @ map snd extra_lhs_vars) cx fun could_unify (Bound i, Bound j) = i = j | could_unify (Var v, Var v') = v = v' | could_unify (Free v, Free v') = v = v' | could_unify (Const (v, ty), Const (v', ty')) = v = v' andalso ty = ty' | could_unify (Abs (_, ty, bdy), Abs (_, ty', bdy')) = ty = ty' andalso could_unify (bdy, bdy') | could_unify (u $ v, u' $ v') = could_unify (u, u') andalso could_unify (v, v') | could_unify _ = false fun is_alpha_renaming t = t |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> could_unify handle TERM _ => false val alpha_conversion = rule = "bind" andalso is_alpha_renaming concl val can_remove_subproof = compress andalso (is_skolemization rule orelse alpha_conversion) val (fixed_subproof : veriT_replay_node list, _) = fold_map postprocess (if can_remove_subproof then [] else subproof) (subproof_cx, subproof_rew) val unsk_and_rewrite = SMTLIB_Isar.unskolemize_names ctxt o subproof_rewriter (* postprocess assms *) val stripped_args = args |> (fn SMTLIB.S S => S) val sanitized_args = proof_ctxt_of_rule rule stripped_args val arg_cx = subproof_cx |> add_bound_variables_to_ctxt concl (shadowing_vars @ map fst extra_lhs_vars) val (termified_args, _) = fold_map node_of sanitized_args arg_cx |> apfst (map fst) val normalized_args = map unsk_and_rewrite termified_args val subproof_assms = proof_ctxt_of_rule rule normalized_args (* postprocess arguments *) val rule_args = args_of_rule rule stripped_args val (termified_args, _) = fold_map term_of rule_args subproof_cx val normalized_args = map unsk_and_rewrite termified_args val rule_args = map subproof_rewriter normalized_args val raw_insts = insts_of_forall_inst rule stripped_args fun termify_term (x, t) cx = let val (t, cx) = term_of t cx in ((x, t), cx) end val (termified_args, _) = fold_map termify_term raw_insts subproof_cx val insts = Symtab.empty |> fold (fn (x, t) => fn insts => Symtab.update_new (x, t) insts) termified_args |> Symtab.map (K unsk_and_rewrite) (* declarations *) val (declarations, _) = fold_map termify_term declarations cx |> apfst (map (apsnd unsk_and_rewrite)) (* fix step *) val bound_t = bounds |> map (fn s => (s, the (find_type_in_formula concl s))) val skolem_defs = (if is_skolemization rule then map (fn id => id ^ veriT_def) (skolems_introduced_by_rule args) else []) val skolems_of_subproof = (if is_skolemization rule then flat (map collect_skolem_defs subproof) else []) val fixed_prems = prems @ (if is_assm_repetition id rule then [id] else []) @ skolem_defs @ skolems_of_subproof @ (id_of_last_step fixed_subproof) (* fix subproof *) val normalized_rule = normalized_rule_name id rule |> (if compress andalso alpha_conversion then K "refl" else I) val extra_assms2 = (if rule = subproof_rule then extract_assumptions_from_subproof fixed_subproof else []) val step = mk_replay_node id normalized_rule rule_args fixed_prems subproof_assms concl bound_t insts declarations (bound_tvars, subproof_assms, extra_assms2, fixed_subproof) in (step, (cx', rew)) end in postprocess step (cx, []) |> (fn (step, (cx, _)) => (step, cx)) - end + end + +fun combine_proof_steps ((step1 : veriT_replay_node) :: step2 :: steps) = + let + val (VeriT_Replay_Node {id = id1, rule = rule1, args = args1, prems = prems1, + proof_ctxt = proof_ctxt1, concl = concl1, bounds = bounds1, insts = insts1, + declarations = declarations1, + subproof = (bound_sub1, assms_sub1, assms_extra1, subproof1)}) = step1 + val (VeriT_Replay_Node {id = id2, rule = rule2, args = args2, prems = prems2, + proof_ctxt = proof_ctxt2, concl = concl2, bounds = bounds2, insts = insts2, + declarations = declarations2, + subproof = (bound_sub2, assms_sub2, assms_extra2, subproof2)}) = step2 + val goals1 = + (case concl1 of + _ $ (Const (\<^const_name>\HOL.disj\, _) $ _ $ + (Const (\<^const_name>\HOL.disj\, _) $ (Const (\<^const_name>\HOL.Not\, _) $a) $ b)) => [a,b] + | _ => []) + val goal2 = (case concl2 of _ $ a => a) + in + if rule1 = equiv_pos2_rule andalso rule2 = th_resolution_rule andalso member (op =) prems2 id1 + andalso member (op =) goals1 goal2 + then + mk_replay_node id2 theory_resolution2_rule args2 (filter_out (curry (op =) id1) prems2) + proof_ctxt2 concl2 bounds2 insts2 declarations2 + (bound_sub2, assms_sub2, assms_extra2, combine_proof_steps subproof2) :: + combine_proof_steps steps + else + mk_replay_node id1 rule1 args1 prems1 + proof_ctxt1 concl1 bounds1 insts1 declarations1 + (bound_sub1, assms_sub1, assms_extra1, combine_proof_steps subproof1) :: + combine_proof_steps (step2 :: steps) + end + | combine_proof_steps steps = steps val linearize_proof = let fun map_node_concl f (VeriT_Node {id, rule, prems, proof_ctxt, concl}) = mk_node id rule prems proof_ctxt (f concl) fun linearize (VeriT_Replay_Node {id = id, rule = rule, args = _, prems = prems, proof_ctxt = proof_ctxt, concl = concl, bounds = bounds, insts = _, declarations = _, subproof = (bounds', assms, inputs, subproof)}) = let val bounds = distinct (op =) bounds val bounds' = distinct (op =) bounds' fun mk_prop_of_term concl = concl |> fastype_of concl = \<^typ>\bool\ ? curry (op $) \<^term>\Trueprop\ fun remove_assumption_id assumption_id prems = filter_out (curry (op =) assumption_id) prems fun add_assumption assumption concl = \<^const>\Pure.imp\ $ mk_prop_of_term assumption $ mk_prop_of_term concl fun inline_assumption assumption assumption_id (VeriT_Node {id, rule, prems, proof_ctxt, concl}) = mk_node id rule (remove_assumption_id assumption_id prems) proof_ctxt (add_assumption assumption concl) fun find_input_steps_and_inline [] = [] | find_input_steps_and_inline (VeriT_Node {id = id', rule, prems, concl, ...} :: steps) = if rule = input_rule then find_input_steps_and_inline (map (inline_assumption concl id') steps) else mk_node (id') rule prems [] concl :: find_input_steps_and_inline steps fun free_bounds bounds (concl) = fold (fn (var, typ) => fn t => Logic.all (Free (var, typ)) t) bounds concl val subproof = subproof |> flat o map linearize |> map (map_node_concl (fold add_assumption (assms @ inputs))) |> map (map_node_concl (free_bounds (bounds @ bounds'))) |> find_input_steps_and_inline val concl = free_bounds bounds concl in subproof @ [mk_node id rule prems proof_ctxt concl] end in linearize end fun rule_of (VeriT_Replay_Node {rule,...}) = rule fun subproof_of (VeriT_Replay_Node {subproof = (_, _, _, subproof),...}) = subproof (* Massage Skolems for Sledgehammer. We have to make sure that there is an "arrow" in the graph for skolemization steps. A. The normal easy case This function detects the steps of the form P \ Q :skolemization Q :resolution with P and replace them by Q :skolemization Throwing away the step "P \ Q" completely. This throws away a lot of information, but it does not matter too much for Sledgehammer. B. Skolems in subproofs Supporting this is more or less hopeless as long as the Isar reconstruction of Sledgehammer does not support more features like definitions. veriT is able to generate proofs with skolemization -happening in subproofs inside the formula. +happening in subproofs inside the formula. (assume "A \ P" ... P \ Q :skolemization in the subproof ...) hence A \ P \ A \ Q :lemma ... R :something with some rule and replace them by R :skolemization with some rule Without any subproof *) fun remove_skolem_definitions_proof steps = let fun replace_equivalent_by_imp (judgement $ ((Const(\<^const_name>\HOL.eq\, typ) $ arg1) $ arg2)) = judgement $ ((Const(\<^const_name>\HOL.implies\, typ) $ arg1) $ arg2) | replace_equivalent_by_imp a = a (*This case is probably wrong*) fun remove_skolem_definitions (VeriT_Replay_Node {id = id, rule = rule, args = args, prems = prems, proof_ctxt = proof_ctxt, concl = concl, bounds = bounds, insts = insts, declarations = declarations, subproof = (vars, assms', extra_assms', subproof)}) (prems_to_remove, skolems) = let val prems = prems |> filter_out (member (op =) prems_to_remove) val trivial_step = is_SH_trivial rule fun has_skolem_substep st NONE = if is_skolemization (rule_of st) then SOME (rule_of st) else fold has_skolem_substep (subproof_of st) NONE | has_skolem_substep _ a = a val promote_to_skolem = exists (fn t => member (op =) skolems t) prems val promote_from_assms = fold has_skolem_substep subproof NONE <> NONE val promote_step = promote_to_skolem orelse promote_from_assms - val skolem_step_to_skip = is_skolemization rule orelse + val skolem_step_to_skip = is_skolemization rule orelse (promote_from_assms andalso length prems > 1) val is_skolem = is_skolemization rule orelse promote_step val prems = prems |> filter_out (fn t => member (op =) skolems t) |> is_skolem ? filter_out (String.isPrefix id) val rule = (if promote_step then default_skolem_rule else rule) val subproof = subproof |> (is_skolem ? K []) (*subproofs of skolemization steps are useless for SH*) |> map (fst o (fn st => remove_skolem_definitions st (prems_to_remove, skolems))) (*no new definitions in subproofs*) |> flat val concl = concl |> is_skolem ? replace_equivalent_by_imp val step = (if skolem_step_to_skip orelse rule = veriT_def orelse trivial_step then [] else mk_replay_node id rule args prems proof_ctxt concl bounds insts declarations (vars, assms', extra_assms', subproof) |> single) val defs = (if rule = veriT_def orelse trivial_step then id :: prems_to_remove else prems_to_remove) val skolems = (if skolem_step_to_skip then id :: skolems else skolems) in (step, (defs, skolems)) end in fold_map remove_skolem_definitions steps ([], []) |> fst |> flat end local fun import_proof_and_post_process typs funs lines ctxt = let val compress = SMT_Config.compress_verit_proofs ctxt val smtlib_lines_without_qm = lines |> map single |> map SMTLIB.parse |> map remove_all_qm2 - val (raw_steps, _, _) = + val (raw_steps, _, _) = parse_raw_proof_steps NONE smtlib_lines_without_qm SMTLIB_Proof.empty_name_binding - + fun process step (cx, cx') = let fun postprocess step (cx, cx') = let val (step, cx) = postprocess_proof compress ctxt step cx in (step, (cx, cx')) end in uncurry (fold_map postprocess) (preprocess compress step (cx, cx')) end val step = (empty_context ctxt typs funs, []) |> fold_map process raw_steps |> (fn (steps, (cx, _)) => (flat steps, cx)) + |> compress? apfst combine_proof_steps in step end in fun parse typs funs lines ctxt = let val (u, env) = import_proof_and_post_process typs funs lines ctxt val t = u |> remove_skolem_definitions_proof |> flat o (map linearize_proof) fun node_to_step (VeriT_Node {id, rule, prems, concl, ...}) = mk_step id rule prems [] concl [] in (map node_to_step t, ctxt_of env) end fun parse_replay typs funs lines ctxt = let val (u, env) = import_proof_and_post_process typs funs lines ctxt val _ = (SMT_Config.verit_msg ctxt) (fn () => \<^print> u) in (u, ctxt_of env) end end end; diff --git a/src/HOL/Tools/SMT/verit_replay_methods.ML b/src/HOL/Tools/SMT/verit_replay_methods.ML --- a/src/HOL/Tools/SMT/verit_replay_methods.ML +++ b/src/HOL/Tools/SMT/verit_replay_methods.ML @@ -1,1180 +1,1192 @@ (* Title: HOL/Tools/SMT/verit_replay_methods.ML Author: Mathias Fleury, MPII, JKU Proof method for replaying veriT proofs. *) signature VERIT_REPLAY_METHODS = sig (*methods for verit proof rules*) val method_for: string -> Proof.context -> thm list -> term list -> term Symtab.table -> (string * term) list -> term -> thm val requires_subproof_assms : string list -> string -> bool val requires_local_input: string list -> string -> bool val eq_congruent_pred: Proof.context -> 'a -> term -> thm val discharge: Proof.context -> thm list -> term -> thm end; structure Verit_Replay_Methods: VERIT_REPLAY_METHODS = struct (*Some general comments on the proof format: 1. Double negations are not always removed. This means for example that the equivalence rules cannot assume that the double negations have already been removed. Therefore, we match the term, instantiate the theorem, then use simp (to remove double negations), and finally use assumption. 2. The reconstruction for rule forall_inst is buggy and tends to be very fragile, because the rule is doing much more that is supposed to do. Moreover types can make trivial goals (for the boolean structure) impossible to prove. 3. Duplicate literals are sometimes removed, mostly by the SAT solver. Rules unsupported on purpose: * Distinct_Elim, XOR, let (we don't need them). * deep_skolemize (because it is not clear if verit still generates using it). *) datatype verit_rule = False | True | (*input: a repeated (normalized) assumption of assumption of in a subproof*) Normalized_Input | Local_Input | (*Subproof:*) Subproof | (*Conjunction:*) And | Not_And | And_Pos | And_Neg | (*Disjunction""*) Or | Or_Pos | Not_Or | Or_Neg | (*Disjunction:*) Implies | Implies_Neg1 | Implies_Neg2 | Implies_Pos | Not_Implies1 | Not_Implies2 | (*Equivalence:*) Equiv_neg1 | Equiv_pos1 | Equiv_pos2 | Equiv_neg2 | Not_Equiv1 | Not_Equiv2 | Equiv1 | Equiv2 | (*If-then-else:*) ITE_Pos1 | ITE_Pos2 | ITE_Neg1 | ITE_Neg2 | Not_ITE1 | Not_ITE2 | ITE_Intro | ITE1 | ITE2 | (*Equality:*) Eq_Congruent | Eq_Reflexive | Eq_Transitive | Eq_Congruent_Pred | Trans | Refl | Cong | (*Arithmetics:*) LA_Disequality | LA_Generic | LA_Tautology | LIA_Generic | LA_Totality | LA_RW_Eq | NLA_Generic | (*Quantifiers:*) Forall_Inst | Qnt_Rm_Unused | Qnt_Join | Onepoint | Bind | Skolem_Forall | Skolem_Ex | (*Resolution:*) Theory_Resolution | Resolution | (*Temporary rules, that the verit developpers want to remove:*) AC_Simp | Bfun_Elim | Qnt_CNF | (*Used to introduce skolem constants*) Definition | (*Former cong rules*) Bool_Simplify | Or_Simplify | Not_Simplify | And_Simplify | Equiv_Simplify | Implies_Simplify | Connective_Def | Minus_Simplify | Comp_Simplify | Eq_Simplify | ITE_Simplify | Sum_Simplify | Prod_Simplify | Qnt_Simplify | Not_Not | Tautological_Clause | Duplicate_Literals | (*Unsupported rule*) - Unsupported + Unsupported | + (*For compression*) + Theory_Resolution2 fun verit_rule_of "bind" = Bind | verit_rule_of "cong" = Cong | verit_rule_of "refl" = Refl | verit_rule_of "equiv1" = Equiv1 | verit_rule_of "equiv2" = Equiv2 | verit_rule_of "equiv_pos1" = Equiv_pos1 - | verit_rule_of "equiv_pos2" = Equiv_pos2 + (*Equiv_pos2 covered below*) | verit_rule_of "equiv_neg1" = Equiv_neg1 | verit_rule_of "equiv_neg2" = Equiv_neg2 | verit_rule_of "sko_forall" = Skolem_Forall | verit_rule_of "sko_ex" = Skolem_Ex | verit_rule_of "eq_reflexive" = Eq_Reflexive - | verit_rule_of "th_resolution" = Theory_Resolution | verit_rule_of "forall_inst" = Forall_Inst | verit_rule_of "implies_pos" = Implies_Pos | verit_rule_of "or" = Or | verit_rule_of "not_or" = Not_Or | verit_rule_of "resolution" = Resolution | verit_rule_of "trans" = Trans | verit_rule_of "false" = False | verit_rule_of "ac_simp" = AC_Simp | verit_rule_of "and" = And | verit_rule_of "not_and" = Not_And | verit_rule_of "and_pos" = And_Pos | verit_rule_of "and_neg" = And_Neg | verit_rule_of "or_pos" = Or_Pos | verit_rule_of "or_neg" = Or_Neg | verit_rule_of "not_equiv1" = Not_Equiv1 | verit_rule_of "not_equiv2" = Not_Equiv2 | verit_rule_of "not_implies1" = Not_Implies1 | verit_rule_of "not_implies2" = Not_Implies2 | verit_rule_of "implies_neg1" = Implies_Neg1 | verit_rule_of "implies_neg2" = Implies_Neg2 | verit_rule_of "implies" = Implies | verit_rule_of "bfun_elim" = Bfun_Elim | verit_rule_of "ite1" = ITE1 | verit_rule_of "ite2" = ITE2 | verit_rule_of "not_ite1" = Not_ITE1 | verit_rule_of "not_ite2" = Not_ITE2 | verit_rule_of "ite_pos1" = ITE_Pos1 | verit_rule_of "ite_pos2" = ITE_Pos2 | verit_rule_of "ite_neg1" = ITE_Neg1 | verit_rule_of "ite_neg2" = ITE_Neg2 | verit_rule_of "la_disequality" = LA_Disequality | verit_rule_of "lia_generic" = LIA_Generic | verit_rule_of "la_generic" = LA_Generic | verit_rule_of "la_tautology" = LA_Tautology | verit_rule_of "la_totality" = LA_Totality | verit_rule_of "la_rw_eq"= LA_RW_Eq | verit_rule_of "nla_generic"= NLA_Generic | verit_rule_of "eq_transitive" = Eq_Transitive | verit_rule_of "qnt_rm_unused" = Qnt_Rm_Unused | verit_rule_of "onepoint" = Onepoint | verit_rule_of "qnt_join" = Qnt_Join | verit_rule_of "subproof" = Subproof | verit_rule_of "bool_simplify" = Bool_Simplify | verit_rule_of "or_simplify" = Or_Simplify | verit_rule_of "ite_simplify" = ITE_Simplify | verit_rule_of "and_simplify" = And_Simplify | verit_rule_of "not_simplify" = Not_Simplify | verit_rule_of "equiv_simplify" = Equiv_Simplify | verit_rule_of "eq_simplify" = Eq_Simplify | verit_rule_of "implies_simplify" = Implies_Simplify | verit_rule_of "connective_def" = Connective_Def | verit_rule_of "minus_simplify" = Minus_Simplify | verit_rule_of "sum_simplify" = Sum_Simplify | verit_rule_of "prod_simplify" = Prod_Simplify | verit_rule_of "comp_simplify" = Comp_Simplify | verit_rule_of "qnt_simplify" = Qnt_Simplify | verit_rule_of "tautology" = Tautological_Clause | verit_rule_of "qnt_cnf" = Qnt_CNF | verit_rule_of r = if r = Verit_Proof.normalized_input_rule then Normalized_Input else if r = Verit_Proof.local_input_rule then Local_Input else if r = Verit_Proof.veriT_def then Definition else if r = Verit_Proof.not_not_rule then Not_Not else if r = Verit_Proof.contract_rule then Duplicate_Literals else if r = Verit_Proof.ite_intro_rule then ITE_Intro else if r = Verit_Proof.eq_congruent_rule then Eq_Congruent else if r = Verit_Proof.eq_congruent_pred_rule then Eq_Congruent_Pred + else if r = Verit_Proof.theory_resolution2_rule then Theory_Resolution2 + else if r = Verit_Proof.th_resolution_rule then Theory_Resolution + else if r = Verit_Proof.equiv_pos2_rule then Equiv_pos2 else (@{print} ("Unsupport rule", r); Unsupported) fun string_of_verit_rule Bind = "Bind" | string_of_verit_rule Cong = "Cong" | string_of_verit_rule Refl = "Refl" | string_of_verit_rule Equiv1 = "Equiv1" | string_of_verit_rule Equiv2 = "Equiv2" | string_of_verit_rule Equiv_pos1 = "Equiv_pos1" | string_of_verit_rule Equiv_pos2 = "Equiv_pos2" | string_of_verit_rule Equiv_neg1 = "Equiv_neg1" | string_of_verit_rule Equiv_neg2 = "Equiv_neg2" | string_of_verit_rule Skolem_Forall = "Skolem_Forall" | string_of_verit_rule Skolem_Ex = "Skolem_Ex" | string_of_verit_rule Eq_Reflexive = "Eq_Reflexive" | string_of_verit_rule Theory_Resolution = "Theory_Resolution" + | string_of_verit_rule Theory_Resolution2 = "Theory_Resolution2" | string_of_verit_rule Forall_Inst = "forall_inst" | string_of_verit_rule Or = "Or" | string_of_verit_rule Not_Or = "Not_Or" | string_of_verit_rule Resolution = "Resolution" | string_of_verit_rule Eq_Congruent = "eq_congruent" | string_of_verit_rule Trans = "trans" | string_of_verit_rule False = "false" | string_of_verit_rule And = "and" | string_of_verit_rule And_Pos = "and_pos" | string_of_verit_rule Not_And = "not_and" | string_of_verit_rule And_Neg = "and_neg" | string_of_verit_rule Or_Pos = "or_pos" | string_of_verit_rule Or_Neg = "or_neg" | string_of_verit_rule AC_Simp = "ac_simp" | string_of_verit_rule Not_Equiv1 = "not_equiv1" | string_of_verit_rule Not_Equiv2 = "not_equiv2" | string_of_verit_rule Not_Implies1 = "not_implies1" | string_of_verit_rule Not_Implies2 = "not_implies2" | string_of_verit_rule Implies_Neg1 = "implies_neg1" | string_of_verit_rule Implies_Neg2 = "implies_neg2" | string_of_verit_rule Implies = "implies" | string_of_verit_rule Bfun_Elim = "bfun_elim" | string_of_verit_rule ITE1 = "ite1" | string_of_verit_rule ITE2 = "ite2" | string_of_verit_rule Not_ITE1 = "not_ite1" | string_of_verit_rule Not_ITE2 = "not_ite2" | string_of_verit_rule ITE_Pos1 = "ite_pos1" | string_of_verit_rule ITE_Pos2 = "ite_pos2" | string_of_verit_rule ITE_Neg1 = "ite_neg1" | string_of_verit_rule ITE_Neg2 = "ite_neg2" | string_of_verit_rule ITE_Intro = "ite_intro" | string_of_verit_rule LA_Disequality = "la_disequality" | string_of_verit_rule LA_Generic = "la_generic" | string_of_verit_rule LIA_Generic = "lia_generic" | string_of_verit_rule LA_Tautology = "la_tautology" | string_of_verit_rule LA_RW_Eq = "la_rw_eq" | string_of_verit_rule LA_Totality = "LA_Totality" | string_of_verit_rule NLA_Generic = "nla_generic" | string_of_verit_rule Eq_Transitive = "eq_transitive" | string_of_verit_rule Qnt_Rm_Unused = "qnt_remove_unused" | string_of_verit_rule Onepoint = "onepoint" | string_of_verit_rule Qnt_Join = "qnt_join" | string_of_verit_rule Eq_Congruent_Pred = "eq_congruent_pred" | string_of_verit_rule Normalized_Input = Verit_Proof.normalized_input_rule | string_of_verit_rule Local_Input = Verit_Proof.local_input_rule | string_of_verit_rule Subproof = "subproof" | string_of_verit_rule Bool_Simplify = "bool_simplify" | string_of_verit_rule Equiv_Simplify = "equiv_simplify" | string_of_verit_rule Eq_Simplify = "eq_simplify" | string_of_verit_rule Not_Simplify = "not_simplify" | string_of_verit_rule And_Simplify = "and_simplify" | string_of_verit_rule Or_Simplify = "or_simplify" | string_of_verit_rule ITE_Simplify = "ite_simplify" | string_of_verit_rule Implies_Simplify = "implies_simplify" | string_of_verit_rule Connective_Def = "connective_def" | string_of_verit_rule Minus_Simplify = "minus_simplify" | string_of_verit_rule Sum_Simplify = "sum_simplify" | string_of_verit_rule Prod_Simplify = "prod_simplify" | string_of_verit_rule Comp_Simplify = "comp_simplify" | string_of_verit_rule Qnt_Simplify = "qnt_simplify" | string_of_verit_rule Not_Not = Verit_Proof.not_not_rule | string_of_verit_rule Tautological_Clause = "tautology" | string_of_verit_rule Duplicate_Literals = Verit_Proof.contract_rule | string_of_verit_rule Qnt_CNF = "qnt_cnf" | string_of_verit_rule r = "Unknown rule: " ^ \<^make_string> r fun replay_error ctxt msg rule thms t = SMT_Replay_Methods.replay_error ctxt msg (string_of_verit_rule rule) thms t (* utility function *) fun eqsubst_all ctxt thms = K ((REPEAT o HEADGOAL) (EqSubst.eqsubst_asm_tac ctxt [0] thms)) THEN' K ((REPEAT o HEADGOAL) (EqSubst.eqsubst_tac ctxt [0] thms)) fun simplify_tac ctxt thms = ctxt |> empty_simpset |> put_simpset HOL_basic_ss |> (fn ctxt => ctxt addsimps @{thms simp_thms} addsimps thms) |> Simplifier.asm_full_simp_tac (* sko_forall requires the assumptions to be able to prove the equivalence in case of double skolemization. See comment below. *) fun requires_subproof_assms _ t = member (op =) ["refl", "sko_forall", "sko_ex", "cong"] t fun requires_local_input _ t = member (op =) [Verit_Proof.local_input_rule] t (*This is a weaker simplification form. It is weaker, but is also less likely to loop*) fun partial_simplify_tac ctxt thms = ctxt |> empty_simpset |> put_simpset HOL_basic_ss |> (fn ctxt => ctxt addsimps @{thms simp_thms} addsimps thms) |> Simplifier.full_simp_tac val try_provers = SMT_Replay_Methods.try_provers "verit" fun TRY' tac = fn i => TRY (tac i) fun REPEAT' tac = fn i => REPEAT (tac i) fun REPEAT_CHANGED tac = fn i => REPEAT (CHANGED (tac i)) (* Bind *) (*The bind rule is non-obvious due to the handling of quantifiers: "\x y a. x = y ==> (\b. P a b x) \ (\b. P' a b y)" ------------------------------------------------------ \a. (\b x. P a b x) \ (\b y. P' a b y) is a valid application.*) val bind_thms = [@{lemma \(\x x'. x = x' \ P x = Q x') \ (\x. P x) = (\y. Q y)\ by blast}, @{lemma \(\x x'. x = x' \ P x = Q x') \ (\x. P x) = (\y. Q y)\ by blast}, @{lemma \(\x x'. x = x' \ P x = Q x') \ (\x. P x = Q x)\ by blast}, @{lemma \(\x x'. x = x' \ P x = Q x') \ (\x. P x = Q x)\ by blast}] val bind_thms_same_name = [@{lemma \(\x. P x = Q x) \ (\x. P x) = (\y. Q y)\ by blast}, @{lemma \(\x. P x = Q x) \ (\x. P x) = (\y. Q y)\ by blast}, @{lemma \(\x. P x = Q x) \ (\x. P x = Q x)\ by blast}, @{lemma \(\x. P x = Q x) \ (\x. P x = Q x)\ by blast}] fun extract_quantified_names_q (_ $ Abs (name, _, t)) = apfst (curry (op ::) name) (extract_quantified_names_q t) | extract_quantified_names_q t = ([], t) fun extract_forall_quantified_names_q (Const(\<^const_name>\HOL.All\, _) $ Abs (name, ty, t)) = (name, ty) :: (extract_forall_quantified_names_q t) | extract_forall_quantified_names_q _ = [] fun extract_all_forall_quantified_names_q (Const(\<^const_name>\HOL.All\, _) $ Abs (name, _, t)) = name :: (extract_all_forall_quantified_names_q t) | extract_all_forall_quantified_names_q (t $ u) = extract_all_forall_quantified_names_q t @ extract_all_forall_quantified_names_q u | extract_all_forall_quantified_names_q _ = [] val extract_quantified_names_ba = SMT_Replay_Methods.dest_prop #> extract_quantified_names_q ##> HOLogic.dest_eq ##> fst ##> extract_quantified_names_q ##> fst val extract_quantified_names = extract_quantified_names_ba #> (op @) val extract_all_forall_quantified_names = SMT_Replay_Methods.dest_prop #> HOLogic.dest_eq #> fst #> extract_all_forall_quantified_names_q fun extract_all_exists_quantified_names_q (Const(\<^const_name>\HOL.Ex\, _) $ Abs (name, _, t)) = name :: (extract_all_exists_quantified_names_q t) | extract_all_exists_quantified_names_q (t $ u) = extract_all_exists_quantified_names_q t @ extract_all_exists_quantified_names_q u | extract_all_exists_quantified_names_q _ = [] val extract_all_exists_quantified_names = SMT_Replay_Methods.dest_prop #> HOLogic.dest_eq #> fst #> extract_all_exists_quantified_names_q val extract_bind_names = HOLogic.dest_eq #> apply2 (fn (Free (name, _)) => name) fun combine_quant ctxt ((n1, n2) :: bounds) (n1' :: formula) = TRY' (if n1 = n1' then if n1 <> n2 then resolve_tac ctxt bind_thms THEN' TRY'(resolve_tac ctxt [@{thm refl}]) THEN' combine_quant ctxt bounds formula else resolve_tac ctxt bind_thms_same_name THEN' combine_quant ctxt bounds formula else resolve_tac ctxt @{thms allI} THEN' combine_quant ctxt ((n1, n2) :: bounds) formula) | combine_quant _ _ _ = K all_tac fun bind_quants ctxt args t = combine_quant ctxt (map extract_bind_names args) (extract_quantified_names t) fun generalize_prems_q [] prems = prems | generalize_prems_q (_ :: quants) prems = generalize_prems_q quants (@{thm spec} OF [prems]) fun generalize_prems t = generalize_prems_q (fst (extract_quantified_names_ba t)) fun bind ctxt [prems] args t = SMT_Replay_Methods.prove ctxt t (fn _ => bind_quants ctxt args t THEN' TRY' (SOLVED' (resolve_tac ctxt [generalize_prems t prems] THEN_ALL_NEW TRY' (assume_tac ctxt ORELSE' resolve_tac ctxt @{thms refl})))) | bind ctxt thms _ t = replay_error ctxt "invalid bind application" Bind thms t (* Congruence/Refl *) fun cong ctxt thms = try_provers ctxt (string_of_verit_rule Cong) [ ("basic", SMT_Replay_Methods.cong_basic ctxt thms), ("unfolding then reflexivity", SMT_Replay_Methods.cong_unfolding_trivial ctxt thms), ("unfolding then auto", SMT_Replay_Methods.cong_unfolding_first ctxt thms), ("full", SMT_Replay_Methods.cong_full ctxt thms)] thms fun refl ctxt thm t = (case find_first (fn thm => t = Thm.full_prop_of thm) thm of SOME thm => thm | NONE => (case try (fn t => SMT_Replay_Methods.match_instantiate ctxt t @{thm refl}) t of NONE => cong ctxt thm t | SOME thm => thm)) (* Instantiation *) local fun dropWhile _ [] = [] | dropWhile f (x :: xs) = if f x then dropWhile f xs else x :: xs in fun forall_inst ctxt _ _ insts t = let fun instantiate_and_solve i ({context = ctxt, prems = [prem], ...}: Subgoal.focus) = let val t = Thm.prop_of prem val quants = t |> SMT_Replay_Methods.dest_prop |> extract_forall_quantified_names_q val insts = map (Symtab.lookup insts o fst) (rev quants) |> dropWhile (curry (op =) NONE) |> rev fun option_map _ NONE = NONE | option_map f (SOME a) = SOME (f a) fun instantiate_with inst prem = Drule.infer_instantiate' ctxt [NONE, inst] @{thm spec} OF [prem] val inst_thm = fold instantiate_with (map (option_map (Thm.cterm_of ctxt)) insts) prem in (Method.insert_tac ctxt [inst_thm] THEN' TRY' (fn i => assume_tac ctxt i) THEN' TRY' (partial_simplify_tac ctxt @{thms eq_commute})) i end | instantiate_and_solve _ ({context = ctxt, prems = thms, ...}: Subgoal.focus) = replay_error ctxt "invalid application" Forall_Inst thms t in SMT_Replay_Methods.prove ctxt t (fn _ => match_tac ctxt [@{thm disj_not1} RSN (1, @{thm iffD2}) OF [@{thm impI}]] THEN' (fn i => Subgoal.FOCUS (instantiate_and_solve i) ctxt i)) end end (* Or *) fun or _ (thm :: _) _ = thm | or ctxt thms t = replay_error ctxt "invalid bind application" Or thms t (* Implication *) val implies_pos_thm = [@{lemma \\(A \ B) \ \A \ B\ by blast}, @{lemma \\(\A \ B) \ A \ B\ by blast}] fun implies_pos ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => resolve_tac ctxt implies_pos_thm) fun extract_rewrite_rule_assumption _ thms = let fun is_rewrite_rule thm = (case Thm.prop_of thm of \<^term>\Trueprop\ $ (Const(\<^const_name>\HOL.eq\, _) $ _ $ Free(_, _)) => true | _ => false) fun is_context_rule thm = (case Thm.prop_of thm of \<^term>\Trueprop\ $ (Const(\<^const_name>\HOL.eq\, _) $ Free(_, _) $ Free(_, _)) => true | _ => false) val ctxt_eq = thms |> filter is_context_rule val rew = thms |> filter_out is_context_rule |> filter is_rewrite_rule in (ctxt_eq, rew) end local fun rewrite_all_skolems thm_indirect ctxt (SOME thm :: thms) = EqSubst.eqsubst_tac ctxt [0] [thm_indirect OF [thm]] THEN' (partial_simplify_tac ctxt (@{thms eq_commute})) THEN' rewrite_all_skolems thm_indirect ctxt thms | rewrite_all_skolems thm_indirect ctxt (NONE :: thms) = rewrite_all_skolems thm_indirect ctxt thms | rewrite_all_skolems _ _ [] = K (all_tac) fun extract_var_name (thm :: thms) = let val name = Thm.concl_of thm |> SMT_Replay_Methods.dest_prop |> HOLogic.dest_eq |> fst |> (fn Const(_,_) $ Abs(name, _, _) => [(name,@{thm sym} OF [thm])] | _ => []) in name :: extract_var_name thms end | extract_var_name [] = [] fun skolem_tac extractor thm1 thm2 ctxt thms t = let val (ctxt_eq, ts) = extract_rewrite_rule_assumption ctxt thms fun ordered_definitions () = let val var_order = extractor t val thm_names_with_var = extract_var_name ts |> flat in map (AList.lookup (op =) thm_names_with_var) var_order end in SMT_Replay_Methods.prove ctxt t (fn _ => K (unfold_tac ctxt ctxt_eq) THEN' ((SOLVED' (K (unfold_tac ctxt (map (fn thm => thm1 OF [@{thm sym} OF [thm]]) ts)))) ORELSE' (rewrite_all_skolems thm2 ctxt (ordered_definitions ()) THEN' partial_simplify_tac ctxt @{thms eq_commute}))) end in val skolem_forall = skolem_tac extract_all_forall_quantified_names @{thm verit_sko_forall_indirect} @{thm verit_sko_forall_indirect2} val skolem_ex = skolem_tac extract_all_exists_quantified_names @{thm verit_sko_ex_indirect} @{thm verit_sko_ex_indirect2} end fun eq_reflexive ctxt _ t = SMT_Replay_Methods.match_instantiate ctxt t @{thm refl} local fun not_not_prove ctxt _ = K (unfold_tac ctxt @{thms not_not}) THEN' match_tac ctxt @{thms verit_or_simplify_1} fun duplicate_literals_prove ctxt prems = Method.insert_tac ctxt prems THEN' match_tac ctxt @{thms ccontr} THEN' K (unfold_tac ctxt @{thms de_Morgan_disj not_not}) THEN' TRY o CHANGED_PROP o REPEAT_ALL_NEW (ematch_tac ctxt @{thms conjE}) THEN' CHANGED_PROP o REPEAT_ALL_NEW (ematch_tac ctxt @{thms disjE}) THEN' REPEAT' (ematch_tac ctxt @{thms notE} THEN' TRY' (assume_tac ctxt)) fun tautological_clause_prove ctxt _ = match_tac ctxt @{thms verit_or_neg} THEN' K (unfold_tac ctxt @{thms not_not disj_assoc[symmetric]}) THEN' TRY' (match_tac ctxt @{thms notE} THEN_ALL_NEW assume_tac ctxt) + + val theory_resolution2_lemma = @{lemma \a \ a = b \ b\ by blast} in fun prove_abstract abstracter tac ctxt thms t = let val thms = map (Conv.fconv_rule Thm.eta_long_conversion) thms val t' = Thm.eta_long_conversion (Object_Logic.dest_judgment ctxt (Thm.cterm_of ctxt t)) val (_, t2) = Logic.dest_equals (Thm.prop_of t') val thm = SMT_Replay_Methods.prove_abstract ctxt thms t2 tac ( fold_map (abstracter o SMT_Replay_Methods.dest_thm) thms ##>> abstracter (SMT_Replay_Methods.dest_prop t2)) in @{thm verit_Pure_trans} OF [t', thm] end val not_not = prove_abstract SMT_Replay_Methods.abstract_bool_shallow not_not_prove val tautological_clause = prove_abstract SMT_Replay_Methods.abstract_bool_shallow tautological_clause_prove val duplicate_literals = prove_abstract SMT_Replay_Methods.abstract_bool_shallow duplicate_literals_prove val unit_res = prove_abstract SMT_Replay_Methods.abstract_bool_shallow SMT_Replay_Methods.prop_tac +(*match_instantiate does not work*) +fun theory_resolution2 ctxt prems t = + SMT_Replay_Methods.prove ctxt t (fn _ => match_tac ctxt [theory_resolution2_lemma OF prems]) + end fun normalized_input ctxt prems t = SMT_Replay_Methods.prove ctxt t (fn _ => Method.insert_tac ctxt prems THEN' TRY' (K (unfold_tac ctxt @{thms SMT.trigger_def})) THEN' TRY' (partial_simplify_tac ctxt @{thms eq_commute})) val false_rule_thm = @{lemma \\False\ by blast} fun false_rule ctxt _ t = SMT_Replay_Methods.match_instantiate ctxt t false_rule_thm (* Transitivity *) val trans_bool_thm = @{lemma \P = Q \ Q \ P\ by blast} fun trans ctxt thms t = let val prop_of = HOLogic.dest_Trueprop o Thm.full_prop_of fun combine_thms [thm1, thm2] = (case (prop_of thm1, prop_of thm2) of ((Const(\<^const_name>\HOL.eq\, _) $ t1 $ t2), (Const(\<^const_name>\HOL.eq\, _) $ t3 $ t4)) => if t2 aconv t3 then thm1 RSN (1, thm2 RSN (2, @{thm trans})) else if t2 aconv t4 then thm1 RSN ((1, ((thm2 RS sym)) RSN (2, @{thm trans}))) else if t1 aconv t4 then thm2 RSN (1, thm1 RSN (2, @{thm trans})) else raise Fail "invalid trans theorem" | _ => trans_bool_thm OF [thm1, thm2]) | combine_thms (thm1 :: thm2 :: thms) = combine_thms (combine_thms [thm1, thm2] :: thms) | combine_thms thms = replay_error ctxt "invalid bind application" Trans thms t val t' = Thm.eta_long_conversion (Object_Logic.dest_judgment ctxt (Thm.cterm_of ctxt t)) val (_, t2) = Logic.dest_equals (Thm.prop_of t') val thms = map (Conv.fconv_rule Thm.eta_long_conversion) thms val trans_thm = combine_thms thms in (case (prop_of trans_thm, t2) of ((Const(\<^const_name>\HOL.eq\, _) $ t1 $ _), (Const(\<^const_name>\HOL.eq\, _) $ t3 $ _)) => if t1 aconv t3 then trans_thm else trans_thm RS sym | _ => trans_thm (*to be on the safe side*)) end fun tmp_AC_rule ctxt thms t = SMT_Replay_Methods.prove ctxt t (fn _ => Method.insert_tac ctxt thms THEN' REPEAT_ALL_NEW (partial_simplify_tac ctxt @{thms eq_commute} THEN' TRY' (simplify_tac ctxt @{thms ac_simps conj_ac}) THEN' TRY' (Classical.fast_tac ctxt))) (* And/Or *) local fun not_and_rule_prove ctxt prems = Method.insert_tac ctxt prems THEN' K (unfold_tac ctxt @{thms de_Morgan_conj}) THEN_ALL_NEW TRY' (assume_tac ctxt) fun or_pos_prove ctxt _ = K (unfold_tac ctxt @{thms de_Morgan_disj not_not}) THEN' match_tac ctxt @{thms verit_and_pos} THEN' K (unfold_tac ctxt @{thms de_Morgan_conj de_Morgan_disj not_not}) THEN' TRY' (assume_tac ctxt) fun not_or_rule_prove ctxt prems = Method.insert_tac ctxt prems THEN' K (unfold_tac ctxt @{thms de_Morgan_disj not_not}) THEN' TRY' (REPEAT' (match_tac ctxt @{thms conjI})) THEN_ALL_NEW ((REPEAT' (ematch_tac ctxt @{thms conjE})) THEN' TRY' (assume_tac ctxt)) fun and_rule_prove ctxt prems = Method.insert_tac ctxt prems THEN' (fn i => REPEAT (dresolve_tac ctxt @{thms conjE} i THEN assume_tac ctxt (i+1))) THEN' TRY' (assume_tac ctxt) fun and_neg_rule_prove ctxt _ = match_tac ctxt @{thms verit_and_neg} THEN' K (unfold_tac ctxt @{thms de_Morgan_conj not_not}) THEN' TRY' (assume_tac ctxt) fun prover tac = prove_abstract SMT_Replay_Methods.abstract_prop tac in val and_rule = prover and_rule_prove val not_and_rule = prover not_and_rule_prove val not_or_rule = prover not_or_rule_prove val or_pos_rule = prover or_pos_prove val and_neg_rule = prover and_neg_rule_prove val or_neg_rule = prove_abstract SMT_Replay_Methods.abstract_bool (fn ctxt => fn _ => resolve_tac ctxt @{thms verit_or_neg} THEN' K (unfold_tac ctxt @{thms not_not}) THEN_ALL_NEW (REPEAT' (SOLVED' (match_tac ctxt @{thms disjI1} THEN_ALL_NEW assume_tac ctxt) ORELSE' (match_tac ctxt @{thms disjI2} THEN' TRY' (assume_tac ctxt))))) fun and_pos ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => REPEAT_CHANGED (resolve_tac ctxt @{thms verit_and_pos}) THEN' TRY' (assume_tac ctxt)) end (* Equivalence Transformation *) local fun prove_equiv equiv_thm ctxt [thm] t = SMT_Replay_Methods.prove ctxt t (fn _ => Method.insert_tac ctxt [equiv_thm OF [thm]] THEN' TRY' (assume_tac ctxt)) | prove_equiv _ ctxt thms t = replay_error ctxt "invalid application in some equiv rule" Unsupported thms t in val not_equiv1 = prove_equiv @{lemma \\(A \ B) \ A \ B\ by blast} val not_equiv2 = prove_equiv @{lemma \\(A \ B) \ \A \ \B\ by blast} val equiv1 = prove_equiv @{lemma \(A \ B) \ \A \ B\ by blast} val equiv2 = prove_equiv @{lemma \(A \ B) \ A \ \B\ by blast} val not_implies1 = prove_equiv @{lemma \\(A \ B) \ A\ by blast} val not_implies2 = prove_equiv @{lemma \\(A \B) \ \B\ by blast} end (* Equivalence Lemma *) (*equiv_pos2 is very important for performance. We have tried various tactics, including a specialisation of SMT_Replay_Methods.match_instantiate, but there never was a measurable and consistent gain.*) local fun prove_equiv_pos_neg2 thm ctxt _ t = SMT_Replay_Methods.match_instantiate ctxt t thm in val equiv_pos1_thm = @{lemma \\(a \ b) \ a \ \b\ by blast+} val equiv_pos1 = prove_equiv_pos_neg2 equiv_pos1_thm val equiv_pos2_thm = @{lemma \\a b. (a \ b) \ \a \ b\ by blast+} val equiv_pos2 = prove_equiv_pos_neg2 equiv_pos2_thm val equiv_neg1_thm = @{lemma \(a \ b) \ \a \ \b\ by blast+} val equiv_neg1 = prove_equiv_pos_neg2 equiv_neg1_thm val equiv_neg2_thm = @{lemma \(a \ b) \ a \ b\ by blast} val equiv_neg2 = prove_equiv_pos_neg2 equiv_neg2_thm end local fun implies_pos_neg_term ctxt thm (\<^term>\Trueprop\ $ (\<^term>\HOL.disj\ $ (\<^term>\HOL.implies\ $ a $ b) $ _)) = Drule.infer_instantiate' ctxt (map (SOME o Thm.cterm_of ctxt) [a, b]) thm | implies_pos_neg_term ctxt thm t = replay_error ctxt "invalid application in Implies" Unsupported [thm] t fun prove_implies_pos_neg thm ctxt _ t = let val thm = implies_pos_neg_term ctxt thm t in SMT_Replay_Methods.prove ctxt t (fn _ => Method.insert_tac ctxt [thm] THEN' TRY' (assume_tac ctxt)) end in val implies_neg1_thm = @{lemma \(a \ b) \ a\ by blast} val implies_neg1 = prove_implies_pos_neg implies_neg1_thm val implies_neg2_thm = @{lemma \(a \ b) \ \b\ by blast} val implies_neg2 = prove_implies_pos_neg implies_neg2_thm val implies_thm = @{lemma \(a \ b) \ \a \ b\ by blast} fun implies_rules ctxt prems t = SMT_Replay_Methods.prove ctxt t (fn _ => Method.insert_tac ctxt [implies_thm OF prems] THEN' TRY' (assume_tac ctxt)) end (* BFun *) local val bfun_theorems = @{thms verit_bfun_elim} in fun bfun_elim ctxt prems t = SMT_Replay_Methods.prove ctxt t (fn _ => Method.insert_tac ctxt prems THEN' TRY' (eqsubst_all ctxt bfun_theorems) THEN' TRY' (simplify_tac ctxt @{thms eq_commute all_conj_distrib ex_disj_distrib})) end (* If-Then-Else *) local fun prove_ite ite_thm thm ctxt = resolve_tac ctxt [ite_thm OF [thm]] THEN' K (unfold_tac ctxt @{thms not_not}) THEN' TRY' (assume_tac ctxt) in val ite_pos1_thm = @{lemma \\(if x then P else Q) \ x \ Q\ by auto} fun ite_pos1 ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => resolve_tac ctxt [ite_pos1_thm]) val ite_pos2_thms = @{lemma \\(if x then P else Q) \ \x \ P\ \\(if \x then P else Q) \ x \ P\ by auto} fun ite_pos2 ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => resolve_tac ctxt ite_pos2_thms) val ite_neg1_thms = @{lemma \(if x then P else Q) \ x \ \Q\ \(if x then P else \Q) \ x \ Q\ by auto} fun ite_neg1 ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => resolve_tac ctxt ite_neg1_thms) val ite_neg2_thms = @{lemma \(if x then P else Q) \ \x \ \P\ \(if \x then P else Q) \ x \ \P\ \(if x then \P else Q) \ \x \ P\ \(if \x then \P else Q) \ x \ P\ by auto} fun ite_neg2 ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => resolve_tac ctxt ite_neg2_thms) val ite1_thm = @{lemma \(if x then P else Q) \ x \ Q\ by (auto split: if_splits) } fun ite1 ctxt [thm] t = SMT_Replay_Methods.prove ctxt t (fn _ => prove_ite ite1_thm thm ctxt) val ite2_thm = @{lemma \(if x then P else Q) \ \x \ P\ by (auto split: if_splits) } fun ite2 ctxt [thm] t = SMT_Replay_Methods.prove ctxt t (fn _ => prove_ite ite2_thm thm ctxt) val not_ite1_thm = @{lemma \\(if x then P else Q) \ x \ \Q\ by (auto split: if_splits) } fun not_ite1 ctxt [thm] t = SMT_Replay_Methods.prove ctxt t (fn _ => prove_ite not_ite1_thm thm ctxt) val not_ite2_thm = @{lemma \\(if x then P else Q) \ \x \ \P\ by (auto split: if_splits) } fun not_ite2 ctxt [thm] t = SMT_Replay_Methods.prove ctxt t (fn _ => prove_ite not_ite2_thm thm ctxt) (*ite_intro can introduce new terms that are in the proof exactly the sames as the old one, but are not internally, hence the possible reordering.*) fun ite_intro ctxt _ t = let fun simplify_ite ctxt thms = ctxt |> empty_simpset |> put_simpset HOL_basic_ss |> (fn ctxt => ctxt addsimps thms @ @{thms if_True if_False refl simp_thms if_cancel}) |> Raw_Simplifier.add_eqcong @{thm verit_ite_if_cong} |> Simplifier.full_simp_tac in SMT_Replay_Methods.prove ctxt t (fn _ => simplify_ite ctxt [] THEN' TRY' (simplify_ite ctxt @{thms eq_commute})) end end (* Quantifiers *) local val rm_unused = @{lemma \(\x. P) = P\ \(\x. P) = P\ by blast+} fun qnt_cnf_tac ctxt = simplify_tac ctxt @{thms de_Morgan_conj de_Morgan_disj imp_conv_disj iff_conv_conj_imp if_bool_eq_disj ex_simps all_simps ex_disj_distrib verit_connective_def(3) all_conj_distrib} THEN' TRY' (Blast.blast_tac ctxt) in fun qnt_rm_unused ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => K (unfold_tac ctxt rm_unused)) fun onepoint ctxt prems t = SMT_Replay_Methods.prove ctxt t (fn _ => Method.insert_tac ctxt prems THEN' Simplifier.full_simp_tac (put_simpset HOL_basic_ss (empty_simpset ctxt) addsimps @{thms HOL.simp_thms HOL.all_simps} addsimprocs [@{simproc HOL.defined_All}, @{simproc HOL.defined_Ex}]) THEN' TRY' (Blast.blast_tac ctxt) THEN' TRY' (Metis_Tactic.metis_tac [] ATP_Problem_Generate.combsN ctxt [])) fun qnt_join ctxt _ t = SMT_Replay_Methods.prove ctxt t Classical.fast_tac fun qnt_cnf ctxt _ t = SMT_Replay_Methods.prove ctxt t qnt_cnf_tac fun qnt_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => partial_simplify_tac ctxt []) end (* Equality *) fun eq_transitive ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => REPEAT_CHANGED (resolve_tac ctxt [@{thm disj_not1} RSN (1, @{thm iffD2}) OF @{thms impI}]) THEN' REPEAT' (resolve_tac ctxt @{thms impI}) THEN' REPEAT' (eresolve_tac ctxt @{thms conjI}) THEN' REPEAT' (fn i => dresolve_tac ctxt @{thms verit_eq_transitive} i THEN assume_tac ctxt (i+1)) THEN' resolve_tac ctxt @{thms refl}) local fun find_rew rews t t' = (case AList.lookup (op =) rews (t, t') of SOME thm => SOME (thm COMP @{thm symmetric}) | NONE => (case AList.lookup (op =) rews (t', t) of SOME thm => SOME thm | NONE => NONE)) fun eq_pred_conv rews t ctxt ctrm = (case find_rew rews t (Thm.term_of ctrm) of SOME thm => Conv.rewr_conv thm ctrm | NONE => (case t of f $ arg => (Conv.fun_conv (eq_pred_conv rews f ctxt) then_conv Conv.arg_conv (eq_pred_conv rews arg ctxt)) ctrm | _ => Conv.all_conv ctrm)) fun eq_pred_rewrite_tac ({context = ctxt, prems, concl, ...}: Subgoal.focus) = let val rews = prems |> map_filter (try (apfst (HOLogic.dest_eq o Thm.term_of o Object_Logic.dest_judgment ctxt o Thm.cconcl_of) o `(fn x => x))) |> map (apsnd (fn x => @{thm eq_reflection} OF [x])) fun conv_left conv = Conv.arg_conv (Conv.arg_conv conv) fun conv_left_neg conv = Conv.arg_conv (Conv.arg_conv (Conv.arg_conv conv)) val (t1, conv_term) = (case Thm.term_of (Object_Logic.dest_judgment ctxt concl) of Const(_, _) $ (Const(\<^const_name>\HOL.Not\, _) $ t1) $ _ => (t1, conv_left) | Const(_, _) $ t1 $ (Const(\<^const_name>\HOL.Not\, _) $ _) => (t1, conv_left_neg) | Const(_, _) $ t1 $ _ => (t1, conv_left) | t1 => (t1, conv_left)) fun throwing_CONVERSION cv i st = Seq.single (Conv.gconv_rule cv i st) in throwing_CONVERSION (conv_term (eq_pred_conv rews t1 ctxt)) end in fun eq_congruent_pred ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => REPEAT' (resolve_tac ctxt [@{thm disj_not1[of \_ = _\]} RSN (1, @{thm iffD2}) OF @{thms impI}]) THEN' (fn i => Subgoal.FOCUS (fn focus => eq_pred_rewrite_tac focus i) ctxt i) THEN' (resolve_tac ctxt @{thms refl excluded_middle excluded_middle[of \\_\, unfolded not_not]} ORELSE' assume_tac ctxt)) val eq_congruent = eq_congruent_pred end (* Subproof *) fun subproof ctxt [prem] t = SMT_Replay_Methods.prove ctxt t (fn _ => (resolve_tac ctxt [@{thm disj_not1} RSN (1, @{thm iffD2}) OF [@{thm impI}], @{thm disj_not1[of \\_\, unfolded not_not]} RSN (1, @{thm iffD2}) OF [@{thm impI}]] THEN' resolve_tac ctxt [prem] THEN_ALL_NEW assume_tac ctxt THEN' TRY' (assume_tac ctxt)) ORELSE' TRY' (Method.insert_tac ctxt [prem] THEN' Blast.blast_tac ctxt)) | subproof ctxt prems t = replay_error ctxt "invalid application, only one assumption expected" Subproof prems t (* Simplifying Steps *) (* The reconstruction is a bit tricky: At first we only rewrite only based on the rules that are passed as argument. Then we simply use simp_thms to reconstruct all the proofs (and these theorems cover all the simplification below). *) local fun rewrite_only_thms ctxt thms = ctxt |> empty_simpset |> put_simpset HOL_basic_ss |> (fn ctxt => ctxt addsimps thms) |> Simplifier.full_simp_tac fun rewrite_thms ctxt thms = ctxt |> empty_simpset |> put_simpset HOL_basic_ss |> Raw_Simplifier.add_eqcong @{thm eq_reflection[OF imp_cong]} |> (fn ctxt => ctxt addsimps thms addsimps @{thms simp_thms}) |> Simplifier.full_simp_tac fun chain_rewrite_thms ctxt thms = TRY' (rewrite_only_thms ctxt thms) THEN' TRY' (rewrite_thms ctxt thms) fun chain_rewrite_two_step_with_ac_simps ctxt thms1 thms2 = TRY' (rewrite_only_thms ctxt thms1) THEN' TRY' (rewrite_thms ctxt thms2) fun chain_rewrite_thms_two_step ctxt thms1 thms2 thms3 thms4 = chain_rewrite_two_step_with_ac_simps ctxt thms1 thms2 THEN' TRY' (chain_rewrite_two_step_with_ac_simps ctxt thms3 thms4) val imp_refl = @{lemma \(P \ P) = True\ by blast} in fun rewrite_bool_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (chain_rewrite_thms ctxt @{thms verit_bool_simplify})) fun rewrite_and_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (chain_rewrite_two_step_with_ac_simps ctxt @{thms verit_and_simplify verit_and_simplify1} @{thms verit_and_simplify})) fun rewrite_or_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (chain_rewrite_two_step_with_ac_simps ctxt @{thms verit_or_simplify verit_or_simplify_1} @{thms verit_or_simplify}) THEN' TRY' (REPEAT' (match_tac ctxt @{thms verit_and_pos}) THEN' assume_tac ctxt)) fun rewrite_not_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (rewrite_only_thms ctxt @{thms verit_not_simplify})) fun rewrite_equiv_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (rewrite_only_thms ctxt @{thms verit_equiv_simplify})) fun rewrite_eq_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (chain_rewrite_two_step_with_ac_simps ctxt @{thms verit_eq_simplify} (Named_Theorems.get ctxt @{named_theorems ac_simps}))) fun rewrite_implies_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (rewrite_only_thms ctxt @{thms verit_implies_simplify})) (* It is more efficient to first fold the implication symbols. That is however not enough when symbols appears within expressions, hence we also unfold implications in the other direction. *) fun rewrite_connective_def ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => chain_rewrite_thms_two_step ctxt (imp_refl :: @{thms not_not verit_connective_def[symmetric]}) (@{thms verit_connective_def[symmetric]}) (imp_refl :: @{thms not_not verit_connective_def}) (@{thms verit_connective_def})) fun rewrite_minus_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => chain_rewrite_two_step_with_ac_simps ctxt @{thms arith_simps verit_minus_simplify} (Named_Theorems.get ctxt @{named_theorems ac_simps} @ @{thms numerals arith_simps arith_special numeral_class.numeral.numeral_One})) fun rewrite_comp_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => chain_rewrite_thms ctxt @{thms verit_comp_simplify}) fun rewrite_ite_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => (rewrite_only_thms ctxt @{thms verit_ite_simplify})) end (* Simplifications *) local fun simplify_arith ctxt thms = partial_simplify_tac ctxt (thms @ Named_Theorems.get ctxt @{named_theorems ac_simps} @ @{thms arith_simps}) in fun sum_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => simplify_arith ctxt @{thms verit_sum_simplify arith_special}) fun prod_simplify ctxt _ t = SMT_Replay_Methods.prove ctxt t (fn _ => simplify_arith ctxt @{thms verit_prod_simplify}) end (* Arithmetics *) local val la_rw_eq_thm = @{lemma \(a :: nat) = b \ (a \ b) \ (a \ b)\ by auto} in fun la_rw_eq ctxt _ t = SMT_Replay_Methods.match_instantiate ctxt t la_rw_eq_thm fun la_generic_prove args ctxt _ = SMT_Replay_Arith.la_farkas args ctxt fun la_generic ctxt _ args = prove_abstract (SMT_Replay_Methods.abstract_arith_shallow ctxt) (la_generic_prove args) ctxt [] fun lia_generic ctxt _ t = SMT_Replay_Methods.prove_arith_rewrite SMT_Replay_Methods.abstract_neq ctxt t fun la_disequality ctxt _ t = SMT_Replay_Methods.match_instantiate ctxt t @{thm verit_la_disequality} end (* Combining all together *) fun unsupported rule ctxt thms _ _ _ = SMT_Replay_Methods.replay_error ctxt "Unsupported verit rule" rule thms fun ignore_args f ctxt thm _ _ _ t = f ctxt thm t fun ignore_decls f ctxt thm args insts _ t = f ctxt thm args insts t fun ignore_insts f ctxt thm args _ _ t = f ctxt thm args t fun choose And = ignore_args and_rule | choose And_Neg = ignore_args and_neg_rule | choose And_Pos = ignore_args and_pos | choose And_Simplify = ignore_args rewrite_and_simplify | choose Bind = ignore_insts bind | choose Bool_Simplify = ignore_args rewrite_bool_simplify | choose Comp_Simplify = ignore_args rewrite_comp_simplify | choose Cong = ignore_args cong | choose Connective_Def = ignore_args rewrite_connective_def | choose Duplicate_Literals = ignore_args duplicate_literals | choose Eq_Congruent = ignore_args eq_congruent | choose Eq_Congruent_Pred = ignore_args eq_congruent_pred | choose Eq_Reflexive = ignore_args eq_reflexive | choose Eq_Simplify = ignore_args rewrite_eq_simplify | choose Eq_Transitive = ignore_args eq_transitive | choose Equiv1 = ignore_args equiv1 | choose Equiv2 = ignore_args equiv2 | choose Equiv_neg1 = ignore_args equiv_neg1 | choose Equiv_neg2 = ignore_args equiv_neg2 | choose Equiv_pos1 = ignore_args equiv_pos1 | choose Equiv_pos2 = ignore_args equiv_pos2 | choose Equiv_Simplify = ignore_args rewrite_equiv_simplify | choose False = ignore_args false_rule | choose Forall_Inst = ignore_decls forall_inst | choose Implies = ignore_args implies_rules | choose Implies_Neg1 = ignore_args implies_neg1 | choose Implies_Neg2 = ignore_args implies_neg2 | choose Implies_Pos = ignore_args implies_pos | choose Implies_Simplify = ignore_args rewrite_implies_simplify | choose ITE1 = ignore_args ite1 | choose ITE2 = ignore_args ite2 | choose ITE_Intro = ignore_args ite_intro | choose ITE_Neg1 = ignore_args ite_neg1 | choose ITE_Neg2 = ignore_args ite_neg2 | choose ITE_Pos1 = ignore_args ite_pos1 | choose ITE_Pos2 = ignore_args ite_pos2 | choose ITE_Simplify = ignore_args rewrite_ite_simplify | choose LA_Disequality = ignore_args la_disequality | choose LA_Generic = ignore_insts la_generic | choose LA_RW_Eq = ignore_args la_rw_eq | choose LA_Tautology = ignore_args SMT_Replay_Methods.arith_th_lemma_wo_shallow | choose LA_Totality = ignore_args SMT_Replay_Methods.arith_th_lemma_wo_shallow | choose LIA_Generic = ignore_args lia_generic | choose Local_Input = ignore_args refl | choose Minus_Simplify = ignore_args rewrite_minus_simplify | choose NLA_Generic = ignore_args SMT_Replay_Methods.arith_th_lemma_wo_shallow | choose Normalized_Input = ignore_args normalized_input | choose Not_And = ignore_args not_and_rule | choose Not_Equiv1 = ignore_args not_equiv1 | choose Not_Equiv2 = ignore_args not_equiv2 | choose Not_Implies1 = ignore_args not_implies1 | choose Not_Implies2 = ignore_args not_implies2 | choose Not_ITE1 = ignore_args not_ite1 | choose Not_ITE2 = ignore_args not_ite2 | choose Not_Not = ignore_args not_not | choose Not_Or = ignore_args not_or_rule | choose Not_Simplify = ignore_args rewrite_not_simplify | choose Or = ignore_args or | choose Or_Neg = ignore_args or_neg_rule | choose Or_Pos = ignore_args or_pos_rule | choose Or_Simplify = ignore_args rewrite_or_simplify + | choose Theory_Resolution2 = ignore_args theory_resolution2 | choose Prod_Simplify = ignore_args prod_simplify | choose Qnt_Join = ignore_args qnt_join | choose Qnt_Rm_Unused = ignore_args qnt_rm_unused | choose Onepoint = ignore_args onepoint | choose Qnt_Simplify = ignore_args qnt_simplify | choose Refl = ignore_args refl | choose Resolution = ignore_args unit_res | choose Skolem_Ex = ignore_args skolem_ex | choose Skolem_Forall = ignore_args skolem_forall | choose Subproof = ignore_args subproof | choose Sum_Simplify = ignore_args sum_simplify | choose Tautological_Clause = ignore_args tautological_clause | choose Theory_Resolution = ignore_args unit_res | choose AC_Simp = ignore_args tmp_AC_rule | choose Bfun_Elim = ignore_args bfun_elim | choose Qnt_CNF = ignore_args qnt_cnf | choose Trans = ignore_args trans | choose r = unsupported (string_of_verit_rule r) type verit_method = Proof.context -> thm list -> term -> thm type abs_context = int * term Termtab.table fun with_tracing rule method ctxt thms args insts decls t = let val _ = SMT_Replay_Methods.trace_goal ctxt rule thms t in method ctxt thms args insts decls t end fun method_for rule = with_tracing rule (choose (verit_rule_of rule)) fun discharge ctxt [thm] t = SMT_Replay_Methods.prove ctxt t (fn _ => resolve_tac ctxt [thm] THEN_ALL_NEW (resolve_tac ctxt @{thms refl})) end;