142 fun add_type T (tcx as (_, types, _)) = |
142 fun add_type T (tcx as (_, types, _)) = |
143 (case Typtab.lookup types T of |
143 (case Typtab.lookup types T of |
144 SOME ty => (ty, tcx) |
144 SOME ty => (ty, tcx) |
145 | NONE => add_new_type T tcx) |
145 | NONE => add_new_type T tcx) |
146 |
146 |
147 fun trans_type _ \<^typ>\<open>HOL.bool\<close> = pair Argo_Expr.Bool |
147 fun trans_type _ \<^Type>\<open>bool\<close> = pair Argo_Expr.Bool |
148 | trans_type ctxt (Type (\<^type_name>\<open>fun\<close>, [T1, T2])) = |
148 | trans_type ctxt \<^Type>\<open>fun T1 T2\<close> = |
149 trans_type ctxt T1 ##>> trans_type ctxt T2 #>> Argo_Expr.Func |
149 trans_type ctxt T1 ##>> trans_type ctxt T2 #>> Argo_Expr.Func |
150 | trans_type ctxt T = (fn tcx => |
150 | trans_type ctxt T = (fn tcx => |
151 (case ext_trans_type ctxt (trans_type ctxt) T tcx of |
151 (case ext_trans_type ctxt (trans_type ctxt) T tcx of |
152 SOME result => result |
152 SOME result => result |
153 | NONE => add_type T tcx)) |
153 | NONE => add_type T tcx)) |
162 fun add_term ctxt t (tcx as (_, _, terms)) = |
162 fun add_term ctxt t (tcx as (_, _, terms)) = |
163 (case Termtab.lookup terms t of |
163 (case Termtab.lookup terms t of |
164 SOME c => (Argo_Expr.mk_con c, tcx) |
164 SOME c => (Argo_Expr.mk_con c, tcx) |
165 | NONE => add_new_term ctxt t (Term.fastype_of t) tcx) |
165 | NONE => add_new_term ctxt t (Term.fastype_of t) tcx) |
166 |
166 |
167 fun mk_eq \<^typ>\<open>HOL.bool\<close> = Argo_Expr.mk_iff |
167 fun mk_eq \<^Type>\<open>bool\<close> = Argo_Expr.mk_iff |
168 | mk_eq _ = Argo_Expr.mk_eq |
168 | mk_eq _ = Argo_Expr.mk_eq |
169 |
169 |
170 fun trans_term _ \<^const>\<open>HOL.True\<close> = pair Argo_Expr.true_expr |
170 fun trans_term _ \<^Const_>\<open>True\<close> = pair Argo_Expr.true_expr |
171 | trans_term _ \<^const>\<open>HOL.False\<close> = pair Argo_Expr.false_expr |
171 | trans_term _ \<^Const_>\<open>False\<close> = pair Argo_Expr.false_expr |
172 | trans_term ctxt (\<^const>\<open>HOL.Not\<close> $ t) = trans_term ctxt t #>> Argo_Expr.mk_not |
172 | trans_term ctxt \<^Const_>\<open>Not for t\<close> = trans_term ctxt t #>> Argo_Expr.mk_not |
173 | trans_term ctxt (\<^const>\<open>HOL.conj\<close> $ t1 $ t2) = |
173 | trans_term ctxt \<^Const_>\<open>conj for t1 t2\<close> = |
174 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry Argo_Expr.mk_and2 |
174 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry Argo_Expr.mk_and2 |
175 | trans_term ctxt (\<^const>\<open>HOL.disj\<close> $ t1 $ t2) = |
175 | trans_term ctxt \<^Const_>\<open>disj for t1 t2\<close> = |
176 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry Argo_Expr.mk_or2 |
176 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry Argo_Expr.mk_or2 |
177 | trans_term ctxt (\<^const>\<open>HOL.implies\<close> $ t1 $ t2) = |
177 | trans_term ctxt \<^Const_>\<open>implies for t1 t2\<close> = |
178 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry Argo_Expr.mk_imp |
178 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry Argo_Expr.mk_imp |
179 | trans_term ctxt (Const (\<^const_name>\<open>HOL.If\<close>, _) $ t1 $ t2 $ t3) = |
179 | trans_term ctxt \<^Const_>\<open>If _ for t1 t2 t3\<close> = |
180 trans_term ctxt t1 ##>> trans_term ctxt t2 ##>> trans_term ctxt t3 #>> |
180 trans_term ctxt t1 ##>> trans_term ctxt t2 ##>> trans_term ctxt t3 #>> |
181 (fn ((u1, u2), u3) => Argo_Expr.mk_ite u1 u2 u3) |
181 (fn ((u1, u2), u3) => Argo_Expr.mk_ite u1 u2 u3) |
182 | trans_term ctxt (Const (\<^const_name>\<open>HOL.eq\<close>, T) $ t1 $ t2) = |
182 | trans_term ctxt \<^Const_>\<open>HOL.eq T for t1 t2\<close> = |
183 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry (mk_eq (Term.domain_type T)) |
183 trans_term ctxt t1 ##>> trans_term ctxt t2 #>> uncurry (mk_eq T) |
184 | trans_term ctxt (t as (t1 $ t2)) = (fn tcx => |
184 | trans_term ctxt (t as (t1 $ t2)) = (fn tcx => |
185 (case ext_trans_term ctxt (trans_term ctxt) t tcx of |
185 (case ext_trans_term ctxt (trans_term ctxt) t tcx of |
186 SOME result => result |
186 SOME result => result |
187 | NONE => tcx |> trans_term ctxt t1 ||>> trans_term ctxt t2 |>> uncurry Argo_Expr.mk_app)) |
187 | NONE => tcx |> trans_term ctxt t1 ||>> trans_term ctxt t2 |>> uncurry Argo_Expr.mk_app)) |
188 | trans_term ctxt t = (fn tcx => |
188 | trans_term ctxt t = (fn tcx => |
256 |
256 |
257 fun mk_nary' d _ [] = d |
257 fun mk_nary' d _ [] = d |
258 | mk_nary' _ f ts = mk_nary f ts |
258 | mk_nary' _ f ts = mk_nary f ts |
259 |
259 |
260 fun mk_ite t1 t2 t3 = |
260 fun mk_ite t1 t2 t3 = |
261 let |
261 let val T = Term.fastype_of t2 |
262 val T = Term.fastype_of t2 |
262 in \<^Const>\<open>If T for t1 t2 t3\<close> end |
263 val ite = Const (\<^const_name>\<open>HOL.If\<close>, [\<^typ>\<open>HOL.bool\<close>, T, T] ---> T) |
263 |
264 in ite $ t1 $ t2 $ t3 end |
264 fun term_of _ (Argo_Expr.E (Argo_Expr.True, _)) = \<^Const>\<open>True\<close> |
265 |
265 | term_of _ (Argo_Expr.E (Argo_Expr.False, _)) = \<^Const>\<open>False\<close> |
266 fun term_of _ (Argo_Expr.E (Argo_Expr.True, _)) = \<^const>\<open>HOL.True\<close> |
|
267 | term_of _ (Argo_Expr.E (Argo_Expr.False, _)) = \<^const>\<open>HOL.False\<close> |
|
268 | term_of cx (Argo_Expr.E (Argo_Expr.Not, [e])) = HOLogic.mk_not (term_of cx e) |
266 | term_of cx (Argo_Expr.E (Argo_Expr.Not, [e])) = HOLogic.mk_not (term_of cx e) |
269 | term_of cx (Argo_Expr.E (Argo_Expr.And, es)) = |
267 | term_of cx (Argo_Expr.E (Argo_Expr.And, es)) = |
270 mk_nary' \<^const>\<open>HOL.True\<close> HOLogic.mk_conj (map (term_of cx) es) |
268 mk_nary' \<^Const>\<open>True\<close> HOLogic.mk_conj (map (term_of cx) es) |
271 | term_of cx (Argo_Expr.E (Argo_Expr.Or, es)) = |
269 | term_of cx (Argo_Expr.E (Argo_Expr.Or, es)) = |
272 mk_nary' \<^const>\<open>HOL.False\<close> HOLogic.mk_disj (map (term_of cx) es) |
270 mk_nary' \<^Const>\<open>False\<close> HOLogic.mk_disj (map (term_of cx) es) |
273 | term_of cx (Argo_Expr.E (Argo_Expr.Imp, [e1, e2])) = |
271 | term_of cx (Argo_Expr.E (Argo_Expr.Imp, [e1, e2])) = |
274 HOLogic.mk_imp (term_of cx e1, term_of cx e2) |
272 HOLogic.mk_imp (term_of cx e1, term_of cx e2) |
275 | term_of cx (Argo_Expr.E (Argo_Expr.Iff, [e1, e2])) = |
273 | term_of cx (Argo_Expr.E (Argo_Expr.Iff, [e1, e2])) = |
276 HOLogic.mk_eq (term_of cx e1, term_of cx e2) |
274 HOLogic.mk_eq (term_of cx e1, term_of cx e2) |
277 | term_of cx (Argo_Expr.E (Argo_Expr.Ite, [e1, e2, e3])) = |
275 | term_of cx (Argo_Expr.E (Argo_Expr.Ite, [e1, e2, e3])) = |
287 | term_of (cx as (ctxt, _)) e = |
285 | term_of (cx as (ctxt, _)) e = |
288 (case ext_term_of ctxt (term_of cx) e of |
286 (case ext_term_of ctxt (term_of cx) e of |
289 SOME t => t |
287 SOME t => t |
290 | NONE => raise Fail "bad expression") |
288 | NONE => raise Fail "bad expression") |
291 |
289 |
292 fun as_prop ct = Thm.apply \<^cterm>\<open>HOL.Trueprop\<close> ct |
290 fun as_prop ct = Thm.apply \<^cterm>\<open>Trueprop\<close> ct |
293 |
291 |
294 fun cterm_of ctxt cons e = Thm.cterm_of ctxt (term_of (ctxt, cons) e) |
292 fun cterm_of ctxt cons e = Thm.cterm_of ctxt (term_of (ctxt, cons) e) |
295 fun cprop_of ctxt cons e = as_prop (cterm_of ctxt cons e) |
293 fun cprop_of ctxt cons e = as_prop (cterm_of ctxt cons e) |
296 |
294 |
297 |
295 |
315 (fn {context, ...} => HEADGOAL (Classical.fast_tac context)) |
313 (fn {context, ...} => HEADGOAL (Classical.fast_tac context)) |
316 |
314 |
317 fun with_frees ctxt n mk = |
315 fun with_frees ctxt n mk = |
318 let |
316 let |
319 val ns = map (fn i => "P" ^ string_of_int i) (0 upto (n - 1)) |
317 val ns = map (fn i => "P" ^ string_of_int i) (0 upto (n - 1)) |
320 val ts = map (Free o rpair \<^typ>\<open>bool\<close>) ns |
318 val ts = map (Free o rpair \<^Type>\<open>bool\<close>) ns |
321 val t = mk_nary HOLogic.mk_disj (mk ts) |
319 val t = mk_nary HOLogic.mk_disj (mk ts) |
322 in prove_taut ctxt ns t end |
320 in prove_taut ctxt ns t end |
323 |
321 |
324 fun taut_and1_term ts = mk_nary HOLogic.mk_conj ts :: map HOLogic.mk_not ts |
322 fun taut_and1_term ts = mk_nary HOLogic.mk_conj ts :: map HOLogic.mk_not ts |
325 fun taut_and2_term i ts = [HOLogic.mk_not (mk_nary HOLogic.mk_conj ts), nth ts i] |
323 fun taut_and2_term i ts = [HOLogic.mk_not (mk_nary HOLogic.mk_conj ts), nth ts i] |
372 Conv.try_conv (Conv.arg_conv cv) then_conv |
370 Conv.try_conv (Conv.arg_conv cv) then_conv |
373 Conv.try_conv (Conv.rewr_conv rule then_conv cv)) ct |
371 Conv.try_conv (Conv.rewr_conv rule then_conv cv)) ct |
374 |
372 |
375 fun flat_conj_conv ct = |
373 fun flat_conj_conv ct = |
376 (case Thm.term_of ct of |
374 (case Thm.term_of ct of |
377 \<^const>\<open>HOL.conj\<close> $ _ $ _ => flatten_conv flat_conj_conv flatten_and_thm ct |
375 \<^Const_>\<open>conj for _ _\<close> => flatten_conv flat_conj_conv flatten_and_thm ct |
378 | _ => Conv.all_conv ct) |
376 | _ => Conv.all_conv ct) |
379 |
377 |
380 fun flat_disj_conv ct = |
378 fun flat_disj_conv ct = |
381 (case Thm.term_of ct of |
379 (case Thm.term_of ct of |
382 \<^const>\<open>HOL.disj\<close> $ _ $ _ => flatten_conv flat_disj_conv flatten_or_thm ct |
380 \<^Const_>\<open>disj for _ _\<close> => flatten_conv flat_disj_conv flatten_or_thm ct |
383 | _ => Conv.all_conv ct) |
381 | _ => Conv.all_conv ct) |
384 |
382 |
385 fun explode rule1 rule2 thm = |
383 fun explode rule1 rule2 thm = |
386 explode rule1 rule2 (thm RS rule1) @ explode rule1 rule2 (thm RS rule2) handle THM _ => [thm] |
384 explode rule1 rule2 (thm RS rule1) @ explode rule1 rule2 (thm RS rule2) handle THM _ => [thm] |
387 val explode_conj = explode @{thm conjunct1} @{thm conjunct2} |
385 val explode_conj = explode @{thm conjunct1} @{thm conjunct2} |
413 val lhs = under_assumption lf ct |
411 val lhs = under_assumption lf ct |
414 val rhs = rf (Thm.dest_arg (snd (Thm.dest_implies (Thm.cprop_of lhs)))) |
412 val rhs = rf (Thm.dest_arg (snd (Thm.dest_implies (Thm.cprop_of lhs)))) |
415 in mk_rewr (discharge2 lhs rhs rule) end |
413 in mk_rewr (discharge2 lhs rhs rule) end |
416 |
414 |
417 fun with_conj f g ct = iff_intro iff_conj_thm (f o explode_conj) g ct |
415 fun with_conj f g ct = iff_intro iff_conj_thm (f o explode_conj) g ct |
418 fun with_ndis f g ct = iff_intro iff_ndis_thm (f o explode_ndis) g (Thm.apply \<^cterm>\<open>HOL.Not\<close> ct) |
416 fun with_ndis f g ct = iff_intro iff_ndis_thm (f o explode_ndis) g (Thm.apply \<^cterm>\<open>Not\<close> ct) |
419 |
417 |
420 fun swap_indices n iss = map (fn i => find_index (fn is => member (op =) is i) iss) (0 upto (n - 1)) |
418 fun swap_indices n iss = map (fn i => find_index (fn is => member (op =) is i) iss) (0 upto (n - 1)) |
421 fun sort_nary w f g (n, iss) = w (f (map hd iss)) (under_assumption (f (swap_indices n iss) o g)) |
419 fun sort_nary w f g (n, iss) = w (f (map hd iss)) (under_assumption (f (swap_indices n iss) o g)) |
422 val sort_conj = sort_nary with_conj join_conj explode_conj |
420 val sort_conj = sort_nary with_conj join_conj explode_conj |
423 val sort_ndis = sort_nary with_ndis join_ndis explode_ndis |
421 val sort_ndis = sort_nary with_ndis join_ndis explode_ndis |
483 and replay_args_conv _ [] ct = Conv.all_conv ct |
481 and replay_args_conv _ [] ct = Conv.all_conv ct |
484 | replay_args_conv ctxt [c] ct = Conv.arg_conv (replay_conv ctxt c) ct |
482 | replay_args_conv ctxt [c] ct = Conv.arg_conv (replay_conv ctxt c) ct |
485 | replay_args_conv ctxt [c1, c2] ct = binop_conv (replay_conv ctxt c1) (replay_conv ctxt c2) ct |
483 | replay_args_conv ctxt [c1, c2] ct = binop_conv (replay_conv ctxt c1) (replay_conv ctxt c2) ct |
486 | replay_args_conv ctxt (c :: cs) ct = |
484 | replay_args_conv ctxt (c :: cs) ct = |
487 (case Term.head_of (Thm.term_of ct) of |
485 (case Term.head_of (Thm.term_of ct) of |
488 Const (\<^const_name>\<open>HOL.If\<close>, _) => |
486 \<^Const_>\<open>If _\<close> => |
489 let val (cs', c') = split_last cs |
487 let val (cs', c') = split_last cs |
490 in Conv.combination_conv (replay_args_conv ctxt (c :: cs')) (replay_conv ctxt c') ct end |
488 in Conv.combination_conv (replay_args_conv ctxt (c :: cs')) (replay_conv ctxt c') ct end |
491 | _ => binop_conv (replay_conv ctxt c) (replay_args_conv ctxt cs) ct) |
489 | _ => binop_conv (replay_conv ctxt c) (replay_args_conv ctxt cs) ct) |
492 |
490 |
493 fun replay_rewrite ctxt c thm = Conv.fconv_rule (HOLogic.Trueprop_conv (replay_conv ctxt c)) thm |
491 fun replay_rewrite ctxt c thm = Conv.fconv_rule (HOLogic.Trueprop_conv (replay_conv ctxt c)) thm |
519 |
517 |
520 (* proof replay for unit resolution *) |
518 (* proof replay for unit resolution *) |
521 |
519 |
522 val unit_rule = @{lemma "(P \<Longrightarrow> False) \<Longrightarrow> (\<not>P \<Longrightarrow> False) \<Longrightarrow> False" by fast} |
520 val unit_rule = @{lemma "(P \<Longrightarrow> False) \<Longrightarrow> (\<not>P \<Longrightarrow> False) \<Longrightarrow> False" by fast} |
523 val unit_rule_var = Thm.dest_arg (Thm.dest_arg1 (Thm.cprem_of unit_rule 1)) |
521 val unit_rule_var = Thm.dest_arg (Thm.dest_arg1 (Thm.cprem_of unit_rule 1)) |
524 val bogus_ct = \<^cterm>\<open>HOL.True\<close> |
522 val bogus_ct = \<^cterm>\<open>True\<close> |
525 |
523 |
526 fun replay_unit_res lit (pthm, plits) (nthm, nlits) = |
524 fun replay_unit_res lit (pthm, plits) (nthm, nlits) = |
527 let |
525 let |
528 val plit = the (AList.lookup (op =) plits lit) |
526 val plit = the (AList.lookup (op =) plits lit) |
529 val nlit = the (AList.lookup (op =) nlits (~lit)) |
527 val nlit = the (AList.lookup (op =) nlits (~lit)) |
542 val dneg_rule = @{lemma "\<not>\<not>P \<Longrightarrow> P" by auto} |
540 val dneg_rule = @{lemma "\<not>\<not>P \<Longrightarrow> P" by auto} |
543 |
541 |
544 fun replay_hyp i ct = |
542 fun replay_hyp i ct = |
545 if i < 0 then (Thm.assume ct, [(~i, ct)]) |
543 if i < 0 then (Thm.assume ct, [(~i, ct)]) |
546 else |
544 else |
547 let val cu = as_prop (Thm.apply \<^cterm>\<open>HOL.Not\<close> (Thm.apply \<^cterm>\<open>HOL.Not\<close> (Thm.dest_arg ct))) |
545 let val cu = as_prop (Thm.apply \<^cterm>\<open>Not\<close> (Thm.apply \<^cterm>\<open>Not\<close> (Thm.dest_arg ct))) |
548 in (discharge (Thm.assume cu) dneg_rule, [(~i, cu)]) end |
546 in (discharge (Thm.assume cu) dneg_rule, [(~i, cu)]) end |
549 |
547 |
550 |
548 |
551 (* proof replay for lemma *) |
549 (* proof replay for lemma *) |
552 |
550 |
600 val unclausify_rule1 = @{lemma "(\<not>P \<Longrightarrow> False) \<Longrightarrow> P" by auto} |
598 val unclausify_rule1 = @{lemma "(\<not>P \<Longrightarrow> False) \<Longrightarrow> P" by auto} |
601 val unclausify_rule2 = @{lemma "(P \<Longrightarrow> False) \<Longrightarrow> \<not>P" by auto} |
599 val unclausify_rule2 = @{lemma "(P \<Longrightarrow> False) \<Longrightarrow> \<not>P" by auto} |
602 |
600 |
603 fun unclausify (thm, lits) ls = |
601 fun unclausify (thm, lits) ls = |
604 (case (Thm.prop_of thm, lits) of |
602 (case (Thm.prop_of thm, lits) of |
605 (\<^const>\<open>HOL.Trueprop\<close> $ \<^const>\<open>HOL.False\<close>, [(_, ct)]) => |
603 (\<^Const_>\<open>Trueprop for \<open>\<^Const_>\<open>False\<close>\<close>\<close>, [(_, ct)]) => |
606 let val thm = Thm.implies_intr ct thm |
604 let val thm = Thm.implies_intr ct thm |
607 in (discharge thm unclausify_rule1 handle THM _ => discharge thm unclausify_rule2, ls) end |
605 in (discharge thm unclausify_rule1 handle THM _ => discharge thm unclausify_rule2, ls) end |
608 | _ => (thm, Ord_List.union lit_ord lits ls)) |
606 | _ => (thm, Ord_List.union lit_ord lits ls)) |
609 |
607 |
610 fun with_thms f tps = fold_map unclausify tps [] |>> f |
608 fun with_thms f tps = fold_map unclausify tps [] |>> f |
667 |
665 |
668 fun instantiate_elim_rule thm = |
666 fun instantiate_elim_rule thm = |
669 let val ct = Drule.strip_imp_concl (Thm.cprop_of thm) |
667 let val ct = Drule.strip_imp_concl (Thm.cprop_of thm) |
670 in |
668 in |
671 (case Thm.term_of ct of |
669 (case Thm.term_of ct of |
672 \<^const>\<open>HOL.Trueprop\<close> $ Var (_, \<^typ>\<open>HOL.bool\<close>) => |
670 \<^Const_>\<open>Trueprop for \<open>Var (_, \<^Type>\<open>bool\<close>)\<close>\<close> => |
673 instantiate (Thm.dest_arg ct) \<^cterm>\<open>HOL.False\<close> thm |
671 instantiate (Thm.dest_arg ct) \<^cterm>\<open>False\<close> thm |
674 | Var _ => instantiate ct \<^cprop>\<open>HOL.False\<close> thm |
672 | Var _ => instantiate ct \<^cprop>\<open>False\<close> thm |
675 | _ => thm) |
673 | _ => thm) |
676 end |
674 end |
677 |
675 |
678 fun atomize_conv ctxt ct = |
676 fun atomize_conv ctxt ct = |
679 (case Thm.term_of ct of |
677 (case Thm.term_of ct of |
680 \<^const>\<open>HOL.Trueprop\<close> $ _ => Conv.all_conv |
678 \<^Const_>\<open>Trueprop for _\<close> => Conv.all_conv |
681 | \<^const>\<open>Pure.imp\<close> $ _ $ _ => |
679 | \<^Const_>\<open>Pure.imp for _ _\<close> => |
682 Conv.binop_conv (atomize_conv ctxt) then_conv |
680 Conv.binop_conv (atomize_conv ctxt) then_conv |
683 Conv.rewr_conv @{thm atomize_imp} |
681 Conv.rewr_conv @{thm atomize_imp} |
684 | Const (\<^const_name>\<open>Pure.eq\<close>, _) $ _ $ _ => |
682 | \<^Const>\<open>Pure.eq _ for _ _\<close> => |
685 Conv.binop_conv (atomize_conv ctxt) then_conv |
683 Conv.binop_conv (atomize_conv ctxt) then_conv |
686 Conv.rewr_conv @{thm atomize_eq} |
684 Conv.rewr_conv @{thm atomize_eq} |
687 | Const (\<^const_name>\<open>Pure.all\<close>, _) $ Abs _ => |
685 | \<^Const>\<open>Pure.all _ for \<open>Abs _\<close>\<close> => |
688 Conv.binder_conv (atomize_conv o snd) ctxt then_conv |
686 Conv.binder_conv (atomize_conv o snd) ctxt then_conv |
689 Conv.rewr_conv @{thm atomize_all} |
687 Conv.rewr_conv @{thm atomize_all} |
690 | _ => Conv.all_conv) ct |
688 | _ => Conv.all_conv) ct |
691 |
689 |
692 fun normalize ctxt thm = |
690 fun normalize ctxt thm = |