(* Title: HOL/Tools/SMT/z3_replay_methods.ML Author: Sascha Boehme, TU Muenchen Author: Jasmin Blanchette, TU Muenchen
Proof methods for replaying Z3 proofs.
*)
signature Z3_REPLAY_METHODS = sig
(*methods for Z3 proof rules*) type z3_method = Proof.context -> thm list -> term -> thm val true_axiom: z3_method val mp: z3_method val refl: z3_method val symm: z3_method val trans: z3_method val cong: z3_method val quant_intro: z3_method val distrib: z3_method val and_elim: z3_method val not_or_elim: z3_method val rewrite: z3_method val rewrite_star: z3_method val pull_quant: z3_method val push_quant: z3_method val elim_unused: z3_method val dest_eq_res: z3_method val quant_inst: z3_method val lemma: z3_method val unit_res: z3_method val iff_true: z3_method val iff_false: z3_method val comm: z3_method val def_axiom: z3_method val apply_def: z3_method val iff_oeq: z3_method val nnf_pos: z3_method val nnf_neg: z3_method val mp_oeq: z3_method val arith_th_lemma: z3_method val th_lemma: string -> z3_method val method_for: Z3_Proof.z3_rule -> z3_method end;
val quant_intro_rules = @{lemma "(\x. P x = Q x) ==> (\x. P x) = (\x. Q x)" "(\x. P x = Q x) ==> (\x. P x) = (\x. Q x)" "(!!x. (\ P x) = Q x) \ (\(\x. P x)) = (\x. Q x)" "(\x. (\ P x) = Q x) ==> (\(\x. P x)) = (\x. Q x)"
by fast+}
fun quant_intro ctxt [thm] t =
SMT_Replay_Methods.prove ctxt t (K (REPEAT_ALL_NEW (resolve_tac ctxt (thm :: quant_intro_rules))))
| quant_intro ctxt thms t = replay_rule_error ctxt Z3_Proof.Quant_Intro thms t
(* distributivity of conjunctions and disjunctions *)
(* TODO: there are no tests with this proof rule *) fun distrib ctxt _ t =
SMT_Replay_Methods.prove_abstract' ctxt t prop_tac
(SMT_Replay_Methods.abstract_prop (dest_prop t))
(* elimination of conjunctions *)
fun and_elim ctxt [thm] t =
SMT_Replay_Methods.prove_abstract ctxt [thm] t prop_tac (
SMT_Replay_Methods.abstract_lit (dest_prop t) ##>>
SMT_Replay_Methods.abstract_conj (dest_thm thm) #>>
apfst single o swap)
| and_elim ctxt thms t = replay_rule_error ctxt Z3_Proof.And_Elim thms t
(* elimination of negated disjunctions *)
fun not_or_elim ctxt [thm] t =
SMT_Replay_Methods.prove_abstract ctxt [thm] t prop_tac (
SMT_Replay_Methods.abstract_lit (dest_prop t) ##>>
SMT_Replay_Methods.abstract_not SMT_Replay_Methods.abstract_disj (dest_thm thm) #>>
apfst single o swap)
| not_or_elim ctxt thms t =
replay_rule_error ctxt Z3_Proof.Not_Or_Elim thms t
(* rewriting *)
local
fun dest_all (Const (\<^const_name>\<open>HOL.All\<close>, _) $ Abs (_, T, t)) nctxt = let val (n, nctxt') = Name.variant "" nctxt val f = Free (n, T) val t' = Term.subst_bound (f, t) in dest_all t' nctxt' |>> cons f end
| dest_all t _ = ([], t)
fun dest_alls t = let val nctxt = Name.make_context (Term.add_free_names t []) val (lhs, rhs) = HOLogic.dest_eq (dest_prop t) val (ls, lhs') = dest_all lhs nctxt val (rs, rhs') = dest_all rhs nctxt in if eq_list (op aconv) (ls, rs) then SOME (ls, (HOLogic.mk_eq (lhs', rhs'))) else NONE end
fun forall_intr ctxt t thm = letval ct = Thm.cterm_of ctxt t in Thm.forall_intr ct thm COMP_INCR @{thm iff_allI} end
in
fun focus_eq f ctxt t =
(case dest_alls t of
NONE => f ctxt t
| SOME (vs, t') => fold (forall_intr ctxt) vs (f ctxt t'))
end
fun abstract_eq f (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t1 $ t2) =
f t1 ##>> f t2 #>> HOLogic.mk_eq
| abstract_eq _ t = SMT_Replay_Methods.abstract_term t
fun prove_prop_rewrite ctxt t =
SMT_Replay_Methods.prove_abstract' ctxt t prop_tac (
abstract_eq SMT_Replay_Methods.abstract_prop (dest_prop t))
fun arith_rewrite_tac ctxt _ = letval backup_tac = Arith_Data.arith_tac ctxt ORELSE' Clasimp.force_tac ctxt in
(TRY o Simplifier.simp_tac ctxt) THEN_ALL_NEW backup_tac
ORELSE' backup_tac end
fun prove_arith_rewrite ctxt t =
SMT_Replay_Methods.prove_abstract' ctxt t arith_rewrite_tac (
abstract_eq (SMT_Replay_Methods.abstract_arith ctxt) (dest_prop t))
val lift_ite_thm = @{thm HOL.if_distrib} RS @{thm eq_reflection}
fun ternary_conv cv = Conv.combination_conv (Conv.binop_conv cv) cv
fun negated_prop \<^Const_>\<open>Not for t\<close> = HOLogic.mk_Trueprop t
| negated_prop t = HOLogic.mk_Trueprop (HOLogic.mk_not t)
fun intro_hyps tab (t as \<^Const_>\<open>HOL.disj\<close> $ t1 $ t2) cx =
lookup_intro_hyps tab t (fold (intro_hyps tab) [t1, t2]) cx
| intro_hyps tab t cx =
lookup_intro_hyps tab t (fn _ => raise LEMMA ()) cx
and lookup_intro_hyps tab t f (cx as (thm, terms)) =
(case Termtab.lookup tab (negated_prop t) of
NONE => f cx
| SOME hyp => (norm_lemma (Thm.implies_intr hyp thm), t :: terms))
fun lemma ctxt (thms as [thm]) t =
(let val tab = Termtab.make (map (`Thm.term_of) (Thm.chyps_of thm)) val (thm', terms) = intro_hyps tab (dest_prop t) (thm, []) in
SMT_Replay_Methods.prove_abstract ctxt [thm'] t prop_tac (
fold (snd oo SMT_Replay_Methods.abstract_lit) terms #>
SMT_Replay_Methods.abstract_disj (dest_thm thm') #>> single ##>>
SMT_Replay_Methods.abstract_disj (dest_prop t)) end handle LEMMA () => replay_error ctxt "Bad proof state" Z3_Proof.Lemma thms t)
| lemma ctxt thms t = replay_rule_error ctxt Z3_Proof.Lemma thms t
(* unit resolution *)
fun unit_res ctxt thms t =
SMT_Replay_Methods.prove_abstract ctxt thms t prop_tac (
fold_map (SMT_Replay_Methods.abstract_unit o dest_thm) thms ##>>
SMT_Replay_Methods.abstract_unit (dest_prop t) #>>
(fn (prems, concl) => (prems, concl)))
(* iff-true *)
val iff_true_rule = @{lemma "P ==> P = True" by fast}
fun iff_true _ [thm] _ = thm RS iff_true_rule
| iff_true ctxt thms t = replay_rule_error ctxt Z3_Proof.Iff_True thms t
(* iff-false *)
val iff_false_rule = @{lemma "\P \ P = False" by fast}
fun iff_false _ [thm] _ = thm RS iff_false_rule
| iff_false ctxt thms t = replay_rule_error ctxt Z3_Proof.Iff_False thms t
(* commutativity *)
fun comm ctxt _ t = SMT_Replay_Methods.match_instantiate ctxt t @{thm eq_commute}
(* definitional axioms *)
fun def_axiom_disj ctxt t =
(case dest_prop t of
\<^Const_>\<open>disj for u1 u2\<close> =>
SMT_Replay_Methods.prove_abstract' ctxt t prop_tac (
SMT_Replay_Methods.abstract_prop u2 ##>> SMT_Replay_Methods.abstract_prop u1 #>>
HOLogic.mk_disj o swap)
| u => SMT_Replay_Methods.prove_abstract' ctxt t prop_tac (SMT_Replay_Methods.abstract_prop u))
fun nnf_pos ctxt = nnf ctxt Z3_Proof.Nnf_Pos fun nnf_neg ctxt = nnf ctxt Z3_Proof.Nnf_Neg
(* mapping of rules to methods *)
fun unsupported rule ctxt = replay_error ctxt "Unsupported" rule fun assumed rule ctxt = replay_error ctxt "Assumed" rule
fun choose Z3_Proof.True_Axiom = true_axiom
| choose (r as Z3_Proof.Asserted) = assumed r
| choose (r as Z3_Proof.Goal) = assumed r
| choose Z3_Proof.Modus_Ponens = mp
| choose Z3_Proof.Reflexivity = refl
| choose Z3_Proof.Symmetry = symm
| choose Z3_Proof.Transitivity = trans
| choose (r as Z3_Proof.Transitivity_Star) = unsupported r
| choose Z3_Proof.Monotonicity = cong
| choose Z3_Proof.Quant_Intro = quant_intro
| choose Z3_Proof.Distributivity = distrib
| choose Z3_Proof.And_Elim = and_elim
| choose Z3_Proof.Not_Or_Elim = not_or_elim
| choose Z3_Proof.Rewrite = rewrite
| choose Z3_Proof.Rewrite_Star = rewrite_star
| choose Z3_Proof.Pull_Quant = pull_quant
| choose (r as Z3_Proof.Pull_Quant_Star) = unsupported r
| choose Z3_Proof.Push_Quant = push_quant
| choose Z3_Proof.Elim_Unused_Vars = elim_unused
| choose Z3_Proof.Dest_Eq_Res = dest_eq_res
| choose Z3_Proof.Quant_Inst = quant_inst
| choose (r as Z3_Proof.Hypothesis) = assumed r
| choose Z3_Proof.Lemma = lemma
| choose Z3_Proof.Unit_Resolution = unit_res
| choose Z3_Proof.Iff_True = iff_true
| choose Z3_Proof.Iff_False = iff_false
| choose Z3_Proof.Commutativity = comm
| choose Z3_Proof.Def_Axiom = def_axiom
| choose (r as Z3_Proof.Intro_Def) = assumed r
| choose Z3_Proof.Apply_Def = apply_def
| choose Z3_Proof.Iff_Oeq = iff_oeq
| choose Z3_Proof.Nnf_Pos = nnf_pos
| choose Z3_Proof.Nnf_Neg = nnf_neg
| choose (r as Z3_Proof.Nnf_Star) = unsupported r
| choose (r as Z3_Proof.Cnf_Star) = unsupported r
| choose (r as Z3_Proof.Skolemize) = assumed r
| choose Z3_Proof.Modus_Ponens_Oeq = mp_oeq
| choose (Z3_Proof.Th_Lemma name) = th_lemma name
fun with_tracing rule method ctxt thms t = letval _ = trace_goal ctxt rule thms t in method ctxt thms t end
fun method_for rule = with_tracing rule (choose rule)
end;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.21Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.