944 if fo then Thm.first_order_match (elhs', eta_t') |
944 if fo then Thm.first_order_match (elhs', eta_t') |
945 else Thm.match (elhs', eta_t'); |
945 else Thm.match (elhs', eta_t'); |
946 val thm' = Thm.instantiate insts (Thm.rename_boundvars lhs eta_t rthm); |
946 val thm' = Thm.instantiate insts (Thm.rename_boundvars lhs eta_t rthm); |
947 val prop' = Thm.prop_of thm'; |
947 val prop' = Thm.prop_of thm'; |
948 val unconditional = (Logic.count_prems prop' = 0); |
948 val unconditional = (Logic.count_prems prop' = 0); |
949 val (lhs', rhs') = Logic.dest_equals (Logic.strip_imp_concl prop') |
949 val (lhs', rhs') = Logic.dest_equals (Logic.strip_imp_concl prop'); |
950 in |
950 in |
951 if perm andalso not (termless (rhs', lhs')) |
951 if perm andalso not (termless (rhs', lhs')) |
952 then (trace_named_thm ctxt (fn () => "Cannot apply permutative rewrite rule") (thm, name); |
952 then |
953 trace_thm ctxt (fn () => "Term does not become smaller:") thm'; NONE) |
953 (trace_named_thm ctxt (fn () => "Cannot apply permutative rewrite rule") (thm, name); |
954 else (trace_named_thm ctxt (fn () => "Applying instance of rewrite rule") (thm, name); |
954 trace_thm ctxt (fn () => "Term does not become smaller:") thm'; |
955 if unconditional |
955 NONE) |
956 then |
956 else |
957 (trace_thm ctxt (fn () => "Rewriting:") thm'; |
957 (trace_named_thm ctxt (fn () => "Applying instance of rewrite rule") (thm, name); |
|
958 if unconditional |
|
959 then |
|
960 (trace_thm ctxt (fn () => "Rewriting:") thm'; |
|
961 let |
|
962 val lr = Logic.dest_equals prop; |
|
963 val SOME thm'' = check_conv ctxt false eta_thm thm'; |
|
964 in SOME (thm'', uncond_skel (congs, lr)) end) |
|
965 else |
|
966 (trace_thm ctxt (fn () => "Trying to rewrite:") thm'; |
|
967 if simp_depth ctxt > Config.get ctxt simp_depth_limit |
|
968 then |
958 let |
969 let |
959 val lr = Logic.dest_equals prop; |
970 val s = "simp_depth_limit exceeded - giving up"; |
960 val SOME thm'' = check_conv ctxt false eta_thm thm'; |
971 val _ = trace ctxt false (fn () => s); |
961 in SOME (thm'', uncond_skel (congs, lr)) end) |
972 val _ = Context_Position.if_visible ctxt warning s; |
962 else |
973 in NONE end |
963 (trace_thm ctxt (fn () => "Trying to rewrite:") thm'; |
974 else |
964 if simp_depth ctxt > Config.get ctxt simp_depth_limit |
975 (case prover ctxt thm' of |
965 then |
|
966 let |
|
967 val s = "simp_depth_limit exceeded - giving up"; |
|
968 val _ = trace ctxt false (fn () => s); |
|
969 val _ = Context_Position.if_visible ctxt warning s; |
|
970 in NONE end |
|
971 else |
|
972 case prover ctxt thm' of |
|
973 NONE => (trace_thm ctxt (fn () => "FAILED") thm'; NONE) |
976 NONE => (trace_thm ctxt (fn () => "FAILED") thm'; NONE) |
974 | SOME thm2 => |
977 | SOME thm2 => |
975 (case check_conv ctxt true eta_thm thm2 of |
978 (case check_conv ctxt true eta_thm thm2 of |
976 NONE => NONE |
979 NONE => NONE |
977 | SOME thm2' => |
980 | SOME thm2' => |
978 let |
981 let |
979 val concl = Logic.strip_imp_concl prop; |
982 val concl = Logic.strip_imp_concl prop; |
980 val lr = Logic.dest_equals concl; |
983 val lr = Logic.dest_equals concl; |
981 in SOME (thm2', cond_skel (congs, lr)) end))) |
984 in SOME (thm2', cond_skel (congs, lr)) end)))) |
982 end; |
985 end; |
983 |
986 |
984 fun rews [] = NONE |
987 fun rews [] = NONE |
985 | rews (rrule :: rrules) = |
988 | rews (rrule :: rrules) = |
986 let val opt = rew rrule handle Pattern.MATCH => NONE |
989 let val opt = rew rrule handle Pattern.MATCH => NONE |
987 in case opt of NONE => rews rrules | some => some end; |
990 in (case opt of NONE => rews rrules | some => some) end; |
988 |
991 |
989 fun sort_rrules rrs = |
992 fun sort_rrules rrs = |
990 let |
993 let |
991 fun is_simple ({thm, ...}: rrule) = |
994 fun is_simple ({thm, ...}: rrule) = |
992 (case Thm.prop_of thm of |
995 (case Thm.prop_of thm of |
1001 |
1004 |
1002 fun proc_rews [] = NONE |
1005 fun proc_rews [] = NONE |
1003 | proc_rews (Proc {name, proc, lhs, ...} :: ps) = |
1006 | proc_rews (Proc {name, proc, lhs, ...} :: ps) = |
1004 if Pattern.matches (Proof_Context.theory_of ctxt) (Thm.term_of lhs, Thm.term_of t) then |
1007 if Pattern.matches (Proof_Context.theory_of ctxt) (Thm.term_of lhs, Thm.term_of t) then |
1005 (debug_term ctxt false (fn () => "Trying procedure " ^ quote name ^ " on:") eta_t; |
1008 (debug_term ctxt false (fn () => "Trying procedure " ^ quote name ^ " on:") eta_t; |
1006 case proc ctxt eta_t' of |
1009 (case proc ctxt eta_t' of |
1007 NONE => (debug ctxt false (fn () => "FAILED"); proc_rews ps) |
1010 NONE => (debug ctxt false (fn () => "FAILED"); proc_rews ps) |
1008 | SOME raw_thm => |
1011 | SOME raw_thm => |
1009 (trace_thm ctxt (fn () => "Procedure " ^ quote name ^ " produced rewrite rule:") |
1012 (trace_thm ctxt (fn () => "Procedure " ^ quote name ^ " produced rewrite rule:") |
1010 raw_thm; |
1013 raw_thm; |
1011 (case rews (mk_procrule ctxt raw_thm) of |
1014 (case rews (mk_procrule ctxt raw_thm) of |
1012 NONE => (trace_cterm ctxt true (fn () => "IGNORED result of simproc " ^ quote name ^ |
1015 NONE => (trace_cterm ctxt true (fn () => "IGNORED result of simproc " ^ quote name ^ |
1013 " -- does not match") t; proc_rews ps) |
1016 " -- does not match") t; proc_rews ps) |
1014 | some => some))) |
1017 | some => some)))) |
1015 else proc_rews ps; |
1018 else proc_rews ps; |
1016 in |
1019 in |
1017 (case eta_t of |
1020 (case eta_t of |
1018 Abs _ $ _ => SOME (Thm.transitive eta_thm (Thm.beta_conversion false eta_t'), skel0) |
1021 Abs _ $ _ => SOME (Thm.transitive eta_thm (Thm.beta_conversion false eta_t'), skel0) |
1019 | _ => |
1022 | _ => |
1050 apsnd Thm.dest_equals (Thm.dest_implies (hd (cprems_of Drule.imp_cong))); |
1053 apsnd Thm.dest_equals (Thm.dest_implies (hd (cprems_of Drule.imp_cong))); |
1051 |
1054 |
1052 fun transitive1 NONE NONE = NONE |
1055 fun transitive1 NONE NONE = NONE |
1053 | transitive1 (SOME thm1) NONE = SOME thm1 |
1056 | transitive1 (SOME thm1) NONE = SOME thm1 |
1054 | transitive1 NONE (SOME thm2) = SOME thm2 |
1057 | transitive1 NONE (SOME thm2) = SOME thm2 |
1055 | transitive1 (SOME thm1) (SOME thm2) = SOME (Thm.transitive thm1 thm2) |
1058 | transitive1 (SOME thm1) (SOME thm2) = SOME (Thm.transitive thm1 thm2); |
1056 |
1059 |
1057 fun transitive2 thm = transitive1 (SOME thm); |
1060 fun transitive2 thm = transitive1 (SOME thm); |
1058 fun transitive3 thm = transitive1 thm o SOME; |
1061 fun transitive3 thm = transitive1 thm o SOME; |
1059 |
1062 |
1060 fun bottomc ((simprem, useprem, mutsimp), prover, maxidx) = |
1063 fun bottomc ((simprem, useprem, mutsimp), prover, maxidx) = |
1061 let |
1064 let |
1062 fun botc skel ctxt t = |
1065 fun botc skel ctxt t = |
1063 if is_Var skel then NONE |
1066 if is_Var skel then NONE |
1064 else |
1067 else |
1065 (case subc skel ctxt t of |
1068 (case subc skel ctxt t of |
1066 some as SOME thm1 => |
1069 some as SOME thm1 => |
1067 (case rewritec (prover, maxidx) ctxt (Thm.rhs_of thm1) of |
1070 (case rewritec (prover, maxidx) ctxt (Thm.rhs_of thm1) of |
1068 SOME (thm2, skel2) => |
1071 SOME (thm2, skel2) => |
1069 transitive2 (Thm.transitive thm1 thm2) |
1072 transitive2 (Thm.transitive thm1 thm2) |
1070 (botc skel2 ctxt (Thm.rhs_of thm2)) |
|
1071 | NONE => some) |
|
1072 | NONE => |
|
1073 (case rewritec (prover, maxidx) ctxt t of |
|
1074 SOME (thm2, skel2) => transitive2 thm2 |
|
1075 (botc skel2 ctxt (Thm.rhs_of thm2)) |
1073 (botc skel2 ctxt (Thm.rhs_of thm2)) |
1076 | NONE => NONE)) |
1074 | NONE => some) |
|
1075 | NONE => |
|
1076 (case rewritec (prover, maxidx) ctxt t of |
|
1077 SOME (thm2, skel2) => transitive2 thm2 |
|
1078 (botc skel2 ctxt (Thm.rhs_of thm2)) |
|
1079 | NONE => NONE)) |
1077 |
1080 |
1078 and try_botc ctxt t = |
1081 and try_botc ctxt t = |
1079 (case botc skel0 ctxt t of |
1082 (case botc skel0 ctxt t of |
1080 SOME trec1 => trec1 |
1083 SOME trec1 => trec1 |
1081 | NONE => (Thm.reflexive t)) |
1084 | NONE => Thm.reflexive t) |
1082 |
1085 |
1083 and subc skel ctxt t0 = |
1086 and subc skel ctxt t0 = |
1084 let val Simpset ({bounds, ...}, {congs, ...}) = simpset_of ctxt in |
1087 let val Simpset ({bounds, ...}, {congs, ...}) = simpset_of ctxt in |
1085 (case term_of t0 of |
1088 (case term_of t0 of |
1086 Abs (a, T, _) => |
1089 Abs (a, T, _) => |
1092 if b <> b' then |
1095 if b <> b' then |
1093 warning ("Simplifier: renamed bound variable " ^ |
1096 warning ("Simplifier: renamed bound variable " ^ |
1094 quote b ^ " to " ^ quote b' ^ Position.here (Position.thread_data ())) |
1097 quote b ^ " to " ^ quote b' ^ Position.here (Position.thread_data ())) |
1095 else (); |
1098 else (); |
1096 val ctxt' = add_bound ((b', T), a) ctxt; |
1099 val ctxt' = add_bound ((b', T), a) ctxt; |
1097 val skel' = case skel of Abs (_, _, sk) => sk | _ => skel0; |
1100 val skel' = (case skel of Abs (_, _, sk) => sk | _ => skel0); |
1098 in |
1101 in |
1099 (case botc skel' ctxt' t' of |
1102 (case botc skel' ctxt' t' of |
1100 SOME thm => SOME (Thm.abstract_rule a v thm) |
1103 SOME thm => SOME (Thm.abstract_rule a v thm) |
1101 | NONE => NONE) |
1104 | NONE => NONE) |
1102 end |
1105 end |
1103 | t $ _ => (case t of |
1106 | t $ _ => |
|
1107 (case t of |
1104 Const ("==>", _) $ _ => impc t0 ctxt |
1108 Const ("==>", _) $ _ => impc t0 ctxt |
1105 | Abs _ => |
1109 | Abs _ => |
1106 let val thm = Thm.beta_conversion false t0 |
1110 let val thm = Thm.beta_conversion false t0 |
1107 in case subc skel0 ctxt (Thm.rhs_of thm) of |
1111 in |
1108 NONE => SOME thm |
1112 (case subc skel0 ctxt (Thm.rhs_of thm) of |
1109 | SOME thm' => SOME (Thm.transitive thm thm') |
1113 NONE => SOME thm |
|
1114 | SOME thm' => SOME (Thm.transitive thm thm')) |
1110 end |
1115 end |
1111 | _ => |
1116 | _ => |
1112 let fun appc () = |
1117 let fun appc () = |
1113 let |
1118 let |
1114 val (tskel, uskel) = case skel of |
1119 val (tskel, uskel) = |
|
1120 (case skel of |
1115 tskel $ uskel => (tskel, uskel) |
1121 tskel $ uskel => (tskel, uskel) |
1116 | _ => (skel0, skel0); |
1122 | _ => (skel0, skel0)); |
1117 val (ct, cu) = Thm.dest_comb t0 |
1123 val (ct, cu) = Thm.dest_comb t0; |
1118 in |
1124 in |
1119 (case botc tskel ctxt ct of |
1125 (case botc tskel ctxt ct of |
1120 SOME thm1 => |
1126 SOME thm1 => |
1121 (case botc uskel ctxt cu of |
1127 (case botc uskel ctxt cu of |
1122 SOME thm2 => SOME (Thm.combination thm1 thm2) |
1128 SOME thm2 => SOME (Thm.combination thm1 thm2) |
1123 | NONE => SOME (Thm.combination thm1 (Thm.reflexive cu))) |
1129 | NONE => SOME (Thm.combination thm1 (Thm.reflexive cu))) |
1124 | NONE => |
1130 | NONE => |
1125 (case botc uskel ctxt cu of |
1131 (case botc uskel ctxt cu of |
1126 SOME thm1 => SOME (Thm.combination (Thm.reflexive ct) thm1) |
1132 SOME thm1 => SOME (Thm.combination (Thm.reflexive ct) thm1) |
1127 | NONE => NONE)) |
1133 | NONE => NONE)) |
1128 end |
1134 end |
1129 val (h, ts) = strip_comb t |
1135 val (h, ts) = strip_comb t; |
1130 in case cong_name h of |
1136 in |
1131 SOME a => |
1137 (case cong_name h of |
1132 (case AList.lookup (op =) (fst congs) a of |
1138 SOME a => |
1133 NONE => appc () |
1139 (case AList.lookup (op =) (fst congs) a of |
1134 | SOME cong => |
1140 NONE => appc () |
|
1141 | SOME cong => |
1135 (*post processing: some partial applications h t1 ... tj, j <= length ts, |
1142 (*post processing: some partial applications h t1 ... tj, j <= length ts, |
1136 may be a redex. Example: map (%x. x) = (%xs. xs) wrt map_cong*) |
1143 may be a redex. Example: map (%x. x) = (%xs. xs) wrt map_cong*) |
1137 (let |
1144 (let |
1138 val thm = congc (prover ctxt) ctxt maxidx cong t0; |
1145 val thm = congc (prover ctxt) ctxt maxidx cong t0; |
1139 val t = the_default t0 (Option.map Thm.rhs_of thm); |
1146 val t = the_default t0 (Option.map Thm.rhs_of thm); |
1140 val (cl, cr) = Thm.dest_comb t |
1147 val (cl, cr) = Thm.dest_comb t |
1141 val dVar = Var(("", 0), dummyT) |
1148 val dVar = Var(("", 0), dummyT) |
1142 val skel = |
1149 val skel = |
1143 list_comb (h, replicate (length ts) dVar) |
1150 list_comb (h, replicate (length ts) dVar) |
1144 in case botc skel ctxt cl of |
1151 in |
1145 NONE => thm |
1152 (case botc skel ctxt cl of |
1146 | SOME thm' => transitive3 thm |
1153 NONE => thm |
1147 (Thm.combination thm' (Thm.reflexive cr)) |
1154 | SOME thm' => |
1148 end handle Pattern.MATCH => appc ())) |
1155 transitive3 thm (Thm.combination thm' (Thm.reflexive cr))) |
1149 | _ => appc () |
1156 end handle Pattern.MATCH => appc ())) |
|
1157 | _ => appc ()) |
1150 end) |
1158 end) |
1151 | _ => NONE) |
1159 | _ => NONE) |
1152 end |
1160 end |
1153 and impc ct ctxt = |
1161 and impc ct ctxt = |
1154 if mutsimp then mut_impc0 [] ct [] [] ctxt else nonmut_impc ct ctxt |
1162 if mutsimp then mut_impc0 [] ct [] [] ctxt |
|
1163 else nonmut_impc ct ctxt |
1155 |
1164 |
1156 and rules_of_prem ctxt prem = |
1165 and rules_of_prem ctxt prem = |
1157 if maxidx_of_term (term_of prem) <> ~1 |
1166 if maxidx_of_term (term_of prem) <> ~1 |
1158 then (trace_cterm ctxt true |
1167 then (trace_cterm ctxt true |
1159 (fn () => "Cannot add premise as rewrite rule because it contains (type) unknowns:") |
1168 (fn () => "Cannot add premise as rewrite rule because it contains (type) unknowns:") |
1169 let |
1178 let |
1170 val (lhs, rhs) = Thm.dest_equals (Thm.cprop_of eq); |
1179 val (lhs, rhs) = Thm.dest_equals (Thm.cprop_of eq); |
1171 val eq' = Thm.implies_elim (Thm.instantiate |
1180 val eq' = Thm.implies_elim (Thm.instantiate |
1172 ([], [(cA, prem), (cB, lhs), (cC, rhs)]) Drule.imp_cong) |
1181 ([], [(cA, prem), (cB, lhs), (cC, rhs)]) Drule.imp_cong) |
1173 (Thm.implies_intr prem eq) |
1182 (Thm.implies_intr prem eq) |
1174 in if not r then eq' else |
1183 in |
1175 let |
1184 if not r then eq' |
1176 val (prem', concl) = Thm.dest_implies lhs; |
1185 else |
1177 val (prem'', _) = Thm.dest_implies rhs |
1186 let |
1178 in Thm.transitive (Thm.transitive |
1187 val (prem', concl) = Thm.dest_implies lhs; |
1179 (Thm.instantiate ([], [(cA, prem'), (cB, prem), (cC, concl)]) |
1188 val (prem'', _) = Thm.dest_implies rhs |
1180 Drule.swap_prems_eq) eq') |
1189 in Thm.transitive (Thm.transitive |
1181 (Thm.instantiate ([], [(cA, prem), (cB, prem''), (cC, concl)]) |
1190 (Thm.instantiate ([], [(cA, prem'), (cB, prem), (cC, concl)]) |
1182 Drule.swap_prems_eq) |
1191 Drule.swap_prems_eq) eq') |
1183 end |
1192 (Thm.instantiate ([], [(cA, prem), (cB, prem''), (cC, concl)]) |
|
1193 Drule.swap_prems_eq) |
|
1194 end |
1184 end |
1195 end |
1185 |
1196 |
1186 and rebuild [] _ _ _ _ eq = eq |
1197 and rebuild [] _ _ _ _ eq = eq |
1187 | rebuild (prem :: prems) concl (_ :: rrss) (_ :: asms) ctxt eq = |
1198 | rebuild (prem :: prems) concl (_ :: rrss) (_ :: asms) ctxt eq = |
1188 let |
1199 let |
1216 else rebuild prems' concl rrss' asms' ctxt |
1227 else rebuild prems' concl rrss' asms' ctxt |
1217 (botc skel0 (add_rrules (rev rrss', rev asms') ctxt) concl)) |
1228 (botc skel0 (add_rrules (rev rrss', rev asms') ctxt) concl)) |
1218 |
1229 |
1219 | mut_impc (prem :: prems) concl (rrs :: rrss) (asm :: asms) |
1230 | mut_impc (prem :: prems) concl (rrs :: rrss) (asm :: asms) |
1220 prems' rrss' asms' eqns ctxt changed k = |
1231 prems' rrss' asms' eqns ctxt changed k = |
1221 case (if k = 0 then NONE else botc skel0 (add_rrules |
1232 (case (if k = 0 then NONE else botc skel0 (add_rrules |
1222 (rev rrss' @ rrss, rev asms' @ asms) ctxt) prem) of |
1233 (rev rrss' @ rrss, rev asms' @ asms) ctxt) prem) of |
1223 NONE => mut_impc prems concl rrss asms (prem :: prems') |
1234 NONE => mut_impc prems concl rrss asms (prem :: prems') |
1224 (rrs :: rrss') (asm :: asms') (NONE :: eqns) ctxt changed |
1235 (rrs :: rrss') (asm :: asms') (NONE :: eqns) ctxt changed |
1225 (if k = 0 then 0 else k - 1) |
1236 (if k = 0 then 0 else k - 1) |
1226 | SOME eqn => |
1237 | SOME eqn => |
1227 let |
1238 let |
1228 val prem' = Thm.rhs_of eqn; |
1239 val prem' = Thm.rhs_of eqn; |
1229 val tprems = map term_of prems; |
1240 val tprems = map term_of prems; |
1230 val i = 1 + fold Integer.max (map (fn p => |
1241 val i = 1 + fold Integer.max (map (fn p => |
1231 find_index (fn q => q aconv p) tprems) (Thm.hyps_of eqn)) ~1; |
1242 find_index (fn q => q aconv p) tprems) (Thm.hyps_of eqn)) ~1; |
1232 val (rrs', asm') = rules_of_prem ctxt prem'; |
1243 val (rrs', asm') = rules_of_prem ctxt prem'; |
1233 in mut_impc prems concl rrss asms (prem' :: prems') |
1244 in |
1234 (rrs' :: rrss') (asm' :: asms') (SOME (fold_rev (disch true) |
1245 mut_impc prems concl rrss asms (prem' :: prems') |
1235 (take i prems) |
1246 (rrs' :: rrss') (asm' :: asms') |
1236 (Drule.imp_cong_rule eqn (Thm.reflexive (Drule.list_implies |
1247 (SOME (fold_rev (disch true) |
1237 (drop i prems, concl))))) :: eqns) |
1248 (take i prems) |
1238 ctxt (length prems') ~1 |
1249 (Drule.imp_cong_rule eqn (Thm.reflexive (Drule.list_implies |
1239 end |
1250 (drop i prems, concl))))) :: eqns) |
1240 |
1251 ctxt (length prems') ~1 |
1241 (*legacy code - only for backwards compatibility*) |
1252 end) |
|
1253 |
|
1254 (*legacy code -- only for backwards compatibility*) |
1242 and nonmut_impc ct ctxt = |
1255 and nonmut_impc ct ctxt = |
1243 let |
1256 let |
1244 val (prem, conc) = Thm.dest_implies ct; |
1257 val (prem, conc) = Thm.dest_implies ct; |
1245 val thm1 = if simprem then botc skel0 ctxt prem else NONE; |
1258 val thm1 = if simprem then botc skel0 ctxt prem else NONE; |
1246 val prem1 = the_default prem (Option.map Thm.rhs_of thm1); |
1259 val prem1 = the_default prem (Option.map Thm.rhs_of thm1); |