150 fun net_instance net ct = first_of (Net.match_term net (Thm.term_of ct)) ct |
150 fun net_instance net ct = first_of (Net.match_term net (Thm.term_of ct)) ct |
151 end |
151 end |
152 |
152 |
153 fun certify ctxt = Thm.cterm_of (ProofContext.theory_of ctxt) |
153 fun certify ctxt = Thm.cterm_of (ProofContext.theory_of ctxt) |
154 fun certify_var ctxt idx T = certify ctxt (Var (("x", idx), T)) |
154 fun certify_var ctxt idx T = certify ctxt (Var (("x", idx), T)) |
|
155 fun certify_free ctxt idx T = certify ctxt (Free ("x" ^ string_of_int idx, T)) |
155 |
156 |
156 fun varify ctxt = |
157 fun varify ctxt = |
157 let |
158 let |
158 fun varify1 cv thm = |
159 fun varify1 cv thm = |
159 let |
160 let |
434 in |
435 in |
435 fun unfold_distinct_conv ct = |
436 fun unfold_distinct_conv ct = |
436 (More_Conv.rewrs_conv [dist1, dist2] else_conv |
437 (More_Conv.rewrs_conv [dist1, dist2] else_conv |
437 (Conv.rewr_conv dist3 then_conv binop_conv set_conv unfold_distinct_conv)) ct |
438 (Conv.rewr_conv dist3 then_conv binop_conv set_conv unfold_distinct_conv)) ct |
438 end |
439 end |
|
440 |
|
441 (** proving abstractions **) |
|
442 |
|
443 fun fold_map_op f ct = |
|
444 let val (cf, cu) = Thm.dest_comb ct |
|
445 in f cu #>> Thm.capply cf end |
|
446 |
|
447 fun fold_map_binop f1 f2 ct = |
|
448 let val ((cf, cu1), cu2) = apfst Thm.dest_comb (Thm.dest_comb ct) |
|
449 in f1 cu1 ##>> f2 cu2 #>> uncurry (Thm.mk_binop cf) end |
|
450 |
|
451 fun abstraction_context ctxt = (ctxt, certify_var, 1, false, Ctermtab.empty) |
|
452 fun abstraction_context' ctxt = (ctxt, certify_free, 1, true, Ctermtab.empty) |
|
453 |
|
454 fun fresh_abstraction ct (cx as (ctxt, mk_var, idx, gen, tab)) = |
|
455 (case Ctermtab.lookup tab ct of |
|
456 SOME cv => (cv, cx) |
|
457 | NONE => |
|
458 let val cv = mk_var ctxt idx (#T (Thm.rep_cterm ct)) |
|
459 in (cv, (ctxt, mk_var, idx + 1, gen, Ctermtab.update (ct, cv) tab)) end) |
|
460 |
|
461 fun prove_abstraction tac ct (ctxt, _, _, gen, tab) = |
|
462 let |
|
463 val insts = map swap (Ctermtab.dest tab) |
|
464 val thm = Goal.prove_internal [] ct (fn _ => tac 1) |
|
465 in |
|
466 if gen |
|
467 then fold SMT_Normalize.instantiate_free insts thm |
|
468 else Thm.instantiate ([], insts) thm |
|
469 end |
439 |
470 |
440 |
471 |
441 (* core proof rules *) |
472 (* core proof rules *) |
442 |
473 |
443 datatype assms = Some of thm list | Many of thm Net.net |
474 datatype assms = Some of thm list | Many of thm Net.net |
686 as_meta_eq ct |
717 as_meta_eq ct |
687 |> by_tac' (nnf_quant_tac (varify ctxt vars (meta_eq_of p)) qs) |
718 |> by_tac' (nnf_quant_tac (varify ctxt vars (meta_eq_of p)) qs) |
688 |
719 |
689 val nnf_rules = thm_net_of [@{thm not_not}] |
720 val nnf_rules = thm_net_of [@{thm not_not}] |
690 |
721 |
|
722 fun abstract ct = |
|
723 (case Thm.term_of ct of |
|
724 @{term False} => pair |
|
725 | @{term Not} $ _ => fold_map_op abstract |
|
726 | @{term "op &"} $ _ $ _ => fold_map_binop abstract abstract |
|
727 | @{term "op |"} $ _ $ _ => fold_map_binop abstract abstract |
|
728 | @{term "op -->"} $ _ $ _ => fold_map_binop abstract abstract |
|
729 | @{term "op = :: bool => _"} $ _ $ _ => fold_map_binop abstract abstract |
|
730 | _ => fresh_abstraction) ct |
|
731 |
|
732 fun abstracted ctxt ct = |
|
733 abstraction_context' ctxt |
|
734 |> abstract (Thm.dest_arg ct) |
|
735 |>> T.mk_prop |
|
736 |-> prove_abstraction (Classical.best_tac HOL_cs) |
|
737 |
691 fun prove_nnf ctxt = |
738 fun prove_nnf ctxt = |
692 try_apply ctxt "nnf" [ |
739 try_apply ctxt "nnf" [ |
693 ("conj/disj", prove_conj_disj_eq o Thm.dest_arg), |
740 ("conj/disj", prove_conj_disj_eq o Thm.dest_arg), |
694 ("rule", the o net_instance nnf_rules), |
741 ("rule", the o net_instance nnf_rules), |
|
742 ("abstract", abstracted ctxt), |
695 ("tactic", by_tac' (Classical.best_tac HOL_cs))] |
743 ("tactic", by_tac' (Classical.best_tac HOL_cs))] |
696 in |
744 in |
697 fun nnf ctxt ps ct = |
745 fun nnf ctxt ps ct = |
698 (case Thm.term_of ct of |
746 (case Thm.term_of ct of |
699 _ $ (l as Const _ $ Abs _) $ (r as Const _ $ Abs _) => |
747 _ $ (l as Const _ $ Abs _) $ (r as Const _ $ Abs _) => |
982 in |
1030 in |
983 val all_distrib_conv = More_Conv.top_sweep_conv (K distrib_conv) |
1031 val all_distrib_conv = More_Conv.top_sweep_conv (K distrib_conv) |
984 end |
1032 end |
985 |
1033 |
986 local |
1034 local |
987 fun make_ctxt ctxt = (ctxt, Ctermtab.empty, 1) |
1035 fun fresh ct = fresh_abstraction ct |
988 fun fresh ct (cx as (ctxt, tab, idx)) = |
|
989 (case Ctermtab.lookup tab ct of |
|
990 SOME cv => (cv, cx) |
|
991 | NONE => |
|
992 let val cv = certify_var ctxt idx (#T (Thm.rep_cterm ct)) |
|
993 in (cv, (ctxt, Ctermtab.update (ct, cv) tab, idx + 1)) end) |
|
994 |
|
995 fun fold_map_op f ct = |
|
996 let val (cf, cu) = Thm.dest_comb ct |
|
997 in f cu #>> Thm.capply cf end |
|
998 |
|
999 fun fold_map_binop f1 f2 ct = |
|
1000 let val ((cf, cu1), cu2) = apfst Thm.dest_comb (Thm.dest_comb ct) |
|
1001 in f1 cu1 ##>> f2 cu2 #>> uncurry (Thm.mk_binop cf) end |
|
1002 |
1036 |
1003 fun mult f1 f2 ct t u = |
1037 fun mult f1 f2 ct t u = |
1004 if is_number t |
1038 if is_number t |
1005 then if is_number u then pair ct else fold_map_binop f1 f2 ct |
1039 then if is_number u then pair ct else fold_map_binop f1 f2 ct |
1006 else fresh ct |
1040 else fresh ct |
1039 @{term "op |"} $ _ $ _ => fold_map_binop disj disj ct |
1073 @{term "op |"} $ _ $ _ => fold_map_binop disj disj ct |
1040 | @{term False} => pair ct |
1074 | @{term False} => pair ct |
1041 | _ => conj ct) |
1075 | _ => conj ct) |
1042 in |
1076 in |
1043 fun prove_arith ctxt thms ct = |
1077 fun prove_arith ctxt thms ct = |
1044 let |
1078 abstraction_context ctxt |
1045 val (goal, (_, tab, _)) = |
1079 |> fold_map (fold_map_op ineq o Thm.cprop_of) thms |
1046 make_ctxt ctxt |
1080 ||>> fold_map_op disj ct |
1047 |> fold_map (fold_map_op ineq o Thm.cprop_of) thms |
1081 |>> uncurry (fold_rev (Thm.mk_binop @{cterm "op ==>"})) |
1048 ||>> fold_map_op disj ct |
1082 |-> prove_abstraction (Arith_Data.arith_tac ctxt) |
1049 |>> uncurry (fold_rev (Thm.mk_binop @{cterm "op ==>"})) |
1083 |> fold (fn th1 => fn th2 => Thm.implies_elim th2 th1) thms |
1050 in |
|
1051 Goal.prove_internal [] goal (fn _ => Arith_Data.arith_tac ctxt 1) |
|
1052 |> Thm.instantiate ([], map swap (Ctermtab.dest tab)) |
|
1053 |> fold (fn th1 => fn th2 => Thm.implies_elim th2 th1) thms |
|
1054 end |
|
1055 end |
1084 end |
1056 in |
1085 in |
1057 fun arith_lemma ctxt thms ct = |
1086 fun arith_lemma ctxt thms ct = |
1058 let val thms' = map (Conv.fconv_rule (all_distrib_conv ctxt)) thms |
1087 let val thms' = map (Conv.fconv_rule (all_distrib_conv ctxt)) thms |
1059 in with_conv (all_distrib_conv ctxt) (prove_arith ctxt thms') ct end |
1088 in with_conv (all_distrib_conv ctxt) (prove_arith ctxt thms') ct end |