neuper@37906: (* elements of calculations. neuper@37906: they are partially held in association lists as ref's for neuper@37906: switching language levels (meta-string, object-values). neuper@37906: in order to keep these ref's during re-evaluation of code, neuper@37906: they are defined here at the beginning of the code. neuper@37906: author: Walther Neuper neuper@37906: (c) isac-team 2003 neuper@37906: neuper@37906: use"calcelems.sml"; neuper@37906: *) neuper@37906: neuper@37906: val linefeed = (curry op^) "\n"; neuper@37906: type authors = string list; neuper@37906: neuper@37906: type cterm' = string; neuper@37906: val empty_cterm' = "empty_cterm'"; neuper@37906: type thmID = string; neuper@37906: type thm' = thmID * cterm';(*WN060610 deprecated in favour of thm''*) neuper@37906: type thm'' = thmID * term; neuper@37906: type rls' = string; neuper@37906: (*.a 'guh'='globally unique handle' is a string unique for each element neuper@37906: of isac's KEStore and persistent over time neuper@37906: (in particular under shifts within the respective hierarchy); neuper@37906: specialty for thys: neuper@37906: # guh NOT resistant agains shifts from one thy to another neuper@37906: (which is the price for Isabelle's design: thy's overwrite ids of subthy's) neuper@37906: # requirement for matchTheory: induce guh from tac + current thy neuper@37906: (see 'fun thy_containing_thm', 'fun thy_containing_rls' etc.) neuper@37906: TODO: introduce to pbl, met.*) neuper@37906: type guh = string; neuper@37906: val e_guh = "e_guh":guh; neuper@37906: neuper@37906: type xml = string; neuper@37906: neuper@37906: (*. eval function calling sml code during rewriting.*) neuper@37906: type eval_fn = (string -> term -> theory -> (string * term) option); neuper@37906: fun e_evalfn (_:'a) (_:term) (_:theory) = NONE:(string * term) option; neuper@37906: (*. op in isa-term 'Const(op,_)' .*) neuper@37906: type calID = string; neuper@37906: type cal = (calID * eval_fn); neuper@37906: (*. fun calculate_ fetches the evaluation-function via this list. *) neuper@37906: type calcID = string; neuper@37906: type calc = (calcID * cal); neuper@37906: neuper@37906: type subs' = (cterm' * cterm') list; (*16.11.00 for FE-KE*) neuper@37906: type subst = (term * term) list; (*here for ets2str*) neuper@37906: val e_subst = []:(term * term) list; neuper@37906: neuper@37906: (*TODO.WN060610 make use of "type rew_ord" total*) neuper@37906: type rew_ord' = string; neuper@37906: val e_rew_ord' = "e_rew_ord" : rew_ord'; neuper@37906: type rew_ord_ = subst -> Term.term * Term.term -> bool; neuper@37906: fun dummy_ord (_:subst) (_:term,_:term) = true; neuper@37906: val e_rew_ord_ = dummy_ord; neuper@37906: type rew_ord = rew_ord' * rew_ord_; neuper@37906: val e_rew_ord = dummy_ord; (* TODO.WN071231 clarify identifiers..e_rew_ordX*) neuper@37906: val e_rew_ordX = (e_rew_ord', e_rew_ord_) : rew_ord; neuper@37906: neuper@37906: neuper@37906: datatype rule = neuper@37906: Erule (*.the empty rule .*) neuper@37906: | Thm of (string * thm)(*.a theorem, ie (identifier, Thm.thm).*) neuper@37906: | Calc of string * (*.sml-code manipulating a (sub)term .*) neuper@37906: (string -> term -> theory -> (string * term) option) neuper@37906: | Cal1 of string * (*.sml-code applied only to whole term neuper@37906: or left/right-hand-side of eqality .*) neuper@37906: (string -> term -> theory -> (string * term) option) neuper@37906: | Rls_ of rls (*.ie. rule sets may be nested.*) neuper@37906: and scr = neuper@37906: EmptyScr neuper@37906: | Script of term (*for met*) neuper@37906: | Rfuns of {init_state : term -> neuper@37906: (term * (*the current formula: neuper@37906: goes locate_gen -> next_tac via istate*) neuper@37906: term * (*the final formula*) neuper@37906: rule list (*of reverse rewrite set (#1#)*) neuper@37906: list * (*may be serveral, eg. in norm_rational*) neuper@37906: (rule * (*Thm (+ Thm generated from Calc) resulting in ...*) neuper@37906: (term * (*... rewrite with ...*) neuper@37906: term list)) (*... assumptions*) neuper@37906: list), (*derivation from given term to normalform neuper@37906: in reverse order with sym_thm; neuper@37906: (#1#) could be extracted from here #1*) neuper@37906: neuper@37906: normal_form: term -> (term * term list) option, neuper@37906: locate_rule: rule list list -> term -> rule neuper@37906: -> (rule * (term * term list)) list, neuper@37906: next_rule : rule list list -> term -> rule option, neuper@37906: attach_form: rule list list -> term -> term neuper@37906: -> (rule * (term * term list)) list} neuper@37906: and rls = neuper@37906: Erls (*for init e_rls*) neuper@37906: neuper@37906: | Rls of (*a confluent and terminating ruleset, in general *) neuper@37906: {id : string, (*for trace_rewrite:=true *) neuper@37906: preconds : term list, (*unused WN020820 *) neuper@37906: (*WN060616 for efficiency... neuper@37906: bdvs : false, (*set in prep_rls for get_bdvs *)*) neuper@37906: rew_ord : rew_ord, (*for rules*) neuper@37906: erls : rls, (*for the conditions in rules *) neuper@37906: srls : rls, (*for evaluation of list_fns in script *) neuper@37906: calc : calc list, (*for Calculate in scr, set by prep_rls *) neuper@37906: rules : rule list, neuper@37906: scr : scr} (*Script term: generating intermed.steps *) neuper@37906: | Seq of (*a sequence of rules to be tried only once *) neuper@37906: {id : string, (*for trace_rewrite:=true *) neuper@37906: preconds : term list, (*unused 20.8.02 *) neuper@37906: (*WN060616 for efficiency... neuper@37906: bdvs : false, (*set in prep_rls for get_bdvs *)*) neuper@37906: rew_ord : rew_ord, (*for rules *) neuper@37906: erls : rls, (*for the conditions in rules *) neuper@37906: srls : rls, (*for evaluation of list_fns in script *) neuper@37906: calc : calc list, (*for Calculate in scr, set by prep_rls *) neuper@37906: rules : rule list, neuper@37906: scr : scr} (*Script term (how to restrict type ???)*) neuper@37906: (*Rrls call SML-code and simulate an rls neuper@37906: difference: there is always _ONE_ redex rewritten in 1 call, neuper@37906: thus wrap Rrls by: Rls (Rls_ ...)*) neuper@37906: neuper@38036: | Rrls of (* for 'reverse rewriting' by SML-functions instead Script *) neuper@38036: {id : string, (* for trace_rewrite := true *) neuper@38036: prepat : (term list *(* preconds, eval with subst from pattern; neuper@38036: if [HOLogic.true_const], match decides alone *) neuper@38036: term ) (* pattern matched with current (sub)term *) neuper@38036: list, (* meta-conjunction is or *) neuper@38036: rew_ord : rew_ord, (* for rules *) neuper@38036: erls : rls, (* for the conditions in rules and preconds *) neuper@38036: calc : calc list, (* for Calculate in scr, set automatic.in prep_rls *) neuper@38036: scr : scr}; (* Rfuns {...} (how to restrict type ???) *) neuper@37906: (*1.8.02 ad (how to restrict type ???): scr should be usable indepentently neuper@37906: from rls, and then contain both Script _AND_ Rfuns !!!*) neuper@37906: neuper@37928: fun thy2ctxt' thy' = ProofContext.init_global (theory thy');(*FIXXXME thy-ctxt*) neuper@37928: fun thy2ctxt thy = ProofContext.init_global thy;(*FIXXXME thy-ctxt*) neuper@37906: neuper@37906: (*ctxt for retrieval of all thms in HOL; FIXME make this local?*) neuper@37924: (*val ctxt_HOL = ProofContext.init_global (theory "Complex_Main");*) neuper@37929: (*val ctxt_HOL = thy2ctxt' "Complex_Main";*) neuper@37906: (*lazy ctxt for retrieval of all thms used in isac; FIXME make this local?*) neuper@37929: (*fun ctxt_Isac _ = thy2ctxt' "Isac";*) neuper@37929: fun Isac _ = ProofContext.theory_of (thy2ctxt' "Isac"); neuper@37906: neuper@37929: val e_rule = neuper@37929: Thm ("refl", ProofContext.get_thm (thy2ctxt' "Complex_Main") "refl" ); neuper@37906: fun id_of_thm (Thm (id, _)) = id neuper@38031: | id_of_thm _ = error "id_of_thm"; neuper@37906: fun thm_of_thm (Thm (_, thm)) = thm neuper@38031: | thm_of_thm _ = error "thm_of_thm"; neuper@37906: fun rep_thm_G' (Thm (thmid, thm)) = (thmid, thm); neuper@37906: fun eq_thmI ((thmid1 : thmID, _ : thm), (thmid2 : thmID, _ : thm)) = neuper@37906: (strip_thy thmid1) = (strip_thy thmid2); neuper@38002: (*version typed weaker WN100910*) neuper@38002: fun eq_thmI' ((thmid1, _), (thmid2, _)) = neuper@38002: (strip_thy thmid1) = (strip_thy thmid2); neuper@37906: neuper@37906: neuper@37906: val string_of_thm = Thm.get_name_hint; (*FIXME.2009*) neuper@37906: (*check for [.] as caused by "fun assoc_thm'"*) neuper@37906: fun string_of_thmI thm = neuper@37906: let val ct' = (de_quote o string_of_thm) thm neuper@37906: val (a, b) = split_nlast (5, explode ct') neuper@37906: in case b of neuper@37906: [" ", " ","[", ".", "]"] => implode a neuper@37906: | _ => ct' neuper@37906: end; neuper@37906: neuper@37906: (*.id requested for all, Rls,Seq,Rrls.*) neuper@37906: fun id_rls Erls = "e_rls" (*WN060714 quick and dirty: recursive defs!*) neuper@37906: | id_rls (Rls {id,...}) = id neuper@37906: | id_rls (Seq {id,...}) = id neuper@37906: | id_rls (Rrls {id,...}) = id; neuper@37906: val rls2str = id_rls; neuper@37906: fun id_rule (Thm (id, _)) = id neuper@37906: | id_rule (Calc (id, _)) = id neuper@37906: | id_rule (Rls_ rls) = id_rls rls; neuper@37906: neuper@37906: fun get_rules (Rls {rules,...}) = rules neuper@37906: | get_rules (Seq {rules,...}) = rules neuper@37906: | get_rules (Rrls _) = []; neuper@37906: neuper@37906: fun rule2str Erule = "Erule" neuper@37906: | rule2str (Thm (str, thm)) = "Thm (\""^str^"\","^(string_of_thmI thm)^")" neuper@37906: | rule2str (Calc (str,f)) = "Calc (\""^str^"\",fn)" neuper@37906: | rule2str (Cal1 (str,f)) = "Cal1 (\""^str^"\",fn)" neuper@37906: | rule2str (Rls_ rls) = "Rls_ (\""^id_rls rls^"\")"; neuper@37906: fun rule2str' Erule = "Erule" neuper@37906: | rule2str' (Thm (str, thm)) = "Thm (\""^str^"\",\"\")" neuper@37906: | rule2str' (Calc (str,f)) = "Calc (\""^str^"\",fn)" neuper@37906: | rule2str' (Cal1 (str,f)) = "Cal1 (\""^str^"\",fn)" neuper@37906: | rule2str' (Rls_ rls) = "Rls_ (\""^id_rls rls^"\")"; neuper@37906: neuper@37906: (*WN080102 compare eq_rule ?!?*) neuper@37906: fun eqrule (Thm (id1,_), Thm (id2,_)) = id1 = id2 neuper@37906: | eqrule (Calc (id1,_), Calc (id2,_)) = id1 = id2 neuper@37906: | eqrule (Cal1 (id1,_), Cal1 (id2,_)) = id1 = id2 neuper@37906: | eqrule (Rls_ _, Rls_ _) = false (*{id=id1}{id=id2} = id1 = id2 FIXXME*) neuper@37906: | eqrule _ = false; neuper@37906: neuper@37906: neuper@37906: type rrlsstate = (*state for reverse rewriting*) neuper@37906: (term * (*the current formula: neuper@37906: goes locate_gen -> next_tac via istate*) neuper@37906: term * (*the final formula*) neuper@37906: rule list (*of reverse rewrite set (#1#)*) neuper@37906: list * (*may be serveral, eg. in norm_rational*) neuper@37906: (rule * (*Thm (+ Thm generated from Calc) resulting in ...*) neuper@37906: (term * (*... rewrite with ...*) neuper@37906: term list)) (*... assumptions*) neuper@37906: list); (*derivation from given term to normalform neuper@37906: in reverse order with sym_thm; neuper@37906: (#1#) could be extracted from here #1*) neuper@37906: val e_type = Type("empty",[]); neuper@37906: val a_type = TFree("'a",[]); neuper@37906: val e_term = Const("empty",e_type); neuper@37906: val a_term = Free("empty",a_type); neuper@37906: val e_rrlsstate = (e_term,e_term,[[e_rule]],[(e_rule,(e_term,[]))]):rrlsstate; neuper@37906: neuper@37906: neuper@37906: neuper@37906: neuper@37906: (*22.2.02: ging auf Linux nicht (Stefan) neuper@37906: val e_scr = Script ((term_of o the o (parse thy)) "e_script");*) neuper@37906: val e_term = Const("empty", Type("'a", [])); neuper@37906: val e_scr = Script e_term; neuper@37906: neuper@37906: neuper@37906: (*ad thm': neuper@37906: there are two kinds of theorems ... neuper@37906: (1) known by isabelle neuper@37906: (2) not known, eg. calc_thm, instantiated rls neuper@37906: the latter have a thmid "#..." neuper@37906: and thus outside isa we ALWAYS transport both (thmid,string_of_thmI) neuper@37906: and have a special assoc_thm / assoc_rls in this interface *) neuper@37906: type theory' = string; (* = domID ^".thy" *) neuper@37906: type domID = string; (* domID ^".thy" = theory' TODO.11.03replace by thyID*) neuper@37906: type thyID = string; (*WN.3.11.03 TODO: replace domID with thyID*) neuper@37906: neuper@37906: fun string_of_thy thy = Context.theory_name thy: theory'; neuper@37906: val theory2domID = string_of_thy; neuper@37906: val theory2thyID = (get_thy o string_of_thy) : theory -> thyID; neuper@37906: val theory2theory' = string_of_thy; neuper@37906: val theory2str = string_of_thy; (*WN050903 ..most consistent naming*) neuper@37906: val theory2str' = implode o (drop_last_n 4) o explode o string_of_thy; neuper@37906: (*> theory2str' Isac.thy; neuper@37906: al it = "Isac" : string neuper@37906: *) neuper@37906: neuper@37906: fun thyID2theory' (thyID:thyID) = neuper@37906: let val ss = explode thyID neuper@37906: val ext = implode (takelast (4, ss)) neuper@37906: in if ext = ".thy" then thyID : theory' (*disarm abuse of thyID*) neuper@37906: else thyID ^ ".thy" neuper@37906: end; neuper@37906: (* thyID2theory' "Isac" (*ok*); neuper@37906: val it = "Isac.thy" : theory' neuper@37906: > thyID2theory' "Isac.thy" (*abuse, goes ok...*); neuper@37906: val it = "Isac.thy" : theory' neuper@37906: *) neuper@37906: neuper@37906: fun theory'2thyID (theory':theory') = neuper@37906: let val ss = explode theory' neuper@37906: val ext = implode (takelast (4, ss)) neuper@37906: in if ext = ".thy" then ((implode o (drop_last_n 4)) ss) : thyID neuper@37906: else theory' (*disarm abuse of theory'*) neuper@37906: end; neuper@37906: (* theory'2thyID "Isac.thy"; neuper@37906: val it = "Isac" : thyID neuper@37906: > theory'2thyID "Isac"; neuper@37906: val it = "Isac" : thyID*) neuper@37906: neuper@37906: neuper@37906: (*. WN0509 discussion: neuper@37906: ############################################################################# neuper@37906: # How to manage theorys in subproblems wrt. the requirement, # neuper@37906: # that scripts should be re-usable ? # neuper@37906: ############################################################################# neuper@37906: neuper@37988: eg. 'Script Solve_rat_equation' calls 'SubProblem (RatEq',..' neuper@37906: which would not allow to 'solve (y'' = -M_b / EI, M_b)' by this script neuper@37906: because Biegelinie.thy is subthy of RatEq.thy and thus Biegelinie.M_b neuper@37906: is unknown in RatEq.thy and M_b cannot be parsed into the scripts guard neuper@37906: (see match_ags). neuper@37906: neuper@37906: Preliminary solution: neuper@38011: # the thy in 'SubProblem (thy', pbl, arglist)' is not taken automatically, neuper@38011: # instead the 'maxthy (rootthy pt) thy' is taken for each subpbl neuper@37906: # however, a thy specified by the user in the rootpbl may lead to neuper@37906: errors in far-off subpbls (which are not yet reported properly !!!) neuper@37906: and interactively specifiying thys in subpbl is not very relevant. neuper@37906: neuper@37906: Other solutions possible: neuper@38011: # always parse and type-check with theory "Isac" neuper@37906: (rejected tue to the vague idea eg. to re-use equations for R in C etc.) neuper@37906: # regard the subthy-relation in specifying thys of subpbls neuper@38011: # specifically handle 'SubProblem (undefined, pbl, arglist)' neuper@37906: # ??? neuper@37906: .*) neuper@37906: (*WN0509 TODO "ProtoPure" ... would be more consistent neuper@37906: with assoc_thy <--> theory2theory' +FIXME assoc_thy "e_domID" -> Script.thy*) neuper@37906: val e_domID = "e_domID":domID; neuper@37906: neuper@37906: (*the key into the hierarchy ob theory elements*) neuper@37906: type theID = string list; neuper@37906: val e_theID = ["e_theID"]; neuper@37906: val theID2str = strs2str; neuper@37906: (*theID eg. is ["IsacKnowledge", "Test", "Rulesets", "ac_plus_times"]*) neuper@37906: fun theID2thyID (theID:theID) = neuper@37906: if length theID >= 3 then (last_elem o (drop_last_n 2)) theID : thyID neuper@38031: else error ("theID2thyID called with "^ theID2str theID); neuper@37906: neuper@37906: (*the key into the hierarchy ob problems*) neuper@37906: type pblID = string list; (* domID::...*) neuper@37906: val e_pblID = ["e_pblID"]:pblID; neuper@37906: val pblID2str = strs2str; neuper@37906: neuper@37906: (*the key into the hierarchy ob methods*) neuper@37906: type metID = string list; neuper@37906: val e_metID = ["e_metID"]:metID; neuper@37906: val metID2str = strs2str; neuper@37906: neuper@37906: (*either theID or pblID or metID*) neuper@37906: type kestoreID = string list; neuper@37906: val e_kestoreID = ["e_kestoreID"]; neuper@37906: val kestoreID2str = strs2str; neuper@37906: neuper@37906: (*for distinction of contexts*) neuper@37906: datatype ketype = Exp_ | Thy_ | Pbl_ | Met_; neuper@37906: fun ketype2str Exp_ = "Exp_" neuper@37906: | ketype2str Thy_ = "Thy_" neuper@37906: | ketype2str Pbl_ = "Pbl_" neuper@37906: | ketype2str Met_ = "Met_"; neuper@37906: fun ketype2str' Exp_ = "Example" neuper@37906: | ketype2str' Thy_ = "Theory" neuper@37906: | ketype2str' Pbl_ = "Problem" neuper@37906: | ketype2str' Met_ = "Method"; neuper@37906: neuper@37906: (*see 'How to manage theorys in subproblems' at 'type thyID'*) neuper@38006: val theory' = Unsynchronized.ref ([]:(theory' * theory) list); neuper@37906: neuper@37906: (*.all theories defined for Scripts, recorded in Scripts/Script.ML; neuper@37906: in order to distinguish them from general IsacKnowledge defined later on.*) neuper@38006: val script_thys = Unsynchronized.ref ([] : (theory' * theory) list); neuper@37906: neuper@37906: neuper@37906: (*rewrite orders, also stored in 'type met' and type 'and rls' neuper@37906: The association list is required for 'rewrite.."rew_ord"..' neuper@37947: WN0509 tests not well-organized: see smltest/Knowledge/termorder.sml*) neuper@38007: val rew_ord' = neuper@38007: Unsynchronized.ref neuper@38007: ([]:(rew_ord' * (*the key for the association list *) neuper@37906: (subst (*the bound variables - they get high order*) neuper@37906: -> (term * term) (*(t1, t2) to be compared *) neuper@37906: -> bool)) (*if t1 <= t2 then true else false *) neuper@37906: list); (*association list *) neuper@37906: rew_ord' := overwritel (!rew_ord', [("e_rew_ord", e_rew_ord), neuper@37906: ("dummy_ord", dummy_ord)]); neuper@37906: neuper@37906: neuper@37906: (*WN060120 a hack to get alltogether run again with minimal effort: neuper@37906: theory' is inserted for creating thy_hierarchy; calls for assoc_rls neuper@37906: need not be called*) neuper@38006: val ruleset' = Unsynchronized.ref ([]:(rls' * (theory' * rls)) list); neuper@37906: neuper@37906: (*FIXME.040207 calclist': used by prep_rls, NOT in met*) neuper@38006: val calclist'= Unsynchronized.ref ([]: calc list); neuper@37906: neuper@37906: (*.the hierarchy of thydata.*) neuper@37906: neuper@37906: (*.'a is for pbt | met.*) neuper@37906: (*WN.24.4.03 -"- ... type parameters; afterwards naming inconsistent*) neuper@37906: datatype 'a ptyp = neuper@37906: Ptyp of string * (*element within pblID*) neuper@37906: 'a list * (*several pbts with different domIDs/thy neuper@37906: TODO: select by subthy (isaref.p.69) neuper@37906: presently only _ONE_ elem*) neuper@37906: ('a ptyp) list; (*the children nodes*) neuper@37906: neuper@37906: (*.datatype for collecting thydata for hierarchy.*) neuper@37906: (*WN060720 more consistent naming would be 'type thyelem' or 'thelem'*) neuper@37906: (*WN0606 Htxt contains html which does not belong to the sml-kernel*) neuper@37906: datatype thydata = Html of {guh: guh, neuper@37906: coursedesign: authors, neuper@37906: mathauthors: authors, neuper@37906: html: string} (*html; for demos before database*) neuper@37906: | Hthm of {guh: guh, neuper@37906: coursedesign: authors, neuper@37906: mathauthors: authors, neuper@38002: thm: term} neuper@37906: | Hrls of {guh: guh, neuper@37906: coursedesign: authors, neuper@37906: mathauthors: authors, neuper@37906: (*like vvvvvvvvvvvvv val ruleset' neuper@37906: WN060711 redesign together !*) neuper@37906: thy_rls: (thyID * rls)} neuper@37906: | Hcal of {guh: guh, neuper@37906: coursedesign: authors, neuper@37906: mathauthors: authors, neuper@37906: calc: calc} neuper@37906: | Hord of {guh: guh, neuper@37906: coursedesign: authors, neuper@37906: mathauthors: authors, neuper@37906: ord: (subst -> (term * term) -> bool)}; neuper@37906: val e_thydata = Html {guh="e_guh", coursedesign=[], mathauthors=[], html=""}; neuper@37906: neuper@37906: type thehier = (thydata ptyp) list; neuper@38006: val thehier = Unsynchronized.ref ([] : thehier); neuper@37906: neuper@37906: (*.an association list, gets the value once in Isac.ML.*) neuper@38006: val isab_thm_thy = Unsynchronized.ref ([] : (thmID * (thyID * term)) list); neuper@37906: neuper@37906: neuper@37906: type path = string; neuper@37906: type filename = string; neuper@37906: neuper@37906: (*val xxx = fn: a b => (a,b); ??? fun-definition ???*) neuper@37906: local neuper@37906: fun ii (_:term) = e_rrlsstate; neuper@37906: fun no (_:term) = SOME (e_term,[e_term]); neuper@37906: fun lo (_:rule list list) (_:term) (_:rule) = [(e_rule,(e_term,[e_term]))]; neuper@37906: fun ne (_:rule list list) (_:term) = SOME e_rule; neuper@37906: fun fo (_:rule list list) (_:term) (_:term) = [(e_rule,(e_term,[e_term]))]; neuper@37906: in neuper@37906: val e_rfuns = Rfuns {init_state=ii,normal_form=no,locate_rule=lo, neuper@37906: next_rule=ne,attach_form=fo}; neuper@37906: end; neuper@37906: neuper@37906: val e_rls = neuper@37906: Rls{id = "e_rls", neuper@37906: preconds = [], neuper@37906: rew_ord = ("dummy_ord", dummy_ord), neuper@37906: erls = Erls,srls = Erls, neuper@37906: calc = [], neuper@37906: rules = [], scr = EmptyScr}:rls; neuper@37906: val e_rrls = Rrls {id = "e_rrls", neuper@37906: prepat = [], neuper@37906: rew_ord = ("dummy_ord", dummy_ord), neuper@37906: erls = Erls, neuper@37906: calc = [], neuper@37906: (*asm_thm=[],*) neuper@37906: scr=e_rfuns}:rls; neuper@37906: ruleset' := overwritel (!ruleset', [("e_rls",("Tools",e_rls)), neuper@37906: ("e_rrls",("Tools",e_rrls)) neuper@37906: ]); neuper@37906: neuper@37906: fun rep_rls (Rls {id,preconds,rew_ord,erls,srls,calc,(*asm_thm,*)rules,scr}) = neuper@37906: {id=id,preconds=preconds,rew_ord=rew_ord,erls=erls,srls=srls,calc=calc, neuper@37906: (*asm_thm=asm_thm,*)rules=rules,scr=scr} neuper@37906: | rep_rls (Seq {id,preconds,rew_ord,erls,srls,calc,(*asm_thm,*)rules,scr}) = neuper@37906: {id=id,preconds=preconds,rew_ord=rew_ord,erls=erls,srls=srls,calc=calc, neuper@37906: (*asm_thm=asm_thm,*)rules=rules,scr=scr} neuper@37906: | rep_rls Erls = rep_rls e_rls neuper@37906: | rep_rls (Rrls {id,...}) = rep_rls e_rls neuper@38031: (*error("rep_rls doesn't take apart reverse-rewrite-rule-sets: "^id)*); neuper@37906: (*| rep_rls (Seq {id,...}) = neuper@38031: error("rep_rls doesn't take apart reverse-rewrite-rule-sets: "^id); neuper@37906: --1.7.03*) neuper@37906: fun rep_rrls neuper@37906: (Rrls {id,(*asm_thm,*) calc, erls, prepat, rew_ord, neuper@37906: scr=Rfuns neuper@37906: {attach_form,init_state,locate_rule, neuper@37906: next_rule,normal_form}}) = neuper@37906: {id=id,(*asm_thm=asm_thm,*) calc=calc, erls=erls, prepat=prepat, neuper@37906: rew_ord=rew_ord, attach_form=attach_form, init_state=init_state, neuper@37906: locate_rule=locate_rule, next_rule=next_rule, normal_form=normal_form} neuper@37906: | rep_rrls (Rls {id,...}) = neuper@38031: error ("rep_rrls doesn't take apart (normal) rule-sets: "^id) neuper@37906: | rep_rrls (Seq {id,...}) = neuper@38031: error ("rep_rrls doesn't take apart (normal) rule-sets: "^id); neuper@37906: neuper@37906: fun append_rls id (Rls {id=_,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: rules =rs,scr=sc}) r = neuper@37906: (Rls{id=id,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: rules = rs @ r,scr=sc}:rls) neuper@37906: | append_rls id (Seq {id=_,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: rules =rs,scr=sc}) r = neuper@37906: (Seq{id=id,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: rules = rs @ r,scr=sc}:rls) neuper@37906: | append_rls id (Rrls _) _ = neuper@38031: error ("append_rls: not for reverse-rewrite-rule-set "^id); neuper@37906: neuper@37906: (*. are _atomic_ rules equal ?.*) neuper@37906: (*WN080102 compare eqrule ?!?*) neuper@37906: fun eq_rule (Thm (thm1,_), Thm (thm2,_)) = thm1 = thm2 neuper@37906: | eq_rule (Calc (id1,_), Calc (id2,_)) = id1 = id2 neuper@37906: | eq_rule (Rls_ rls1, Rls_ rls2) = id_rls rls1 = id_rls rls2 neuper@37906: (*id_rls checks for Rls, Seq, Rrls*) neuper@37906: | eq_rule _ = false; neuper@37906: neuper@37906: fun merge_rls _ Erls rls = rls neuper@37906: | merge_rls _ rls Erls = rls neuper@37906: | merge_rls id neuper@37906: (Rls {id=id1,preconds=pc1,rew_ord=ro1,erls=er1,srls=sr1,calc=ca1, neuper@37906: (*asm_thm=at1,*)rules =rs1,scr=sc1}) neuper@37906: (r2 as Rls {id=id2,preconds=pc2,rew_ord=ro2,erls=er2,srls=sr2,calc=ca2, neuper@37906: (*asm_thm=at2,*)rules =rs2,scr=sc2}) = neuper@37906: (Rls {id=id,preconds=pc1 @ ((#preconds o rep_rls) r2), neuper@37906: rew_ord=ro1,erls=merge_rls "" er1 er2(*er1*), neuper@37906: srls=merge_rls ("merged_"^id1^"_"^((#id o rep_rls) r2)) sr1 neuper@37906: ((#srls o rep_rls) r2), neuper@37906: calc=ca1 @ ((#calc o rep_rls) r2), neuper@37906: (*asm_thm=at1 @ ((#asm_thm o rep_rls) r2),*) neuper@37906: rules = gen_union eq_rule rule2str (rs1, (#rules o rep_rls) r2), neuper@37906: scr=sc1}:rls) neuper@37906: | merge_rls id neuper@37906: (Seq {id=id1,preconds=pc1,rew_ord=ro1,erls=er1,srls=sr1,calc=ca1, neuper@37906: (*asm_thm=at1,*)rules =rs1,scr=sc1}) neuper@37906: (r2 as Seq {id=id2,preconds=pc2,rew_ord=ro2,erls=er2,srls=sr2,calc=ca2, neuper@37906: (*asm_thm=at2,*)rules =rs2,scr=sc2}) = neuper@37906: (Seq {id=id,preconds=pc1 @ ((#preconds o rep_rls) r2), neuper@37906: rew_ord=ro1,erls=merge_rls "" er1 er2(*er1*), neuper@37906: srls=merge_rls ("merged_"^id1^"_"^((#id o rep_rls) r2)) sr1 neuper@37906: ((#srls o rep_rls) r2), neuper@37906: calc=ca1 @ ((#calc o rep_rls) r2), neuper@37906: (*asm_thm=at1 @ ((#asm_thm o rep_rls) r2),*) neuper@37906: rules = gen_union eq_rule rule2str (rs1, (#rules o rep_rls) r2), neuper@37906: scr=sc1}:rls) neuper@37906: | merge_rls _ _ _ = neuper@38031: error "merge_rls: not for reverse-rewrite-rule-sets\ neuper@37906: \and not for mixed Rls -- Seq"; neuper@37906: fun remove_rls id (Rls {id=_,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: (*asm_thm=at,*)rules =rs,scr=sc}) r = neuper@37906: (Rls{id=id,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: (*asm_thm=at,*)rules = gen_rems eq_rule (rs, r), neuper@37906: scr=sc}:rls) neuper@37906: | remove_rls id (Seq {id=_,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: (*asm_thm=at,*)rules =rs,scr=sc}) r = neuper@37906: (Seq{id=id,preconds=pc,rew_ord=ro,erls=er,srls=sr,calc=ca, neuper@37906: (*asm_thm=at,*)rules = gen_rems eq_rule (rs, r), neuper@37906: scr=sc}:rls) neuper@38031: | remove_rls id (Rrls _) _ = error neuper@37906: ("remove_rls: not for reverse-rewrite-rule-set "^id); neuper@37906: neuper@37906: (*!!!> gen_rems (op=) ([1,2,3,4], [3,4,5]); neuper@37906: val it = [1, 2] : int list*) neuper@37906: neuper@37906: (*elder version: migrated 3 calls in smtest to memrls neuper@37906: fun mem_rls id rls = neuper@37906: case find_first ((curry op=) id) (map id_rule ((#rules o rep_rls) rls)) of neuper@37906: SOME _ => true | NONE => false;*) neuper@37906: fun memrls r (Rls {rules,...}) = gen_mem eqrule (r, rules) neuper@37906: | memrls r (Seq {rules,...}) = gen_mem eqrule (r, rules) neuper@38031: | memrls r _ = error ("memrls: incomplete impl. r= "^(rule2str r)); neuper@37906: fun rls_get_thm rls (id: xstring) = neuper@37906: case find_first (curry eq_rule e_rule) neuper@37906: ((#rules o rep_rls) rls) of neuper@37906: SOME thm => SOME thm | NONE => NONE; neuper@37906: neuper@38031: fun assoc' ([], key) = error ("ME_Isa: '"^key^"' not known") neuper@37906: | assoc' ((keyi, xi) :: pairs, key) = neuper@37906: if key = keyi then SOME xi else assoc' (pairs, key); neuper@37906: neuper@37927: (*100818 fun assoc_thy (thy:theory') = ((the o assoc')(!theory',thy)) neuper@38031: handle _ => error ("ME_Isa: thy '"^thy^"' not in system");*) neuper@37928: fun assoc_thy (thy:theory') = (*FIXME100818 abolish*) neuper@38042: (theory thy) handle _ => error ("ME_Isa: thy '" ^ thy ^ "' not in system"); neuper@37928: neuper@37906: (*.associate an rls-identifier with an rls; related to 'fun assoc_rls'; neuper@37906: these are NOT compatible to "fun assoc_thm'" in that they do NOT handle neuper@37906: overlays by re-using an identifier in different thys.*) neuper@37906: fun assoc_rls (rls:rls') = ((#2 o the o assoc')(!ruleset',rls)) neuper@38031: handle _ => error ("ME_Isa: '"^rls^"' not in system"); neuper@37906: (*fun assoc_rls (rls:rls') = ((the o assoc')(!ruleset',rls)) neuper@38031: handle _ => error ("ME_Isa: '"^rls^"' not in system");*) neuper@37906: neuper@37906: (*.overwrite an element in an association list and pair it with a thyID neuper@37906: in order to create the thy_hierarchy; neuper@37906: overwrites existing rls' even if they are defined in a different thy; neuper@37906: this is related to assoc_rls, TODO.WN060120: assoc_rew_ord, assoc_calc;.*) neuper@37906: (*WN060120 ...these are NOT compatible to "fun assoc_thm'" in that neuper@37906: they do NOT handle overlays by re-using an identifier in different thys; neuper@37906: "thyID.rlsID" would be a good solution, if the "." would be possible neuper@37906: in scripts... neuper@37906: actually a hack to get alltogether run again with minimal effort*) neuper@37906: fun insthy thy' (rls', rls) = (rls', (thy', rls)); neuper@37906: fun overwritelthy thy (al, bl:(rls' * rls) list) = neuper@37906: let val bl' = map (insthy ((get_thy o theory2theory') thy)) bl neuper@37906: in overwritel (al, bl') end; neuper@37906: neuper@37906: fun assoc_rew_ord ro = ((the o assoc') (!rew_ord',ro)) neuper@38031: handle _ => error ("ME_Isa: rew_ord '"^ro^"' not in system"); neuper@37906: (*get the string for stac from rule*) neuper@38031: fun assoc_calc ([], key) = error ("assoc_calc: '"^ key ^"' not found") neuper@37906: | assoc_calc ((calc, (keyi, xi)) :: pairs, key) = neuper@37906: if key = keyi then calc else assoc_calc (pairs, key); neuper@37906: (*only used for !calclist'...*) neuper@38031: fun assoc1 ([], key) = error ("assoc1 (for met.calc=): '"^ key neuper@37906: ^"' not found") neuper@37906: | assoc1 ((all as (keyi, _)) :: pairs, key) = neuper@37906: if key = keyi then all else assoc1 (pairs, key); neuper@37906: neuper@37906: (*TODO.WN080102 clarify usage of type cal and type calc..*) neuper@37906: fun calID2calcID (calID : calID) = neuper@38031: let fun ass [] = error ("calID2calcID: "^calID^"not in calclist'") neuper@37906: | ass ((calci, (cali, eval_fn))::ids) = neuper@37906: if calID = cali then calci neuper@37906: else ass ids neuper@37906: in ass (!calclist') : calcID end; neuper@37906: neuper@37906: fun termopt2str (SOME t) = neuper@37929: "SOME " ^ (Syntax.string_of_term (thy2ctxt' "Isac") t) neuper@37906: | termopt2str NONE = "NONE"; neuper@38013: (*fun term2str t = Syntax.string_of_term (thy2ctxt' "Isac") t; Isa2002*) neuper@38013: (*Florian1009: 'val' would ensure static lookup, i.e. only at compile time; neuper@38013: however, dynamic lookup is required, since "Isac" is not yet built here.*) neuper@38013: fun term2str t = Print_Mode.setmp [] (Syntax.string_of_term neuper@38013: (ProofContext.init_global (Thy_Info.get_theory "Isac"))) t; neuper@38022: fun terms2str ts = (strs2str o (map term2str )) ts; neuper@38022: (*terms2str [t1,t2] = "[\"1 + 2\",\"abc\"]";*) neuper@38022: fun terms2str' ts = (strs2str' o (map term2str )) ts; neuper@38022: (*terms2str' [t1,t2] = "[1 + 2,abc]";*) neuper@38022: fun terms2strs ts = (map term2str) ts; neuper@38022: (*terms2strs [t1,t2] = ["1 + 2", "abc"];*) neuper@38013: neuper@38024: fun type2str typ = Syntax.string_of_typ (thy2ctxt' "Isac") typ; neuper@37906: val string_of_typ = type2str; neuper@37906: neuper@37906: fun subst2str (s:subst) = neuper@37906: (strs2str o neuper@37906: (map (linefeed o pair2str o neuper@37906: (apsnd term2str) o neuper@37906: (apfst term2str)))) s; neuper@37906: fun subst2str' (s:subst) = neuper@37906: (strs2str' o neuper@37906: (map (pair2str o neuper@37906: (apsnd term2str) o neuper@37906: (apfst term2str)))) s; neuper@37906: (*> subst2str' [(str2term "bdv", str2term "x"), neuper@37906: (str2term "bdv_2", str2term "y")]; neuper@37906: val it = "[(bdv, x)]" : string neuper@37906: *) neuper@37906: val env2str = subst2str; neuper@37906: neuper@37906: neuper@37906: (*recursive defs:*) neuper@37906: fun scr2str (Script s) = "Script "^(term2str s) neuper@37906: | scr2str (Rfuns _) = "Rfuns"; neuper@37906: neuper@37906: neuper@37906: fun maxthy thy1 thy2 = if Theory.subthy (thy1, thy2) then thy2 else thy1; neuper@37906: neuper@37906: neuper@37906: (*.trace internal steps of isac's rewriter*) neuper@38006: val trace_rewrite = Unsynchronized.ref false; neuper@37906: (*.depth of recursion in traces of the rewriter, if trace_rewrite:=true.*) neuper@38006: val depth = Unsynchronized.ref 99999; neuper@37906: (*.no of rewrites exceeding this int -> NO rewrite.*) neuper@37906: (*WN060829 still unused...*) neuper@38006: val lim_rewrite = Unsynchronized.ref 99999; neuper@37906: (*.no of derivation-elements exceeding this int -> SOME derivation-elements.*) neuper@38006: val lim_deriv = Unsynchronized.ref 100; neuper@37906: (*.switch for checking guhs unique before storing a pbl or met; neuper@37906: set true at startup (done at begin of ROOT.ML) neuper@37906: set false for editing IsacKnowledge (done at end of ROOT.ML).*) neuper@38006: val check_guhs_unique = Unsynchronized.ref false; neuper@37906: neuper@37906: neuper@37906: datatype lrd = (*elements of a path (=loc_) into an Isabelle term*) neuper@37906: L (*go left at $*) neuper@37906: | R (*go right at $*) neuper@37906: | D; (*go down at Abs*) neuper@37906: type loc_ = lrd list; neuper@37906: fun ldr2str L = "L" neuper@37906: | ldr2str R = "R" neuper@37906: | ldr2str D = "D"; neuper@37906: fun loc_2str (k:loc_) = (strs2str' o (map ldr2str)) k; neuper@37906: