50 val extract_free_congs : unit -> thm list |
50 val extract_free_congs : unit -> thm list |
51 *) |
51 *) |
52 val tracing : bool ref |
52 val tracing : bool ref |
53 end; |
53 end; |
54 |
54 |
55 functor SimpFun (Simp_data: SIMP_DATA) : SIMP = |
55 functor SimpFun (Simp_data: SIMP_DATA) : SIMP = |
56 struct |
56 struct |
57 |
57 |
58 local open Simp_data in |
58 local open Simp_data in |
59 |
59 |
60 (*For taking apart reductions into left, right hand sides*) |
60 (*For taking apart reductions into left, right hand sides*) |
72 |
72 |
73 (*match subgoal i against possible theorems in the net. |
73 (*match subgoal i against possible theorems in the net. |
74 Similar to match_from_nat_tac, but the net does not contain numbers; |
74 Similar to match_from_nat_tac, but the net does not contain numbers; |
75 rewrite rules are not ordered.*) |
75 rewrite rules are not ordered.*) |
76 fun net_tac net = |
76 fun net_tac net = |
77 SUBGOAL(fn (prem,i) => |
77 SUBGOAL(fn (prem,i) => |
78 resolve_tac (Net.unify_term net (Logic.strip_assums_concl prem)) i); |
78 resolve_tac (Net.unify_term net (Logic.strip_assums_concl prem)) i); |
79 |
79 |
80 (*match subgoal i against possible theorems indexed by lhs in the net*) |
80 (*match subgoal i against possible theorems indexed by lhs in the net*) |
81 fun lhs_net_tac net = |
81 fun lhs_net_tac net = |
82 SUBGOAL(fn (prem,i) => |
82 SUBGOAL(fn (prem,i) => |
83 biresolve_tac (Net.unify_term net |
83 biresolve_tac (Net.unify_term net |
84 (lhs_of (Logic.strip_assums_concl prem))) i); |
84 (lhs_of (Logic.strip_assums_concl prem))) i); |
85 |
85 |
86 fun nth_subgoal i thm = List.nth(prems_of thm,i-1); |
86 fun nth_subgoal i thm = List.nth(prems_of thm,i-1); |
87 |
87 |
108 |
108 |
109 val (normI_thms,normE_thms) = split_list norm_thms; |
109 val (normI_thms,normE_thms) = split_list norm_thms; |
110 |
110 |
111 (*Get the norm constants from norm_thms*) |
111 (*Get the norm constants from norm_thms*) |
112 val norms = |
112 val norms = |
113 let fun norm thm = |
113 let fun norm thm = |
114 case lhs_of(concl_of thm) of |
114 case lhs_of(concl_of thm) of |
115 Const(n,_)$_ => n |
115 Const(n,_)$_ => n |
116 | _ => error "No constant in lhs of a norm_thm" |
116 | _ => error "No constant in lhs of a norm_thm" |
117 in map norm normE_thms end; |
117 in map norm normE_thms end; |
118 |
118 |
142 |
142 |
143 |
143 |
144 (**** Adding "NORM" tags ****) |
144 (**** Adding "NORM" tags ****) |
145 |
145 |
146 (*get name of the constant from conclusion of a congruence rule*) |
146 (*get name of the constant from conclusion of a congruence rule*) |
147 fun cong_const cong = |
147 fun cong_const cong = |
148 case head_of (lhs_of (concl_of cong)) of |
148 case head_of (lhs_of (concl_of cong)) of |
149 Const(c,_) => c |
149 Const(c,_) => c |
150 | _ => "" (*a placeholder distinct from const names*); |
150 | _ => "" (*a placeholder distinct from const names*); |
151 |
151 |
152 (*true if the term is an atomic proposition (no ==> signs) *) |
152 (*true if the term is an atomic proposition (no ==> signs) *) |
154 |
154 |
155 (*ccs contains the names of the constants possessing congruence rules*) |
155 (*ccs contains the names of the constants possessing congruence rules*) |
156 fun add_hidden_vars ccs = |
156 fun add_hidden_vars ccs = |
157 let fun add_hvars tm hvars = case tm of |
157 let fun add_hvars tm hvars = case tm of |
158 Abs(_,_,body) => OldTerm.add_term_vars(body,hvars) |
158 Abs(_,_,body) => OldTerm.add_term_vars(body,hvars) |
159 | _$_ => let val (f,args) = strip_comb tm |
159 | _$_ => let val (f,args) = strip_comb tm |
160 in case f of |
160 in case f of |
161 Const(c,T) => |
161 Const(c,T) => |
162 if member (op =) ccs c |
162 if member (op =) ccs c |
163 then fold_rev add_hvars args hvars |
163 then fold_rev add_hvars args hvars |
164 else OldTerm.add_term_vars (tm, hvars) |
164 else OldTerm.add_term_vars (tm, hvars) |
165 | _ => OldTerm.add_term_vars (tm, hvars) |
165 | _ => OldTerm.add_term_vars (tm, hvars) |
166 end |
166 end |
200 else OldTerm.add_term_frees(asm,hvars) |
200 else OldTerm.add_term_frees(asm,hvars) |
201 val hvars = fold_rev it_asms asms hvars |
201 val hvars = fold_rev it_asms asms hvars |
202 val hvs = map (#1 o dest_Var) hvars |
202 val hvs = map (#1 o dest_Var) hvars |
203 val refl1_tac = refl_tac 1 |
203 val refl1_tac = refl_tac 1 |
204 fun norm_step_tac st = st |> |
204 fun norm_step_tac st = st |> |
205 (case head_of(rhs_of_eq 1 st) of |
205 (case head_of(rhs_of_eq 1 st) of |
206 Var(ixn,_) => if ixn mem hvs then refl1_tac |
206 Var(ixn,_) => if ixn mem hvs then refl1_tac |
207 else resolve_tac normI_thms 1 ORELSE refl1_tac |
207 else resolve_tac normI_thms 1 ORELSE refl1_tac |
208 | Const _ => resolve_tac normI_thms 1 ORELSE |
208 | Const _ => resolve_tac normI_thms 1 ORELSE |
209 resolve_tac congs 1 ORELSE refl1_tac |
209 resolve_tac congs 1 ORELSE refl1_tac |
210 | Free _ => resolve_tac congs 1 ORELSE refl1_tac |
210 | Free _ => resolve_tac congs 1 ORELSE refl1_tac |
211 | _ => refl1_tac) |
211 | _ => refl1_tac) |
212 val add_norm_tac = DEPTH_FIRST (has_fewer_prems nops) norm_step_tac |
212 val add_norm_tac = DEPTH_FIRST (has_fewer_prems nops) norm_step_tac |
213 val SOME(thm'',_) = Seq.pull(add_norm_tac thm') |
213 val SOME(thm'',_) = Seq.pull(add_norm_tac thm') |
214 in thm'' end; |
214 in thm'' end; |
215 |
215 |
216 fun add_norm_tags congs = |
216 fun add_norm_tags congs = |
244 mk_simps=normed_rews[], simps=[], simp_net=Net.empty}; |
244 mk_simps=normed_rews[], simps=[], simp_net=Net.empty}; |
245 |
245 |
246 (** Insertion of congruences and rewrites **) |
246 (** Insertion of congruences and rewrites **) |
247 |
247 |
248 (*insert a thm in a thm net*) |
248 (*insert a thm in a thm net*) |
249 fun insert_thm_warn th net = |
249 fun insert_thm_warn th net = |
250 Net.insert_term Thm.eq_thm_prop (concl_of th, th) net |
250 Net.insert_term Thm.eq_thm_prop (concl_of th, th) net |
251 handle Net.INSERT => |
251 handle Net.INSERT => |
252 (writeln ("Duplicate rewrite or congruence rule:\n" ^ |
252 (writeln ("Duplicate rewrite or congruence rule:\n" ^ |
253 Display.string_of_thm_without_context th); net); |
253 Display.string_of_thm_without_context th); net); |
254 |
254 |
255 val insert_thms = fold_rev insert_thm_warn; |
255 val insert_thms = fold_rev insert_thm_warn; |
256 |
256 |
270 end; |
270 end; |
271 |
271 |
272 (** Deletion of congruences and rewrites **) |
272 (** Deletion of congruences and rewrites **) |
273 |
273 |
274 (*delete a thm from a thm net*) |
274 (*delete a thm from a thm net*) |
275 fun delete_thm_warn th net = |
275 fun delete_thm_warn th net = |
276 Net.delete_term Thm.eq_thm_prop (concl_of th, th) net |
276 Net.delete_term Thm.eq_thm_prop (concl_of th, th) net |
277 handle Net.DELETE => |
277 handle Net.DELETE => |
278 (writeln ("No such rewrite or congruence rule:\n" ^ |
278 (writeln ("No such rewrite or congruence rule:\n" ^ |
279 Display.string_of_thm_without_context th); net); |
279 Display.string_of_thm_without_context th); net); |
280 |
280 |
281 val delete_thms = fold_rev delete_thm_warn; |
281 val delete_thms = fold_rev delete_thm_warn; |
282 |
282 |
335 | _ => find_if(s,j) orelse find_if(t,j) end |
335 | _ => find_if(s,j) orelse find_if(t,j) end |
336 | find_if(_) = false; |
336 | find_if(_) = false; |
337 in find_if(tm,0) end; |
337 in find_if(tm,0) end; |
338 |
338 |
339 fun IF1_TAC cong_tac i = |
339 fun IF1_TAC cong_tac i = |
340 let fun seq_try (ifth::ifths,ifc::ifcs) thm = |
340 let fun seq_try (ifth::ifths,ifc::ifcs) thm = |
341 (COND (if_rewritable ifc i) (DETERM(rtac ifth i)) |
341 (COND (if_rewritable ifc i) (DETERM(rtac ifth i)) |
342 (seq_try(ifths,ifcs))) thm |
342 (seq_try(ifths,ifcs))) thm |
343 | seq_try([],_) thm = no_tac thm |
343 | seq_try([],_) thm = no_tac thm |
344 and try_rew thm = (seq_try(case_rews,case_consts) ORELSE one_subt) thm |
344 and try_rew thm = (seq_try(case_rews,case_consts) ORELSE one_subt) thm |
345 and one_subt thm = |
345 and one_subt thm = |
346 let val test = has_fewer_prems (nprems_of thm + 1) |
346 let val test = has_fewer_prems (nprems_of thm + 1) |
347 fun loop thm = |
347 fun loop thm = |
348 COND test no_tac |
348 COND test no_tac |
349 ((try_rew THEN DEPTH_FIRST test (refl_tac i)) |
349 ((try_rew THEN DEPTH_FIRST test (refl_tac i)) |
350 ORELSE (refl_tac i THEN loop)) thm |
350 ORELSE (refl_tac i THEN loop)) thm |
351 in (cong_tac THEN loop) thm end |
351 in (cong_tac THEN loop) thm end |
352 in COND (may_match(case_consts,i)) try_rew no_tac end; |
352 in COND (may_match(case_consts,i)) try_rew no_tac end; |
353 |
353 |
354 fun CASE_TAC (SS{cong_net,...}) i = |
354 fun CASE_TAC (SS{cong_net,...}) i = |
355 let val cong_tac = net_tac cong_net i |
355 let val cong_tac = net_tac cong_net i |
379 val params = rev (Logic.strip_params subgi) |
379 val params = rev (Logic.strip_params subgi) |
380 in variants_abs (params, Logic.strip_assums_concl subgi) end; |
380 in variants_abs (params, Logic.strip_assums_concl subgi) end; |
381 |
381 |
382 (*print lhs of conclusion of subgoal i*) |
382 (*print lhs of conclusion of subgoal i*) |
383 fun pr_goal_lhs i st = |
383 fun pr_goal_lhs i st = |
384 writeln (Syntax.string_of_term_global (Thm.theory_of_thm st) |
384 writeln (Syntax.string_of_term_global (Thm.theory_of_thm st) |
385 (lhs_of (prepare_goal i st))); |
385 (lhs_of (prepare_goal i st))); |
386 |
386 |
387 (*print conclusion of subgoal i*) |
387 (*print conclusion of subgoal i*) |
388 fun pr_goal_concl i st = |
388 fun pr_goal_concl i st = |
389 writeln (Syntax.string_of_term_global (Thm.theory_of_thm st) (prepare_goal i st)) |
389 writeln (Syntax.string_of_term_global (Thm.theory_of_thm st) (prepare_goal i st)) |
390 |
390 |
391 (*print subgoals i to j (inclusive)*) |
391 (*print subgoals i to j (inclusive)*) |
392 fun pr_goals (i,j) st = |
392 fun pr_goals (i,j) st = |
393 if i>j then () |
393 if i>j then () |
394 else (pr_goal_concl i st; pr_goals (i+1,j) st); |
394 else (pr_goal_concl i st; pr_goals (i+1,j) st); |
437 val anet' = List.foldr lhs_insert_thm anet rwrls |
437 val anet' = List.foldr lhs_insert_thm anet rwrls |
438 in if !tracing andalso not(null new_rws) |
438 in if !tracing andalso not(null new_rws) |
439 then writeln (cat_lines |
439 then writeln (cat_lines |
440 ("Adding rewrites:" :: map Display.string_of_thm_without_context new_rws)) |
440 ("Adding rewrites:" :: map Display.string_of_thm_without_context new_rws)) |
441 else (); |
441 else (); |
442 (ss,thm,anet',anet::ats,cs) |
442 (ss,thm,anet',anet::ats,cs) |
443 end; |
443 end; |
444 |
444 |
445 fun rew(seq,thm,ss,anet,ats,cs, more) = case Seq.pull seq of |
445 fun rew(seq,thm,ss,anet,ats,cs, more) = case Seq.pull seq of |
446 SOME(thm',seq') => |
446 SOME(thm',seq') => |
447 let val n = (nprems_of thm') - (nprems_of thm) |
447 let val n = (nprems_of thm') - (nprems_of thm) |
490 in exec(ss, thm, Net.empty, [], []) end; |
490 in exec(ss, thm, Net.empty, [], []) end; |
491 |
491 |
492 |
492 |
493 fun EXEC_TAC(ss,fl) (SS{auto_tac,cong_net,simp_net,...}) = |
493 fun EXEC_TAC(ss,fl) (SS{auto_tac,cong_net,simp_net,...}) = |
494 let val cong_tac = net_tac cong_net |
494 let val cong_tac = net_tac cong_net |
495 in fn i => |
495 in fn i => |
496 (fn thm => |
496 (fn thm => |
497 if i <= 0 orelse nprems_of thm < i then Seq.empty |
497 if i <= 0 orelse nprems_of thm < i then Seq.empty |
498 else Seq.single(execute(ss,fl,auto_tac,cong_tac,simp_net,i,thm))) |
498 else Seq.single(execute(ss,fl,auto_tac,cong_tac,simp_net,i,thm))) |
499 THEN TRY(auto_tac i) |
499 THEN TRY(auto_tac i) |
500 end; |
500 end; |