src/Tools/isac/Interpret/rewtools.sml
author Walther Neuper <walther.neuper@jku.at>
Wed, 08 Apr 2020 14:24:38 +0200
changeset 59854 c20d08e01ad2
parent 59853 e18f30c44998
child 59857 cbb3fae0381d
permissions -rw-r--r--
separate struct ThyC

note: here is much outdated stuff due to many changes in Isabelle;
there is much to unify, probably all can be dropped now in 2020.
     1 (* 
     2    authors: Walther Neuper 2002, 2006
     3   (c) due to copyright terms
     4 
     5 tools for rewriting, reverse rewriting, context to thy concerning rewriting
     6 *)
     7 
     8 signature REWRITE_TOOLS =
     9 sig
    10   type deriv
    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
    15   datatype contthy
    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}
    26      | EContThy
    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. --------- *)
    49   (*  NONE *)
    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 ----------------------------------------------------------/*)
    56 
    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
    60 end 
    61 (**)
    62 structure Rtools(**): REWRITE_TOOLS(**) =
    63 struct
    64 (**)
    65 
    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'           *
    83  *  (5) FIXME 
    84 .*)
    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               *)
    90   list
    91 
    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
   100 
   101 (* A1==>...==> An ==> (Lhs = Rhs) goes to A1 ==>...==> An ==> (Rhs = Lhs) *)
   102 fun sym_thm thm =
   103   let 
   104     val (deriv,
   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
   112 
   113 (* WN100910 weaker than fun sym_thm for Theory.axioms_of in isa02 *)
   114 fun sym_trm trm =
   115   let
   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))
   120   in trm' end
   121 
   122 (* derive normalform of a rls, or derive until SOME goal,
   123    and record rules applied and rewrites.
   124 val it = fn
   125   : theory
   126     -> rls
   127     -> rule list
   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" ??? 
   131     -> term 
   132     -> (term *       : to this term ...
   133         rule * 	     : ... this rule is applied yielding ...
   134         (term *      : ... this term ...
   135          term list)) : ... under these assumptions.
   136        list          :
   137 returns empty list for a normal form
   138 FIXME.WN040214: treats rules as in Rls, _not_ as in Seq
   139 
   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..
   142  -- replaced below *)
   143 fun make_deriv thy erls rs ro goal tt = 
   144   let 
   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' =
   151         (case goal of 
   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')) =
   155       if lim < 0 
   156       then (tracing ("make_deriv exceeds " ^ int2str (! Celem.lim_deriv) ^ "with deriv =\n");
   157         tracing (deriv2str rts); rts)
   158       else
   159         (case r of
   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'
   164             | SOME (t', a') =>
   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_, _)) => 
   168           let 
   169             val _ = if not (! Celem.trace_rewrite) then () else tracing ("### trying calc. \"" ^ op_^"\"")
   170             val t = TermC.uminus_to_string t
   171           in 
   172             case Num_Calc.adhoc_thm thy c t of
   173               NONE => rew_once lim rts t apno rs'
   174             | SOME (thmid, tm) => 
   175               (let
   176                 val (t', a') = case Rewrite.rewrite_ thy ro erls true tm t of
   177                   SOME ta => ta
   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"
   183           end
   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
   192 
   193 fun sym_drop thmID =
   194   case Symbol.explode thmID of
   195 	  "s" :: "y" :: "m" :: "_" :: id => implode id
   196   | _ => thmID
   197 fun is_sym thmID =
   198   case Symbol.explode thmID of
   199 	  "s" :: "y" :: "m" :: "_" :: _ => true
   200   | _ => false;
   201 
   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}
   214 
   215 (* toggles sym_* and keeps "#:" for ad-hoc calculations *)
   216 fun sym_rule (Rule.Thm (thmID, thm)) =
   217   let
   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)
   226 
   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)
   231 
   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
   238 
   239 fun eq_Thms thmIDs thm = (member op = thmIDs (Celem.id_of_thm thm))
   240   handle ERROR _ => false
   241 
   242 fun thy_containing_thm thmDeriv =
   243   let
   244     val isabthys' = map Context.theory_name (Celem.isabthys ());
   245   in
   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)
   249   end
   250 
   251 (* which theory in ancestors of thy' contains a ruleset *)
   252 fun thy_containing_rls thy' rls' =
   253   let
   254     val thy = ThyC.Thy_Info_get_theory thy'
   255   in
   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' ^ "'")
   259   end
   260 
   261 (* this function cannot work as long as the datastructure does not contain thy' *)
   262 fun thy_containing_cal thy' sop =
   263   let
   264     val thy = ThyC.Thy_Info_get_theory thy'
   265   in
   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' ^ "'")
   269   end
   270 
   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        .*)
   289    	}						 
   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         .*)
   307     }						 
   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                .*)
   314    	}						 
   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                .*)
   322    	}						 
   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                .*)
   327    	}						 
   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                .*)
   334    	}						 
   335 
   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;
   339 
   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
   343 
   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''
   347     in
   348     (case Applicable.applicable_in pos pt tac of
   349       Applicable.Appl (Tactic.Rewrite' (thy', ord', erls, _, _, f, (res,asm))) =>
   350         ContThm
   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 _ =>
   357          let
   358            val pp = Ctree.par_pblobj pt p
   359            val thy' = Ctree.get_obj Ctree.g_domID pt pp
   360            val f = case p_ of
   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"
   364          in
   365            ContNOrew
   366             {thyID   = ThyC.theory'2thyID thy',
   367              thm_rls = 
   368                Celem.thm2guh (thy_containing_thm thm_deriv) (Celem.thmID_of_derivation_name thm_deriv),
   369              applto  = f}
   370 		     end
   371      | _ => error "context_thy..Rewrite: uncovered case 2")
   372     end
   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
   375     in
   376 	  (case Applicable.applicable_in pos pt tac of
   377 	     Applicable.Appl (Tactic.Rewrite_Inst' (thy', ord', erls, _, subst, _, f, (res, asm))) =>
   378 	       let
   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)
   381 	       in
   382 	         ContThmInst
   383 	          {thyID = ThyC.theory'2thyID thy',
   384 	           thm = 
   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}
   389 	       end
   390      | Applicable.Notappl _ =>
   391          let
   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)
   398            val f = case p_ of
   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"
   402          in
   403            ContNOrewInst
   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}
   407          end
   408       | _ => error "context_thy..Rewrite_Inst: uncovered case 4")
   409     end
   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))) =>
   413          ContRls
   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))) =>
   421          ContRlsInst
   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)
   428 
   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 _) = []
   439 
   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 = 
   443   let 
   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
   448   in 
   449     finds (Rule_Set.get_rules rls) 
   450   end
   451 
   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']
   458 	  | NONE => []
   459     else (case Rewrite.rewrite_ thy ro erls false thm f of
   460 	    SOME _ => [Tactic.rule2tac thy [] thm']
   461 	  | NONE => [])
   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]
   465     | NONE => [])
   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]
   469       | NONE => [])
   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"
   478 
   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'')
   487 
   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 ^ "'"); []);
   494 
   495 (* filenames not only for thydata, but also for thy's etc *)
   496 fun theID2filename theID = Celem.theID2guh theID ^ ".xml"
   497 
   498 fun guh2theID guh =
   499   let
   500     val guh' = Symbol.explode guh
   501     val part = implode (take_fromto 1 4 guh')
   502     val isa = implode (take_fromto 5 9 guh')
   503   in
   504     if not (member op = ["exp_", "thy_", "pbl_", "met_"] part)
   505     then raise ERROR ("guh '" ^ guh ^ "' does not begin with exp_ | thy_ | pbl_ | met_")
   506     else
   507       let
   508   	    val chap = case isa of
   509   		  "isab_" => "Isabelle"
   510   		| "scri_" => "IsacScripts"
   511   		| "isac_" => "IsacKnowledge"
   512   		| _ =>
   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"]
   524       | _ => 
   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"
   531 			     | _ =>
   532 			     raise ERROR ("guh2theID: '" ^ guh ^ "' has '" ^ sect ^ "' instead -thm- | -rls- | -cal- | -ord-")
   533 		    in
   534 		      [chap, implode thyID, sect', implode (takerest (5, rest'))]
   535 		    end
   536 	    end	
   537     end
   538 
   539 fun guh2filename guh = guh ^ ".xml";
   540 
   541 fun guh2rewtac guh [] =
   542     let
   543       val (_, thy, sect, xstr) = case guh2theID guh of
   544         [isa, thy, sect, xstr] => (isa, thy, sect, xstr)
   545       | _ => error "guh2rewtac: uncovered case"
   546     in case sect of
   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^"'") 
   550     end
   551   | guh2rewtac guh subs =
   552     let
   553       val (_, thy, sect, xstr) = case guh2theID guh of
   554         [isa, thy, sect, xstr] => (isa, thy, sect, xstr)
   555       | _ => error "guh2rewtac: uncovered case"
   556     in case sect of
   557       "Theorems" => 
   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 ^ "'") 
   561     end
   562 
   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;
   566 
   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),..]
   571    # otherwise []
   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 =
   575     let
   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"
   579     in
   580       case sect of
   581         "Theorems" => 
   582           let val thm = Global_Theory.get_thm (Celem.assoc_thy (ThyC.thyID2theory' thyID)) xstr
   583           in
   584             if Auto_Prog.contains_bdv thm
   585             then
   586               let
   587                 val formal_arg = TermC.str2term "v_"      
   588                 val value = subst_atomic env formal_arg
   589               in ["(''bdv''," ^ Rule.term2str value ^ ")"] : Selem.subs end
   590             else []
   591 	        end
   592   	  | "Rulesets" => 
   593         let
   594           val rules = (Rule_Set.get_rules o assoc_rls) xstr
   595         in
   596           if Auto_Prog.contain_bdv rules
   597           then
   598             let
   599               val formal_arg = TermC.str2term "v_"
   600               val value = subst_atomic env formal_arg
   601             in ["(''bdv''," ^ Rule.term2str value ^ ")"] : Selem.subs end
   602           else []
   603         end
   604       | str => error ("subs_from: uncovered case with " ^ str)
   605     end
   606   | subs_from _ _  guh = error ("subs_from: uncovered case with " ^ guh)
   607 
   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 =
   611   let
   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
   620   in
   621     case scan prog of
   622       NONE => (NONE: Selem.subs option, []: Rule.subst)
   623     | SOME tm =>
   624         let val subst = subst_atomic env tm
   625         in (SOME (Selem.subst'_to_sube subst), Selem.subst'_to_subst subst) end
   626   end
   627 
   628 end