458 fun decomp_simp thm = |
458 fun decomp_simp thm = |
459 let |
459 let |
460 val {thy, prop, ...} = Thm.rep_thm thm; |
460 val {thy, prop, ...} = Thm.rep_thm thm; |
461 val prems = Logic.strip_imp_prems prop; |
461 val prems = Logic.strip_imp_prems prop; |
462 val concl = Drule.strip_imp_concl (Thm.cprop_of thm); |
462 val concl = Drule.strip_imp_concl (Thm.cprop_of thm); |
463 val (lhs, rhs) = Drule.dest_equals concl handle TERM _ => |
463 val (lhs, rhs) = Thm.dest_equals concl handle TERM _ => |
464 raise SIMPLIFIER ("Rewrite rule not a meta-equality", thm); |
464 raise SIMPLIFIER ("Rewrite rule not a meta-equality", thm); |
465 val elhs = Thm.dest_arg (Thm.cprop_of (Thm.eta_conversion lhs)); |
465 val elhs = Thm.dest_arg (Thm.cprop_of (Thm.eta_conversion lhs)); |
466 val elhs = if term_of elhs aconv term_of lhs then lhs else elhs; (*share identical copies*) |
466 val elhs = if term_of elhs aconv term_of lhs then lhs else elhs; (*share identical copies*) |
467 val erhs = Envir.eta_contract (term_of rhs); |
467 val erhs = Envir.eta_contract (term_of rhs); |
468 val perm = |
468 val perm = |
576 end; |
576 end; |
577 |
577 |
578 fun add_cong (ss, thm) = ss |> |
578 fun add_cong (ss, thm) = ss |> |
579 map_simpset2 (fn (congs, procs, mk_rews, termless, subgoal_tac, loop_tacs, solvers) => |
579 map_simpset2 (fn (congs, procs, mk_rews, termless, subgoal_tac, loop_tacs, solvers) => |
580 let |
580 let |
581 val (lhs, _) = Drule.dest_equals (Drule.strip_imp_concl (Thm.cprop_of thm)) |
581 val (lhs, _) = Thm.dest_equals (Drule.strip_imp_concl (Thm.cprop_of thm)) |
582 handle TERM _ => raise SIMPLIFIER ("Congruence not a meta-equality", thm); |
582 handle TERM _ => raise SIMPLIFIER ("Congruence not a meta-equality", thm); |
583 (*val lhs = Envir.eta_contract lhs;*) |
583 (*val lhs = Envir.eta_contract lhs;*) |
584 val a = the (cong_name (head_of (term_of lhs))) handle Option.Option => |
584 val a = the (cong_name (head_of (term_of lhs))) handle Option.Option => |
585 raise SIMPLIFIER ("Congruence must start with a constant or free variable", thm); |
585 raise SIMPLIFIER ("Congruence must start with a constant or free variable", thm); |
586 val (xs, weak) = congs; |
586 val (xs, weak) = congs; |
826 *) |
826 *) |
827 |
827 |
828 fun check_conv msg ss thm thm' = |
828 fun check_conv msg ss thm thm' = |
829 let |
829 let |
830 val thm'' = transitive thm (transitive |
830 val thm'' = transitive thm (transitive |
831 (symmetric (Drule.beta_eta_conversion (Drule.lhs_of thm'))) thm') |
831 (symmetric (Drule.beta_eta_conversion (Thm.lhs_of thm'))) thm') |
832 in if msg then trace_thm (fn () => "SUCCEEDED") ss thm' else (); SOME thm'' end |
832 in if msg then trace_thm (fn () => "SUCCEEDED") ss thm' else (); SOME thm'' end |
833 handle THM _ => |
833 handle THM _ => |
834 let val {thy, prop = _ $ _ $ prop0, ...} = Thm.rep_thm thm in |
834 let val {thy, prop = _ $ _ $ prop0, ...} = Thm.rep_thm thm in |
835 trace_thm (fn () => "Proved wrong thm (Check subgoaler?)") ss thm'; |
835 trace_thm (fn () => "Proved wrong thm (Check subgoaler?)") ss thm'; |
836 trace_term false (fn () => "Should have proved:") ss thy prop0; |
836 trace_term false (fn () => "Should have proved:") ss thy prop0; |
888 |
888 |
889 fun rewritec (prover, thyt, maxt) ss t = |
889 fun rewritec (prover, thyt, maxt) ss t = |
890 let |
890 let |
891 val Simpset ({rules, ...}, {congs, procs, termless, ...}) = ss; |
891 val Simpset ({rules, ...}, {congs, procs, termless, ...}) = ss; |
892 val eta_thm = Thm.eta_conversion t; |
892 val eta_thm = Thm.eta_conversion t; |
893 val eta_t' = Drule.rhs_of eta_thm; |
893 val eta_t' = Thm.rhs_of eta_thm; |
894 val eta_t = term_of eta_t'; |
894 val eta_t = term_of eta_t'; |
895 fun rew {thm, name, lhs, elhs, extra, fo, perm} = |
895 fun rew {thm, name, lhs, elhs, extra, fo, perm} = |
896 let |
896 let |
897 val {thy, prop, maxidx, ...} = rep_thm thm; |
897 val {thy, prop, maxidx, ...} = rep_thm thm; |
898 val (rthm, elhs') = |
898 val (rthm, elhs') = |
899 if maxt = ~1 orelse not extra then (thm, elhs) |
899 if maxt = ~1 orelse not extra then (thm, elhs) |
900 else (Thm.incr_indexes (maxt+1) thm, Thm.cterm_incr_indexes (maxt+1) elhs); |
900 else (Thm.incr_indexes (maxt + 1) thm, Thm.incr_indexes_cterm (maxt + 1) elhs); |
901 val insts = if fo then Thm.cterm_first_order_match (elhs', eta_t') |
901 val insts = |
902 else Thm.cterm_match (elhs', eta_t'); |
902 if fo then Thm.first_order_match (elhs', eta_t') |
|
903 else Thm.match (elhs', eta_t'); |
903 val thm' = Thm.instantiate insts (Thm.rename_boundvars lhs eta_t rthm); |
904 val thm' = Thm.instantiate insts (Thm.rename_boundvars lhs eta_t rthm); |
904 val prop' = Thm.prop_of thm'; |
905 val prop' = Thm.prop_of thm'; |
905 val unconditional = (Logic.count_prems prop' = 0); |
906 val unconditional = (Logic.count_prems prop' = 0); |
906 val (lhs', rhs') = Logic.dest_equals (Logic.strip_imp_concl prop') |
907 val (lhs', rhs') = Logic.dest_equals (Logic.strip_imp_concl prop') |
907 in |
908 in |
972 |
973 |
973 |
974 |
974 (* conversion to apply a congruence rule to a term *) |
975 (* conversion to apply a congruence rule to a term *) |
975 |
976 |
976 fun congc prover ss maxt {thm=cong,lhs=lhs} t = |
977 fun congc prover ss maxt {thm=cong,lhs=lhs} t = |
977 let val rthm = Thm.incr_indexes (maxt+1) cong; |
978 let val rthm = Thm.incr_indexes (maxt + 1) cong; |
978 val rlhs = fst (Drule.dest_equals (Drule.strip_imp_concl (cprop_of rthm))); |
979 val rlhs = fst (Thm.dest_equals (Drule.strip_imp_concl (cprop_of rthm))); |
979 val insts = Thm.cterm_match (rlhs, t) |
980 val insts = Thm.match (rlhs, t) |
980 (* Pattern.match can raise Pattern.MATCH; |
981 (* Thm.match can raise Pattern.MATCH; |
981 is handled when congc is called *) |
982 is handled when congc is called *) |
982 val thm' = Thm.instantiate insts (Thm.rename_boundvars (term_of rlhs) (term_of t) rthm); |
983 val thm' = Thm.instantiate insts (Thm.rename_boundvars (term_of rlhs) (term_of t) rthm); |
983 val unit = trace_thm (fn () => "Applying congruence rule:") ss thm'; |
984 val unit = trace_thm (fn () => "Applying congruence rule:") ss thm'; |
984 fun err (msg, thm) = (trace_thm (fn () => msg) ss thm; NONE) |
985 fun err (msg, thm) = (trace_thm (fn () => msg) ss thm; NONE) |
985 in case prover thm' of |
986 in case prover thm' of |
986 NONE => err ("Congruence proof failed. Could not prove", thm') |
987 NONE => err ("Congruence proof failed. Could not prove", thm') |
987 | SOME thm2 => (case check_conv true ss (Drule.beta_eta_conversion t) thm2 of |
988 | SOME thm2 => (case check_conv true ss (Drule.beta_eta_conversion t) thm2 of |
988 NONE => err ("Congruence proof failed. Should not have proved", thm2) |
989 NONE => err ("Congruence proof failed. Should not have proved", thm2) |
989 | SOME thm2' => |
990 | SOME thm2' => |
990 if op aconv (pairself term_of (dest_equals (cprop_of thm2'))) |
991 if op aconv (pairself term_of (Thm.dest_equals (cprop_of thm2'))) |
991 then NONE else SOME thm2') |
992 then NONE else SOME thm2') |
992 end; |
993 end; |
993 |
994 |
994 val (cA, (cB, cC)) = |
995 val (cA, (cB, cC)) = |
995 apsnd dest_equals (dest_implies (hd (cprems_of Drule.imp_cong))); |
996 apsnd Thm.dest_equals (Thm.dest_implies (hd (cprems_of Drule.imp_cong))); |
996 |
997 |
997 fun transitive1 NONE NONE = NONE |
998 fun transitive1 NONE NONE = NONE |
998 | transitive1 (SOME thm1) NONE = SOME thm1 |
999 | transitive1 (SOME thm1) NONE = SOME thm1 |
999 | transitive1 NONE (SOME thm2) = SOME thm2 |
1000 | transitive1 NONE (SOME thm2) = SOME thm2 |
1000 | transitive1 (SOME thm1) (SOME thm2) = SOME (transitive thm1 thm2) |
1001 | transitive1 (SOME thm1) (SOME thm2) = SOME (transitive thm1 thm2) |
1007 fun botc skel ss t = |
1008 fun botc skel ss t = |
1008 if is_Var skel then NONE |
1009 if is_Var skel then NONE |
1009 else |
1010 else |
1010 (case subc skel ss t of |
1011 (case subc skel ss t of |
1011 some as SOME thm1 => |
1012 some as SOME thm1 => |
1012 (case rewritec (prover, thy, maxidx) ss (Drule.rhs_of thm1) of |
1013 (case rewritec (prover, thy, maxidx) ss (Thm.rhs_of thm1) of |
1013 SOME (thm2, skel2) => |
1014 SOME (thm2, skel2) => |
1014 transitive2 (transitive thm1 thm2) |
1015 transitive2 (transitive thm1 thm2) |
1015 (botc skel2 ss (Drule.rhs_of thm2)) |
1016 (botc skel2 ss (Thm.rhs_of thm2)) |
1016 | NONE => some) |
1017 | NONE => some) |
1017 | NONE => |
1018 | NONE => |
1018 (case rewritec (prover, thy, maxidx) ss t of |
1019 (case rewritec (prover, thy, maxidx) ss t of |
1019 SOME (thm2, skel2) => transitive2 thm2 |
1020 SOME (thm2, skel2) => transitive2 thm2 |
1020 (botc skel2 ss (Drule.rhs_of thm2)) |
1021 (botc skel2 ss (Thm.rhs_of thm2)) |
1021 | NONE => NONE)) |
1022 | NONE => NONE)) |
1022 |
1023 |
1023 and try_botc ss t = |
1024 and try_botc ss t = |
1024 (case botc skel0 ss t of |
1025 (case botc skel0 ss t of |
1025 SOME trec1 => trec1 | NONE => (reflexive t)) |
1026 SOME trec1 => trec1 | NONE => (reflexive t)) |
1043 end |
1044 end |
1044 | t $ _ => (case t of |
1045 | t $ _ => (case t of |
1045 Const ("==>", _) $ _ => impc t0 ss |
1046 Const ("==>", _) $ _ => impc t0 ss |
1046 | Abs _ => |
1047 | Abs _ => |
1047 let val thm = beta_conversion false t0 |
1048 let val thm = beta_conversion false t0 |
1048 in case subc skel0 ss (Drule.rhs_of thm) of |
1049 in case subc skel0 ss (Thm.rhs_of thm) of |
1049 NONE => SOME thm |
1050 NONE => SOME thm |
1050 | SOME thm' => SOME (transitive thm thm') |
1051 | SOME thm' => SOME (transitive thm thm') |
1051 end |
1052 end |
1052 | _ => |
1053 | _ => |
1053 let fun appc () = |
1054 let fun appc () = |
1075 | SOME cong => |
1076 | SOME cong => |
1076 (*post processing: some partial applications h t1 ... tj, j <= length ts, |
1077 (*post processing: some partial applications h t1 ... tj, j <= length ts, |
1077 may be a redex. Example: map (%x. x) = (%xs. xs) wrt map_cong*) |
1078 may be a redex. Example: map (%x. x) = (%xs. xs) wrt map_cong*) |
1078 (let |
1079 (let |
1079 val thm = congc (prover ss) ss maxidx cong t0; |
1080 val thm = congc (prover ss) ss maxidx cong t0; |
1080 val t = the_default t0 (Option.map Drule.rhs_of thm); |
1081 val t = the_default t0 (Option.map Thm.rhs_of thm); |
1081 val (cl, cr) = Thm.dest_comb t |
1082 val (cl, cr) = Thm.dest_comb t |
1082 val dVar = Var(("", 0), dummyT) |
1083 val dVar = Var(("", 0), dummyT) |
1083 val skel = |
1084 val skel = |
1084 list_comb (h, replicate (length ts) dVar) |
1085 list_comb (h, replicate (length ts) dVar) |
1085 in case botc skel ss cl of |
1086 in case botc skel ss cl of |
1106 and add_rrules (rrss, asms) ss = |
1107 and add_rrules (rrss, asms) ss = |
1107 (fold o fold) insert_rrule rrss ss |> add_prems (map_filter I asms) |
1108 (fold o fold) insert_rrule rrss ss |> add_prems (map_filter I asms) |
1108 |
1109 |
1109 and disch r (prem, eq) = |
1110 and disch r (prem, eq) = |
1110 let |
1111 let |
1111 val (lhs, rhs) = Drule.dest_equals (Thm.cprop_of eq); |
1112 val (lhs, rhs) = Thm.dest_equals (Thm.cprop_of eq); |
1112 val eq' = implies_elim (Thm.instantiate |
1113 val eq' = implies_elim (Thm.instantiate |
1113 ([], [(cA, prem), (cB, lhs), (cC, rhs)]) Drule.imp_cong) |
1114 ([], [(cA, prem), (cB, lhs), (cC, rhs)]) Drule.imp_cong) |
1114 (implies_intr prem eq) |
1115 (implies_intr prem eq) |
1115 in if not r then eq' else |
1116 in if not r then eq' else |
1116 let |
1117 let |
1117 val (prem', concl) = dest_implies lhs; |
1118 val (prem', concl) = Thm.dest_implies lhs; |
1118 val (prem'', _) = dest_implies rhs |
1119 val (prem'', _) = Thm.dest_implies rhs |
1119 in transitive (transitive |
1120 in transitive (transitive |
1120 (Thm.instantiate ([], [(cA, prem'), (cB, prem), (cC, concl)]) |
1121 (Thm.instantiate ([], [(cA, prem'), (cB, prem), (cC, concl)]) |
1121 Drule.swap_prems_eq) eq') |
1122 Drule.swap_prems_eq) eq') |
1122 (Thm.instantiate ([], [(cA, prem), (cB, prem''), (cC, concl)]) |
1123 (Thm.instantiate ([], [(cA, prem), (cB, prem''), (cC, concl)]) |
1123 Drule.swap_prems_eq) |
1124 Drule.swap_prems_eq) |
1127 and rebuild [] _ _ _ _ eq = eq |
1128 and rebuild [] _ _ _ _ eq = eq |
1128 | rebuild (prem :: prems) concl (rrs :: rrss) (asm :: asms) ss eq = |
1129 | rebuild (prem :: prems) concl (rrs :: rrss) (asm :: asms) ss eq = |
1129 let |
1130 let |
1130 val ss' = add_rrules (rev rrss, rev asms) ss; |
1131 val ss' = add_rrules (rev rrss, rev asms) ss; |
1131 val concl' = |
1132 val concl' = |
1132 Drule.mk_implies (prem, the_default concl (Option.map Drule.rhs_of eq)); |
1133 Drule.mk_implies (prem, the_default concl (Option.map Thm.rhs_of eq)); |
1133 val dprem = Option.map (curry (disch false) prem) |
1134 val dprem = Option.map (curry (disch false) prem) |
1134 in case rewritec (prover, thy, maxidx) ss' concl' of |
1135 in case rewritec (prover, thy, maxidx) ss' concl' of |
1135 NONE => rebuild prems concl' rrss asms ss (dprem eq) |
1136 NONE => rebuild prems concl' rrss asms ss (dprem eq) |
1136 | SOME (eq', _) => transitive2 (Library.foldl (disch false o swap) |
1137 | SOME (eq', _) => transitive2 (Library.foldl (disch false o swap) |
1137 (the (transitive3 (dprem eq) eq'), prems)) |
1138 (the (transitive3 (dprem eq) eq'), prems)) |
1138 (mut_impc0 (rev prems) (Drule.rhs_of eq') (rev rrss) (rev asms) ss) |
1139 (mut_impc0 (rev prems) (Thm.rhs_of eq') (rev rrss) (rev asms) ss) |
1139 end |
1140 end |
1140 |
1141 |
1141 and mut_impc0 prems concl rrss asms ss = |
1142 and mut_impc0 prems concl rrss asms ss = |
1142 let |
1143 let |
1143 val prems' = strip_imp_prems concl; |
1144 val prems' = strip_imp_prems concl; |
1162 NONE => mut_impc prems concl rrss asms (prem :: prems') |
1163 NONE => mut_impc prems concl rrss asms (prem :: prems') |
1163 (rrs :: rrss') (asm :: asms') (NONE :: eqns) ss changed |
1164 (rrs :: rrss') (asm :: asms') (NONE :: eqns) ss changed |
1164 (if k = 0 then 0 else k - 1) |
1165 (if k = 0 then 0 else k - 1) |
1165 | SOME eqn => |
1166 | SOME eqn => |
1166 let |
1167 let |
1167 val prem' = Drule.rhs_of eqn; |
1168 val prem' = Thm.rhs_of eqn; |
1168 val tprems = map term_of prems; |
1169 val tprems = map term_of prems; |
1169 val i = 1 + Library.foldl Int.max (~1, map (fn p => |
1170 val i = 1 + Library.foldl Int.max (~1, map (fn p => |
1170 find_index (fn q => q aconv p) tprems) (#hyps (rep_thm eqn))); |
1171 find_index (fn q => q aconv p) tprems) (#hyps (rep_thm eqn))); |
1171 val (rrs', asm') = rules_of_prem ss prem' |
1172 val (rrs', asm') = rules_of_prem ss prem' |
1172 in mut_impc prems concl rrss asms (prem' :: prems') |
1173 in mut_impc prems concl rrss asms (prem' :: prems') |
1176 ss (length prems') ~1 |
1177 ss (length prems') ~1 |
1177 end |
1178 end |
1178 |
1179 |
1179 (*legacy code - only for backwards compatibility*) |
1180 (*legacy code - only for backwards compatibility*) |
1180 and nonmut_impc ct ss = |
1181 and nonmut_impc ct ss = |
1181 let val (prem, conc) = dest_implies ct; |
1182 let val (prem, conc) = Thm.dest_implies ct; |
1182 val thm1 = if simprem then botc skel0 ss prem else NONE; |
1183 val thm1 = if simprem then botc skel0 ss prem else NONE; |
1183 val prem1 = the_default prem (Option.map Drule.rhs_of thm1); |
1184 val prem1 = the_default prem (Option.map Thm.rhs_of thm1); |
1184 val ss1 = if not useprem then ss else add_rrules |
1185 val ss1 = if not useprem then ss else add_rrules |
1185 (apsnd single (apfst single (rules_of_prem ss prem1))) ss |
1186 (apsnd single (apfst single (rules_of_prem ss prem1))) ss |
1186 in (case botc skel0 ss1 conc of |
1187 in (case botc skel0 ss1 conc of |
1187 NONE => (case thm1 of |
1188 NONE => (case thm1 of |
1188 NONE => NONE |
1189 NONE => NONE |
1251 (theory_context (Thm.theory_of_cterm ct) empty_ss addsimps thms) ct; |
1252 (theory_context (Thm.theory_of_cterm ct) empty_ss addsimps thms) ct; |
1252 |
1253 |
1253 (*Rewrite a theorem*) |
1254 (*Rewrite a theorem*) |
1254 fun simplify _ [] th = th |
1255 fun simplify _ [] th = th |
1255 | simplify full thms th = |
1256 | simplify full thms th = |
1256 Drule.fconv_rule (rewrite_cterm (full, false, false) simple_prover |
1257 Conv.fconv_rule (rewrite_cterm (full, false, false) simple_prover |
1257 (theory_context (Thm.theory_of_thm th) empty_ss addsimps thms)) th; |
1258 (theory_context (Thm.theory_of_thm th) empty_ss addsimps thms)) th; |
1258 |
1259 |
1259 val rewrite_rule = simplify true; |
1260 val rewrite_rule = simplify true; |
1260 |
1261 |
1261 (*simple term rewriting -- no proof*) |
1262 (*simple term rewriting -- no proof*) |
1262 fun rewrite_term thy rules procs = |
1263 fun rewrite_term thy rules procs = |
1263 Pattern.rewrite_term thy (map decomp_simp' rules) procs; |
1264 Pattern.rewrite_term thy (map decomp_simp' rules) procs; |
1264 |
1265 |
1265 fun rewrite_thm mode prover ss = Drule.fconv_rule (rewrite_cterm mode prover ss); |
1266 fun rewrite_thm mode prover ss = Conv.fconv_rule (rewrite_cterm mode prover ss); |
1266 |
1267 |
1267 (*Rewrite the subgoals of a proof state (represented by a theorem) *) |
1268 (*Rewrite the subgoals of a proof state (represented by a theorem) *) |
1268 fun rewrite_goals_rule thms th = |
1269 fun rewrite_goals_rule thms th = |
1269 Drule.fconv_rule (Drule.goals_conv (K true) (rewrite_cterm (true, true, true) simple_prover |
1270 Conv.fconv_rule (Conv.goals_conv (K true) (rewrite_cterm (true, true, true) simple_prover |
1270 (theory_context (Thm.theory_of_thm th) empty_ss addsimps thms))) th; |
1271 (theory_context (Thm.theory_of_thm th) empty_ss addsimps thms))) th; |
1271 |
1272 |
1272 (*Rewrite the subgoal of a proof state (represented by a theorem)*) |
1273 (*Rewrite the subgoal of a proof state (represented by a theorem)*) |
1273 fun rewrite_goal_rule mode prover ss i thm = |
1274 fun rewrite_goal_rule mode prover ss i thm = |
1274 if 0 < i andalso i <= nprems_of thm |
1275 if 0 < i andalso i <= nprems_of thm |
1275 then Drule.fconv_rule (Drule.goals_conv (fn j => j=i) (rewrite_cterm mode prover ss)) thm |
1276 then Conv.fconv_rule (Conv.goals_conv (fn j => j=i) (rewrite_cterm mode prover ss)) thm |
1276 else raise THM("rewrite_goal_rule", i, [thm]); |
1277 else raise THM("rewrite_goal_rule", i, [thm]); |
1277 |
1278 |
1278 |
1279 |
1279 (** meta-rewriting tactics **) |
1280 (** meta-rewriting tactics **) |
1280 |
1281 |
1318 |
1319 |
1319 local |
1320 local |
1320 |
1321 |
1321 fun gen_norm_hhf ss th = |
1322 fun gen_norm_hhf ss th = |
1322 (if Drule.is_norm_hhf (Thm.prop_of th) then th |
1323 (if Drule.is_norm_hhf (Thm.prop_of th) then th |
1323 else Drule.fconv_rule (rewrite_cterm (true, false, false) (K (K NONE)) ss) th) |
1324 else Conv.fconv_rule (rewrite_cterm (true, false, false) (K (K NONE)) ss) th) |
1324 |> Thm.adjust_maxidx_thm ~1 |
1325 |> Thm.adjust_maxidx_thm ~1 |
1325 |> Drule.gen_all; |
1326 |> Drule.gen_all; |
1326 |
1327 |
1327 val ss = theory_context ProtoPure.thy empty_ss addsimps [Drule.norm_hhf_eq]; |
1328 val ss = theory_context ProtoPure.thy empty_ss addsimps [Drule.norm_hhf_eq]; |
1328 |
1329 |