2 authors: Walther Neuper 2002, 2006
3 (c) due to copyright terms
5 tools for rewriting, reverse rewriting, context to thy concerning rewriting
8 signature REWRITE_TOOLS =
11 val contains_rule : Rule.rule -> Rule_Set.T -> bool
12 val atomic_appl_tacs : theory -> string -> Rule_Set.T -> term -> Tactic.input -> Tactic.input list
13 val thy_containing_rls : ThyC.theory' -> Rule_Set.identifier -> string * ThyC.theory'
14 val thy_containing_cal : ThyC.theory' -> Exec_Def.prog_calcID -> string * string
16 = ContNOrew of {applto: term, thm_rls: Celem.guh, thyID: ThyC.thyID}
17 | ContNOrewInst of {applto: term, bdvs: Rule.subst, thm_rls: Celem.guh, thminst: term, thyID: ThyC.thyID}
18 | ContRls of {applto: term, asms: term list, result: term, rls: Celem.guh, thyID: ThyC.thyID}
19 | ContRlsInst of {applto: term, asms: term list, bdvs: Rule.subst, result: term, rls: Celem.guh, thyID: ThyC.thyID}
20 | ContThm of {applat: term, applto: term, asmrls: Rule_Set.identifier, asms: (term * term) list,
21 lhs: term * term, resasms: term list, result: term, reword: Rule_Def.rew_ord', rhs: term * term,
22 thm: Celem.guh, thyID: ThyC.thyID}
23 | ContThmInst of {applat: term, applto: term, asmrls: Rule_Set.identifier, asms: (term * term) list,
24 bdvs: Rule.subst, lhs: term * term, resasms: term list, result: term, reword: Rule_Def.rew_ord',
25 rhs: term * term, thm: Celem.guh, thminst: term, thyID: ThyC.thyID}
27 val guh2filename : Celem.guh -> Celem.filename
28 val is_sym : Celem.thmID -> bool
29 val sym_drop : Celem.thmID -> Celem.thmID
30 val sym_rls : Rule_Set.T -> Rule_Set.T
31 val sym_rule : Rule.rule -> Rule.rule
32 val thms_of_rls : Rule_Set.T -> Rule.rule list
33 val theID2filename : Celem.theID -> Celem.filename
34 val no_thycontext : Celem.guh -> bool
35 val subs_from : Istate.T -> 'a -> Celem.guh -> Selem.subs
36 val guh2rewtac : Celem.guh -> Selem.subs -> Tactic.input
37 val get_tac_checked : Ctree.ctree -> Pos.pos' -> Tactic.input
38 val context_thy : Calc.T -> Tactic.input -> contthy
39 val distinct_Thm : Rule.rule list -> Rule.rule list
40 val eq_Thms : string list -> Rule.rule -> bool
41 val make_deriv : theory -> Rule_Set.T -> Rule.rule list -> ((term * term) list -> term * term -> bool) ->
42 term option -> term -> deriv
43 val reverse_deriv : theory -> Rule_Set.T -> Rule.rule list -> ((term * term) list -> term * term -> bool) ->
44 term option -> term -> (Rule.rule * (term * term list)) list
45 val get_bdv_subst : term -> (term * term) list -> Selem.subs option * Rule.subst
46 val thy_containing_thm : string -> string * string
47 val guh2theID : Celem.guh -> Celem.theID
48 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
50 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
51 val trtas2str : (term * Rule.rule * (term * term list)) list -> string
52 val eq_Thm : Rule.rule * Rule.rule -> bool
53 val deriv2str : (term * Rule.rule * (term * term list)) list -> string
54 val deriv_of_thm'' : Celem.thm'' -> string
55 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
57 (*----- unused code, kept as hints to design ideas ---------------------------------------------*)
58 val deri2str : (Rule.rule * (term * term list)) list -> string
59 val sym_trm : term -> term
62 structure Rtools(**): REWRITE_TOOLS(**) =
66 (*** reverse rewriting ***)
67 (*. a '_deriv'ation is constructed during 'reverse rewring' by an Rrls *
68 * of for connecting a user-input formula with the current calc-state. *
69 *# It is somewhat incompatible with the rest of the math-engine: *
70 * (1) it is not created by a script *
71 * (2) thus there cannot be another user-input within a derivation *
72 *# It suffers particularily from the not-well-foundedness of the math-engine*
73 * (1) FIXME other branchtyptes than Transitive will change 'embed_deriv' *
74 * (2) FIXME and eventually 'compare_step' (ie. the script interpreter) *
75 * (3) FIXME and eventually 'lev_back' *
76 *# SOME improvements are evident FIXME.040215 '_deriv'ation: *
77 * (1) FIXME nest Rls_ in 'make_deriv' *
78 * (2) FIXME do the not-reversed part in 'make_deriv' by scripts -- thus *
79 * user-input will become possible in this part of a derivation *
80 * (3) FIXME do (2) only if a derivation has been found -- for efficiency, *
81 * while a non-derivable inform requires to step until End_Proof' *
82 * (4) FIXME find criteria on when _not_ to step until End_Proof' *
85 type deriv = (* derivation for insertin one level of nodes into the Ctree *)
86 ( term * (* where the rule is applied to *)
87 Rule.rule * (* rule to be applied *)
88 ( term * (* resulting from rule application *)
89 term list)) (* assumptions resulting from rule application *)
92 fun trta2str (t, r, (t', a)) =
93 "\n(" ^ Rule.term2str t ^ ", " ^ Rule_Set.rule2str' r ^ ", (" ^ Rule.term2str t' ^ ", " ^ Rule.terms2str a ^ "))"
94 fun trtas2str trtas = (strs2str o (map trta2str)) trtas
95 val deriv2str = trtas2str
96 fun rta2str (r, (t, a)) =
97 "\n(" ^ Rule_Set.rule2str' r ^ ", (" ^ Rule.term2str t ^ ", " ^ Rule.terms2str a ^ "))"
98 fun rtas2str rtas = (strs2str o (map rta2str)) rtas
99 val deri2str = rtas2str
101 (* A1==>...==> An ==> (Lhs = Rhs) goes to A1 ==>...==> An ==> (Rhs = Lhs) *)
105 {cert = cert, tags = tags, maxidx = maxidx, shyps = shyps, hyps = hyps, tpairs = tpairs,
106 prop = prop}) = Thm.rep_thm_G thm
107 val (lhs, rhs) = (TermC.dest_equals o TermC.strip_trueprop o Logic.strip_imp_concl) prop
108 val prop' = case TermC.strip_imp_prems' prop of
109 NONE => HOLogic.Trueprop $ (TermC.mk_equality (rhs, lhs))
110 | SOME cs => TermC.ins_concl cs (HOLogic.Trueprop $ (TermC.mk_equality (rhs, lhs)))
111 in Thm.assbl_thm deriv cert tags maxidx shyps hyps tpairs prop' end
113 (* WN100910 weaker than fun sym_thm for Theory.axioms_of in isa02 *)
116 val (lhs, rhs) = (TermC.dest_equals o TermC.strip_trueprop o Logic.strip_imp_concl) trm
117 val trm' = case TermC.strip_imp_prems' trm of
118 NONE => TermC.mk_equality (rhs, lhs)
119 | SOME cs => TermC.ins_concl cs (TermC.mk_equality (rhs, lhs))
122 (* derive normalform of a rls, or derive until SOME goal,
123 and record rules applied and rewrites.
128 -> rew_ord : the order of this rls, which 1 theorem of is used
129 for rewriting 1 single step (?14.4.03)
130 -> term option : 040214 ??? use for "derive until SOME goal" ???
132 -> (term * : to this term ...
133 rule * : ... this rule is applied yielding ...
134 (term * : ... this term ...
135 term list)) : ... under these assumptions.
137 returns empty list for a normal form
138 FIXME.WN040214: treats rules as in Rls, _not_ as in Seq
140 WN060825 too complicated for the intended use by cancel_, common_nominator_
141 and unreflectedly adapted to extension of rules by Rls_: returns Rls_("sym_simpl..
143 fun make_deriv thy erls rs ro goal tt =
145 datatype switch = Appl | Noap (* unify with version in rewrite.sml *)
146 fun rew_once _ rts t Noap [] =
147 (case goal of NONE => rts | SOME _ => error ("make_deriv: no derivation for " ^ Rule.term2str t))
148 | rew_once lim rts t Appl [] = rew_once lim rts t Noap rs
149 (*| Seq _ => rts) FIXXXXXME 14.3.03*)
150 | rew_once lim rts t apno rs' =
152 NONE => rew_or_calc lim rts t apno rs'
153 | SOME g => if g = t then rts else rew_or_calc lim rts t apno rs')
154 and rew_or_calc lim rts t apno (rrs' as (r :: rs')) =
156 then (tracing ("make_deriv exceeds " ^ int2str (! Celem.lim_deriv) ^ "with deriv =\n");
157 tracing (deriv2str rts); rts)
160 Rule.Thm (thmid, tm) =>
161 (if not (! Celem.trace_rewrite) then () else tracing ("### trying thm \"" ^ thmid ^ "\"");
162 case Rewrite.rewrite_ thy ro erls true tm t of
163 NONE => rew_once lim rts t apno rs'
165 (if ! Celem.trace_rewrite then tracing ("=== rewrites to: " ^ Rule.term2str t') else ();
166 rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs'))
167 | Rule.Num_Calc (c as (op_, _)) =>
169 val _ = if not (! Celem.trace_rewrite) then () else tracing ("### trying calc. \"" ^ op_^"\"")
170 val t = TermC.uminus_to_string t
172 case Num_Calc.adhoc_thm thy c t of
173 NONE => rew_once lim rts t apno rs'
174 | SOME (thmid, tm) =>
176 val (t', a') = case Rewrite.rewrite_ thy ro erls true tm t of
178 | NONE => error "adhoc_thm: NONE"
179 val _ = if not (! Celem.trace_rewrite) then () else tracing("=== calc. to: " ^ Rule.term2str t')
180 val r' = Rule.Thm (thmid, tm)
181 in rew_once (lim - 1) (rts @ [(t, r', (t', a'))]) t' Appl rrs' end)
182 handle _ => error "derive_norm, Num_Calc: no rewrite"
184 (*| Cal1 (cc as (op_,_)) => ... WN080222 see rewrite__set_: see 7df94616c1bd and earlier*)
185 | Rule.Rls_ rls => (* WN060829: CREATES "sym_rlsID", see 7df94616c1bd and earlier*)
186 (case Rewrite.rewrite_set_ thy true rls t of
187 NONE => rew_once lim rts t apno rs'
188 | SOME (t', a') => rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs')
189 | rule => error ("rew_once: uncovered case " ^ Rule_Set.rule2str rule))
190 | rew_or_calc _ _ _ _ [] = error "rew_or_calc: called with []"
191 in rew_once (! Celem.lim_deriv) [] tt Noap rs end
194 case Symbol.explode thmID of
195 "s" :: "y" :: "m" :: "_" :: id => implode id
198 case Symbol.explode thmID of
199 "s" :: "y" :: "m" :: "_" :: _ => true
202 (*FIXXXXME.040219: detail has to handle Rls id="sym_..."
203 by applying make_deriv, rev_deriv'; see concat_deriv*)
204 fun sym_rls Rule_Set.Empty = Rule_Set.Empty
205 | sym_rls (Rule_Def.Repeat {id, scr, calc, errpatts, erls, srls, rules, rew_ord, preconds}) =
206 Rule_Def.Repeat {id = "sym_" ^ id, scr = scr, calc = calc, errpatts = errpatts, erls = erls, srls = srls,
207 rules = rules, rew_ord = rew_ord, preconds = preconds}
208 | sym_rls (Rule_Set.Seqence {id, scr, calc, errpatts, erls, srls, rules, rew_ord, preconds}) =
209 Rule_Set.Seqence {id = "sym_" ^ id, scr = scr, calc = calc, errpatts = errpatts, erls = erls, srls = srls,
210 rules = rules, rew_ord = rew_ord, preconds = preconds}
211 | sym_rls (Rule_Set.Rrls {id, scr, calc, errpatts, erls, prepat, rew_ord}) =
212 Rule_Set.Rrls {id = "sym_" ^ id, scr = scr, calc = calc, errpatts = errpatts, erls = erls,
213 prepat = prepat, rew_ord = rew_ord}
215 (* toggles sym_* and keeps "#:" for ad-hoc calculations *)
216 fun sym_rule (Rule.Thm (thmID, thm)) =
218 val thm' = sym_thm thm
219 val thmID' = case Symbol.explode thmID of
220 "s" :: "y" :: "m" :: "_" :: id => implode id
221 | "#" :: ":" :: _ => "#: " ^ Rule.string_of_thmI thm'
222 | _ => "sym_" ^ thmID
223 in Rule.Thm (thmID', thm') end
224 | sym_rule (Rule.Rls_ rls) = Rule.Rls_ (sym_rls rls) (* TODO? handle with interSteps ? *)
225 | sym_rule r = error ("sym_rule: not for " ^ Rule_Set.rule2str r)
227 (*version for reverse rewrite used before 040214*)
228 fun rev_deriv (t, r, (_, a)) = (sym_rule r, (t, a));
229 fun reverse_deriv thy erls rs ro goal t =
230 (rev o (map rev_deriv)) (make_deriv thy erls rs ro goal t)
232 fun eq_Thm (Rule.Thm (id1, _), Rule.Thm (id2,_)) = id1 = id2
233 | eq_Thm (Rule.Thm (_, _), _) = false
234 | eq_Thm (Rule.Rls_ r1, Rule.Rls_ r2) = Rule_Set.id_rls r1 = Rule_Set.id_rls r2
235 | eq_Thm (Rule.Rls_ _, _) = false
236 | eq_Thm (r1, r2) = error ("eq_Thm: called with '" ^ Rule_Set.rule2str r1 ^ "' '" ^ Rule_Set.rule2str r2 ^ "'")
237 fun distinct_Thm r = gen_distinct eq_Thm r
239 fun eq_Thms thmIDs thm = (member op = thmIDs (Celem.id_of_thm thm))
240 handle ERROR _ => false
242 fun thy_containing_thm thmDeriv =
244 val isabthys' = map Context.theory_name (Celem.isabthys ());
246 if member op= isabthys' (Celem.thyID_of_derivation_name thmDeriv)
247 then ("Isabelle", Celem.thyID_of_derivation_name thmDeriv)
248 else ("IsacKnowledge", Celem.thyID_of_derivation_name thmDeriv)
251 (* which theory in ancestors of thy' contains a ruleset *)
252 fun thy_containing_rls thy' rls' =
254 val thy = ThyC.Thy_Info_get_theory thy'
256 case AList.lookup op= (KEStore_Elems.get_rlss thy) rls' of
257 SOME (thy'', _) => (Celem.partID' thy'', thy'')
258 | _ => error ("thy_containing_rls : rls '" ^ rls' ^ "' not in ancestors of thy '" ^ thy' ^ "'")
261 (* this function cannot work as long as the datastructure does not contain thy' *)
262 fun thy_containing_cal thy' sop =
264 val thy = ThyC.Thy_Info_get_theory thy'
266 case AList.lookup op= (KEStore_Elems.get_calcs thy) sop of
267 SOME (_(*"Groups.plus_class.plus"*), _) => ("IsacKnowledge", "Base_Tools")
268 | _ => error ("thy_containing_cal : rls '" ^ sop ^ "' not in ancestors of thy '" ^ thy' ^ "'")
271 (* packing return-values to matchTheory, contextToThy for xml-generation *)
272 datatype contthy = (*also an item from KEStore on Browser ...........#*)
273 EContThy (* not from KEStore ..............................*)
274 | ContThm of (* a theorem in contex ===========================*)
275 {thyID : ThyC.thyID, (* for *2guh in sub-elems here .*)
276 thm : Celem.guh, (* theorem in the context .*)
277 applto : term, (* applied to formula ... .*)
278 applat : term, (* ... with lhs inserted .*)
279 reword : Rule_Def.rew_ord', (* order used for rewrite .*)
280 asms : (term (* asumption instantiated .*)
281 * term) list, (* asumption evaluated .*)
282 lhs : term (* lhs of the theorem ... #*)
283 * term, (* ... instantiated .*)
284 rhs : term (* rhs of the theorem ... #*)
285 * term, (* ... instantiated .*)
286 result : term, (* resulting from the rewrite .*)
287 resasms : term list, (* ... with asms stored .*)
288 asmrls : Rule_Set.identifier (* ruleset for evaluating asms .*)
290 | ContThmInst of (* a theorem with bdvs in contex ============ *)
291 {thyID : ThyC.thyID, (*for *2guh in sub-elems here .*)
292 thm : Celem.guh, (*theorem in the context .*)
293 bdvs : Rule.subst, (*bound variables to modify... .*)
294 thminst : term, (*... theorem instantiated .*)
295 applto : term, (*applied to formula ... .*)
296 applat : term, (*... with lhs inserted .*)
297 reword : Rule_Def.rew_ord', (*order used for rewrite .*)
298 asms : (term (*asumption instantiated .*)
299 * term) list, (*asumption evaluated .*)
300 lhs : term (*lhs of the theorem ... #*)
301 * term, (*... instantiated .*)
302 rhs : term (*rhs of the theorem ... #*)
303 * term, (*... instantiated .*)
304 result : term, (*resulting from the rewrite .*)
305 resasms : term list, (*... with asms stored .*)
306 asmrls : Rule_Set.identifier (*ruleset for evaluating asms .*)
308 | ContRls of (* a rule set in contex ========================= *)
309 {thyID : ThyC.thyID, (*for *2guh in sub-elems here .*)
310 rls : Celem.guh, (*rule set in the context .*)
311 applto : term, (*rewrite this formula .*)
312 result : term, (*resulting from the rewrite .*)
313 asms : term list (*... with asms stored .*)
315 | ContRlsInst of (* a rule set with bdvs in contex =========== *)
316 {thyID : ThyC.thyID, (*for *2guh in sub-elems here .*)
317 rls : Celem.guh, (*rule set in the context .*)
318 bdvs : Rule.subst, (*for bound variables in thms .*)
319 applto : term, (*rewrite this formula .*)
320 result : term, (*resulting from the rewrite .*)
321 asms : term list (*... with asms stored .*)
323 | ContNOrew of (* no rewrite for thm or rls ================== *)
324 {thyID : ThyC.thyID, (*for *2guh in sub-elems here .*)
325 thm_rls : Celem.guh, (*thm or rls in the context .*)
326 applto : term (*rewrite this formula .*)
328 | ContNOrewInst of (* no rewrite for some instantiation ====== *)
329 {thyID : ThyC.thyID, (*for *2guh in sub-elems here .*)
330 thm_rls : Celem.guh, (*thm or rls in the context .*)
331 bdvs : Rule.subst, (*for bound variables in thms .*)
332 thminst : term, (*... theorem instantiated .*)
333 applto : term (*rewrite this formula .*)
336 (*.check a rewrite-tac for bdv (RL always used *_Inst !) TODO.WN060718
337 pass other tacs unchanged.*)
338 fun get_tac_checked pt ((p, _) : Pos.pos') = Ctree.get_obj Ctree.g_tac pt p;
340 (* create a derivation-name, eg. ("refl", _) --> "HOL.refl"*)
341 fun deriv_of_thm'' (thmID, _) =
342 thmID |> Global_Theory.get_thm (ThyC.Isac ()) |> Thm.get_name_hint
344 (* get the formula f at ptp rewritten by the Rewrite_* already applied to f *)
345 fun context_thy (pt, pos as (p,p_)) (tac as Tactic.Rewrite thm'') =
346 let val thm_deriv = deriv_of_thm'' thm''
348 (case Applicable.applicable_in pos pt tac of
349 Applicable.Appl (Tactic.Rewrite' (thy', ord', erls, _, _, f, (res,asm))) =>
351 {thyID = ThyC.theory'2thyID thy',
352 thm = Celem.thm2guh (thy_containing_thm thm_deriv) (Celem.thmID_of_derivation_name thm_deriv),
353 applto = f, applat = Rule.e_term, reword = ord',
354 asms = [](*asms ~~ asms'*), lhs = (Rule.e_term, Rule.e_term)(*(lhs, lhs')*), rhs = (Rule.e_term, Rule.e_term)(*(rhs, rhs')*),
355 result = res, resasms = asm, asmrls = Rule_Set.id_rls erls}
356 | Applicable.Notappl _ =>
358 val pp = Ctree.par_pblobj pt p
359 val thy' = Ctree.get_obj Ctree.g_domID pt pp
361 Pos.Frm => Ctree.get_obj Ctree.g_form pt p
362 | Pos.Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p
363 | _ => error "context_thy: uncovered position"
366 {thyID = ThyC.theory'2thyID thy',
368 Celem.thm2guh (thy_containing_thm thm_deriv) (Celem.thmID_of_derivation_name thm_deriv),
371 | _ => error "context_thy..Rewrite: uncovered case 2")
373 | context_thy (pt, pos as (p, p_)) (tac as Tactic.Rewrite_Inst (subs, (thmID, _))) =
374 let val thm = Global_Theory.get_thm (ThyC.Isac ()) thmID
376 (case Applicable.applicable_in pos pt tac of
377 Applicable.Appl (Tactic.Rewrite_Inst' (thy', ord', erls, _, subst, _, f, (res, asm))) =>
379 val thm_deriv = Thm.get_name_hint thm
380 val thminst = TermC.inst_bdv subst ((Num_Calc.norm o #prop o Thm.rep_thm) thm)
383 {thyID = ThyC.theory'2thyID thy',
385 Celem.thm2guh (thy_containing_thm thm_deriv) (Celem.thmID_of_derivation_name thm_deriv),
386 bdvs = subst, thminst = thminst, applto = f, applat = Rule.e_term, reword = ord',
387 asms = [](*asms ~~ asms'*), lhs = (Rule.e_term, Rule.e_term)(*(lhs, lhs')*), rhs = (Rule.e_term, Rule.e_term)(*(rhs, rhs')*),
388 result = res, resasms = asm, asmrls = Rule_Set.id_rls erls}
390 | Applicable.Notappl _ =>
392 val thm = Global_Theory.get_thm (ThyC.Isac ()(*WN141021 assoc_thy thy' ERROR*)) thmID
393 val thm_deriv = Thm.get_name_hint thm
394 val pp = Ctree.par_pblobj pt p
395 val thy' = Ctree.get_obj Ctree.g_domID pt pp
396 val subst = Selem.subs2subst (Celem.assoc_thy thy') subs
397 val thminst = TermC.inst_bdv subst ((Num_Calc.norm o #prop o Thm.rep_thm) thm)
399 Pos.Frm => Ctree.get_obj Ctree.g_form pt p
400 | Pos.Res => (fst o (Ctree.get_obj Ctree.g_result pt)) p
401 | _ => error "context_thy: uncovered case 3"
404 {thyID = ThyC.theory'2thyID thy',
405 thm_rls = Celem.thm2guh (thy_containing_thm thm_deriv) (Celem.thmID_of_derivation_name thm_deriv),
406 bdvs = subst, thminst = thminst, applto = f}
408 | _ => error "context_thy..Rewrite_Inst: uncovered case 4")
410 | context_thy (pt, p) (tac as Tactic.Rewrite_Set rls') =
411 (case Applicable.applicable_in p pt tac of
412 Applicable.Appl (Tactic.Rewrite_Set' (thy', _, _(*rls*), f, (res,asm))) =>
414 {thyID = ThyC.theory'2thyID thy',
415 rls = Celem.rls2guh (thy_containing_rls thy' rls') rls',
416 applto = f, result = res, asms = asm}
417 | _ => error ("context_thy Rewrite_Set: not for Applicable.Notappl"))
418 | context_thy (pt,p) (tac as Tactic.Rewrite_Set_Inst (_(*subs*), rls')) =
419 (case Applicable.applicable_in p pt tac of
420 Applicable.Appl (Tactic.Rewrite_Set_Inst' (thy', _, subst, _, f, (res,asm))) =>
422 {thyID = ThyC.theory'2thyID thy',
423 rls = Celem.rls2guh (thy_containing_rls thy' rls') rls',
424 bdvs = subst, applto = f, result = res, asms = asm}
425 | _ => error ("context_thy Rewrite_Set_Inst: not for Applicable.Notappl"))
426 | context_thy (_, p) tac =
427 error ("context_thy: not for tac " ^ Tactic.input_to_string tac ^ " at " ^ Pos.pos'2str p)
429 (* get all theorems in a rule set (recursivley containing rule sets) *)
430 fun thm_of_rule Rule.Erule = []
431 | thm_of_rule (thm as Rule.Thm _) = [thm]
432 | thm_of_rule (Rule.Num_Calc _) = []
433 | thm_of_rule (Rule.Cal1 _) = []
434 | thm_of_rule (Rule.Rls_ rls) = thms_of_rls rls
435 and thms_of_rls Rule_Set.Empty = []
436 | thms_of_rls (Rule_Def.Repeat {rules,...}) = (flat o (map thm_of_rule)) rules
437 | thms_of_rls (Rule_Set.Seqence {rules,...}) = (flat o (map thm_of_rule)) rules
438 | thms_of_rls (Rule_Set.Rrls _) = []
440 (* check if a rule is contained in a rule-set (recursivley down in Rls_);
441 this rule can even be a rule-set itself *)
442 fun contains_rule r rls =
444 fun (*find (_, Rls_ rls) = finds (get_rules rls)
445 | find r12 = eq_rule r12
446 and*) finds [] = false
447 | finds (r1 :: rs) = if Rule_Set.eq_rule (r, r1) then true else finds rs
449 finds (Rule_Set.get_rules rls)
452 (* try if a rewrite-rule is applicable to a given formula;
453 in case of rule-sets (recursivley) collect all _atomic_ rewrites *)
454 fun try_rew thy ((_, ro) : Rule_Def.rew_ord) erls (subst : Rule.subst) f (thm' as Rule.Thm (_, thm)) =
455 if Auto_Prog.contains_bdv thm
456 then case Rewrite.rewrite_inst_ thy ro erls false subst thm f of
457 SOME _ => [Tactic.rule2tac thy subst thm']
459 else (case Rewrite.rewrite_ thy ro erls false thm f of
460 SOME _ => [Tactic.rule2tac thy [] thm']
462 | try_rew thy _ _ _ f (cal as Rule.Num_Calc c) =
463 (case Num_Calc.adhoc_thm thy c f of
464 SOME _ => [Tactic.rule2tac thy [] cal]
466 | try_rew thy _ _ _ f (cal as Rule.Cal1 c) =
467 (case Num_Calc.adhoc_thm thy c f of
468 SOME _ => [Tactic.rule2tac thy [] cal]
470 | try_rew thy _ _ subst f (Rule.Rls_ rls) = filter_appl_rews thy subst f rls
471 | try_rew _ _ _ _ _ _ = error "try_rew: uncovered case"
472 and filter_appl_rews thy subst f (Rule_Def.Repeat {rew_ord = ro, erls, rules, ...}) =
473 gen_distinct Tactic.eq_tac (flat (map (try_rew thy ro erls subst f) rules))
474 | filter_appl_rews thy subst f (Rule_Set.Seqence {rew_ord = ro, erls, rules,...}) =
475 gen_distinct Tactic.eq_tac (flat (map (try_rew thy ro erls subst f) rules))
476 | filter_appl_rews _ _ _ (Rule_Set.Rrls _) = []
477 | filter_appl_rews _ _ _ _ = error "filter_appl_rews: uncovered case"
479 (* decide if a tactic is applicable to a given formula;
480 in case of Rewrite_Set* go down to _atomic_ rewrite-tactics *)
481 fun atomic_appl_tacs thy _ _ f (Tactic.Calculate scrID) =
482 try_rew thy Rule.e_rew_ordX Rule_Set.empty [] f (Rule.Num_Calc (assoc_calc' thy scrID |> snd))
483 | atomic_appl_tacs thy ro erls f (Tactic.Rewrite thm'') =
484 try_rew thy (ro, Rule.assoc_rew_ord ro) erls [] f (Rule.Thm thm'')
485 | atomic_appl_tacs thy ro erls f (Tactic.Rewrite_Inst (subs, thm'')) =
486 try_rew thy (ro, Rule.assoc_rew_ord ro) erls (Selem.subs2subst thy subs) f (Rule.Thm thm'')
488 | atomic_appl_tacs thy _ _ f (Tactic.Rewrite_Set rls') =
489 filter_appl_rews thy [] f (assoc_rls rls')
490 | atomic_appl_tacs thy _ _ f (Tactic.Rewrite_Set_Inst (subs, rls')) =
491 filter_appl_rews thy (Selem.subs2subst thy subs) f (assoc_rls rls')
492 | atomic_appl_tacs _ _ _ _ tac =
493 (tracing ("### atomic_appl_tacs: not impl. for tac = '" ^ Tactic.input_to_string tac ^ "'"); []);
495 (* filenames not only for thydata, but also for thy's etc *)
496 fun theID2filename theID = Celem.theID2guh theID ^ ".xml"
500 val guh' = Symbol.explode guh
501 val part = implode (take_fromto 1 4 guh')
502 val isa = implode (take_fromto 5 9 guh')
504 if not (member op = ["exp_", "thy_", "pbl_", "met_"] part)
505 then raise ERROR ("guh '" ^ guh ^ "' does not begin with exp_ | thy_ | pbl_ | met_")
508 val chap = case isa of
509 "isab_" => "Isabelle"
510 | "scri_" => "IsacScripts"
511 | "isac_" => "IsacKnowledge"
513 raise ERROR ("guh2theID: '" ^ guh ^ "' does not have isab_ | scri_ | isac_ at position 5..9")
514 val rest = takerest (9, guh')
515 val thyID = takewhile [] (not o (curry op= "-")) rest
516 val rest' = dropuntil (curry op = "-") rest
517 in case implode rest' of
518 "-part" => [chap] : Celem.theID
519 | "" => [chap, implode thyID]
520 | "-Theorems" => [chap, implode thyID, "Theorems"]
521 | "-Rulesets" => [chap, implode thyID, "Rulesets"]
522 | "-Operations" => [chap, implode thyID, "Operations"]
523 | "-Orders" => [chap, implode thyID, "Orders"]
525 let val sect = implode (take_fromto 1 5 rest')
526 val sect' = case sect of
527 "-thm-" => "Theorems"
528 | "-rls-" => "Rulesets"
529 | "-cal-" => "Operations"
530 | "-ord-" => "Orders"
532 raise ERROR ("guh2theID: '" ^ guh ^ "' has '" ^ sect ^ "' instead -thm- | -rls- | -cal- | -ord-")
534 [chap, implode thyID, sect', implode (takerest (5, rest'))]
539 fun guh2filename guh = guh ^ ".xml";
541 fun guh2rewtac guh [] =
543 val (_, thy, sect, xstr) = case guh2theID guh of
544 [isa, thy, sect, xstr] => (isa, thy, sect, xstr)
545 | _ => error "guh2rewtac: uncovered case"
547 "Theorems" => Tactic.Rewrite (xstr, Rewrite.assoc_thm'' (Celem.assoc_thy thy) xstr)
548 | "Rulesets" => Tactic.Rewrite_Set xstr
549 | _ => error ("guh2rewtac: not impl. for '"^xstr^"'")
551 | guh2rewtac guh subs =
553 val (_, thy, sect, xstr) = case guh2theID guh of
554 [isa, thy, sect, xstr] => (isa, thy, sect, xstr)
555 | _ => error "guh2rewtac: uncovered case"
558 Tactic.Rewrite_Inst (subs, (xstr, Rewrite.assoc_thm'' (Celem.assoc_thy thy) xstr))
559 | "Rulesets" => Tactic.Rewrite_Set_Inst (subs, xstr)
560 | str => error ("guh2rewtac: not impl. for '" ^ str ^ "'")
563 (* the front-end may request a context for any element of the hierarchy *)
564 fun no_thycontext guh = (guh2theID guh; false)
565 handle ERROR _ => true;
567 (* get the substitution of bound variables for matchTheory:
568 # lookup the thm|rls' in the script
569 # take the [(bdv, v_),..] from the respective Rewrite_(Set_)Inst
570 # instantiate this subs with the istates env to [(bdv, x),..]
572 WN060617 hack assuming that all scripts use only one bound variable
573 and use 'v_' as the formal argument for this bound variable*)
574 fun subs_from (Istate.Pstate (pst as {env, ...})) _ guh =
576 val (_, _, thyID, sect, xstr) = case guh2theID guh of
577 theID as [isa, thyID, sect, xstr] => (theID, isa, thyID, sect, xstr)
578 | _ => error "subs_from: uncovered case"
582 let val thm = Global_Theory.get_thm (Celem.assoc_thy (ThyC.thyID2theory' thyID)) xstr
584 if Auto_Prog.contains_bdv thm
587 val formal_arg = TermC.str2term "v_"
588 val value = subst_atomic env formal_arg
589 in ["(''bdv''," ^ Rule.term2str value ^ ")"] : Selem.subs end
594 val rules = (Rule_Set.get_rules o assoc_rls) xstr
596 if Auto_Prog.contain_bdv rules
599 val formal_arg = TermC.str2term "v_"
600 val value = subst_atomic env formal_arg
601 in ["(''bdv''," ^ Rule.term2str value ^ ")"] : Selem.subs end
604 | str => error ("subs_from: uncovered case with " ^ str)
606 | subs_from _ _ guh = error ("subs_from: uncovered case with " ^ guh)
608 (* get a substitution for "bdv*" from the current program and environment.
609 returns a substitution: sube for tac, subst for tac_, i.e. for rewriting *)
610 fun get_bdv_subst prog env =
612 fun scan (Const _) = NONE
613 | scan (Free _) = NONE
614 | scan (Var _) = NONE
615 | scan (Bound _) = NONE
616 | scan (t as Const ("List.list.Cons", _) $ (Const ("Product_Type.Pair", _) $ _ $ _) $ _) =
617 if TermC.is_bdv_subst t then SOME t else NONE
618 | scan (Abs (_, _, body)) = scan body
619 | scan (t1 $ t2) = case scan t1 of NONE => scan t2 | SOME subst => SOME subst
622 NONE => (NONE: Selem.subs option, []: Rule.subst)
624 let val subst = subst_atomic env tm
625 in (SOME (Selem.subst'_to_sube subst), Selem.subst'_to_subst subst) end