src/Tools/isac/Interpret/rewtools.sml
author Walther Neuper <neuper@ist.tugraz.at>
Thu, 31 Jul 2014 14:32:05 +0200
changeset 55487 06883b595617
parent 55485 b10eb9fd4c02
child 55497 48b672239de9
permissions -rw-r--r--
collected updates since changeset 066b35da6c97
     1 (* tools for rewriting, reverse rewriting, context to thy concerning rewriting
     2    authors: Walther Neuper 2002, 2006
     3   (c) due to copyright terms
     4 
     5 use"ME/rewtools.sml";
     6 use"rewtools.sml";
     7 *)
     8 
     9 
    10 
    11 (***.reverse rewriting.***)
    12 
    13 (*.derivation for insertin one level of nodes into the calctree.*)
    14 type deriv  = (term * rule * (term *term list)) list;
    15 
    16 fun trta2str (t,r,(t',a)) = "\n("^(term2str t)^", "^(rule2str' r)^", ("^
    17 			    (term2str t')^", "^(terms2str a)^"))";
    18 fun trtas2str trtas = (strs2str o (map trta2str)) trtas;
    19 val deriv2str = trtas2str;
    20 fun rta2str (r,(t,a)) = "\n("^(rule2str' r)^", ("^
    21 			    (term2str t)^", "^(terms2str a)^"))";
    22 fun rtas2str rtas = (strs2str o (map rta2str)) rtas;
    23 val deri2str = rtas2str;
    24 
    25 
    26 (* A1==>...==>An==>(Lhs = Rhs) goes to A1==>...==>An==>(Rhs = Lhs) 
    27   WN120320: reconsider the desing including the java front-end with html representation;
    28   see tests 
    29   --- OLD compute rlsthmsNOTisac by eq_thmID ---
    30   --- compute val rlsthmsNOTisac ---
    31 *)
    32 fun sym_thm thm =
    33     let 
    34         val (deriv, {thy = thy, tags = tags, maxidx = maxidx, 
    35                      shyps = shyps, hyps = hyps, tpairs = tpairs, 
    36                      prop = prop}) = 
    37 	    rep_thm_G thm;
    38         val (lhs,rhs) = (dest_equals' o strip_trueprop 
    39 		         o Logic.strip_imp_concl) prop;
    40         val prop' = case strip_imp_prems' prop of
    41 		        NONE => Trueprop $ (mk_equality (rhs, lhs))
    42 		      | SOME cs => 
    43 		        ins_concl cs (Trueprop $ (mk_equality (rhs, lhs)));
    44     in assbl_thm deriv thy tags maxidx shyps hyps tpairs prop' end;
    45 (*
    46   (sym RS real_mult_div_cancel1) handle e => print_exn e;
    47 Exception THM 1 raised:
    48 RSN: no unifiers
    49 "?s = ?t ==> ?t = ?s"
    50 "?k ~= 0 ==> ?k * ?m / (?k * ?n) = ?m / ?n"
    51 
    52   val thm = real_mult_div_cancel1;
    53   val prop = (#prop o rep_thm) thm;
    54   atomt prop;
    55   val ppp = Logic.strip_imp_concl prop;
    56   atomt ppp;
    57   ((#prop o rep_thm o sym_thm o sym_thm) thm) = (#prop o rep_thm) thm;
    58 val it = true : bool
    59   ((sym_thm o sym_thm) thm) = thm;
    60 val it = true : bool
    61 
    62   val thm = real_le_anti_sym;
    63   ((sym_thm o sym_thm) thm) = thm;
    64 val it = true : bool
    65 
    66   val thm = real_minus_zero;
    67   ((sym_thm o sym_thm) thm) = thm;
    68 val it = true : bool
    69 *)
    70 (*WN100910 weaker than fun sym_thm for Theory.axioms_of in isa02*)
    71 fun sym_trm trm =
    72     let val (lhs,rhs) = (dest_equals' o strip_trueprop
    73 		         o Logic.strip_imp_concl) trm;
    74         val trm' = case strip_imp_prems' trm of
    75 		        NONE => mk_equality (rhs, lhs)
    76 		      | SOME cs => 
    77 		        ins_concl cs (mk_equality (rhs, lhs));
    78     in trm' end;
    79 (*ML {*
    80 val trm = @{term "k ~= 0 ==> k * m / (k * n) = m / n"};
    81 (tracing o 
    82  (term_to_string')) (sym_trm trm);
    83 "~ k = (0::'a) ==> m / n = k * m / (k * n)"
    84 *}*)
    85 
    86 
    87 
    88 (* derive normalform of a rls, or derive until SOME goal,
    89    and record rules applied and rewrites.
    90 val it = fn
    91   : theory
    92     -> rls
    93     -> rule list
    94     -> rew_ord       : the order of this rls, which 1 theorem of is used 
    95                        for rewriting 1 single step (?14.4.03)
    96     -> term option   : 040214 ??? use for "derive until SOME goal" ??? 
    97     -> term 
    98     -> (term *       : to this term ...
    99         rule * 	     : ... this rule is applied yielding ...
   100         (term *      : ... this term ...
   101          term list)) : ... under these assumptions.
   102        list          :
   103 returns empty list for a normal form
   104 FIXME.WN040214: treats rules as in Rls, _not_ as in Seq
   105 
   106 WN060825 too complicated for the intended use by cancel_, common_nominator_
   107 and unreflectedly adapted to extension of rules by Rls_: returns Rls_("sym_simpl..
   108  -- replaced below *)
   109 fun make_deriv thy erls (rs:rule list) ro(*rew_ord*) goal tt = 
   110   let 
   111     datatype switch = Appl | Noap
   112     fun rew_once lim rts t Noap [] = 
   113         (case goal of NONE => rts | SOME g => error ("make_deriv: no derivation for " ^ term2str t))
   114       | rew_once lim rts t Appl [] = rew_once lim rts t Noap rs
   115         (*| Seq _ => rts) FIXXXXXME 14.3.03*)
   116       | rew_once lim rts t apno rs' =
   117         (case goal of 
   118           NONE => rew_or_calc lim rts t apno rs'
   119         | SOME g => if g = t then rts else rew_or_calc lim rts t apno rs')
   120     and rew_or_calc lim rts t apno (rrs' as (r :: rs')) =
   121       if lim < 0 
   122       then (tracing ("make_deriv exceeds " ^ int2str (! lim_deriv) ^
   123         "with deriv =\n"); tracing (deriv2str rts); rts)
   124       else
   125         case r of
   126           Thm (thmid, tm) => 
   127             (if not (! trace_rewrite) then () else tracing ("### trying thm \"" ^ thmid ^ "\"");
   128             case rewrite_ thy ro erls true tm t of
   129               NONE => rew_once lim rts t apno rs'
   130             | SOME (t', a') =>
   131               (if ! trace_rewrite then tracing ("### rewrites to: " ^ term2str t') else ();
   132               rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs'))
   133         | Calc (c as (op_,_)) => 
   134           let 
   135             val _ = if not (! trace_rewrite) then () else tracing ("### trying calc. \"" ^ op_^"\"")
   136             val t = uminus_to_string t
   137           in 
   138             case get_calculation_ thy c t of
   139               NONE => rew_once lim rts t apno rs'
   140             | SOME (thmid, tm) => 
   141               (let
   142                 val SOME (t', a') = rewrite_ thy ro erls true tm t
   143                 val _ = if not (! trace_rewrite) then () else tracing("### calc. to: " ^term2str t')
   144                 val r' = Thm (thmid, tm)
   145               in rew_once (lim - 1) (rts @ [(t, r', (t', a'))]) t' Appl rrs' end) 
   146                 handle _ => error "derive_norm, Calc: no rewrite"
   147           end
   148       (*| Cal1 (cc as (op_,_)) => ... WN080222 see rewrite__set_: see 7df94616c1bd and earlier*)
   149         | Rls_ rls =>           (* WN060829: CREATES "sym_rlsID", see 7df94616c1bd and earlier*)
   150           (case rewrite_set_ thy true rls t of
   151              NONE => rew_once lim rts t apno rs'
   152            | SOME (t', a') => rew_once (lim - 1) (rts @ [(t, r, (t', a'))]) t' Appl rrs');           
   153   in rew_once (! lim_deriv) [] tt Noap rs end;
   154 
   155 fun sym_drop (thmID : thmID) =
   156     case Symbol.explode thmID of
   157 	"s"::"y"::"m"::"_"::id => implode id : thmID
   158       | id => thmID;
   159 fun is_sym (thmID : thmID) =
   160     case Symbol.explode thmID of
   161 	"s"::"y"::"m"::"_"::id => true
   162       | id => false;
   163 
   164 (*FIXXXXME.040219: detail has to handle Rls id="sym_..." 
   165   by applying make_deriv, rev_deriv'; see concat_deriv*)
   166 fun sym_rls Erls = Erls
   167   | sym_rls (Rls {id, scr, calc, errpatts, erls, srls, rules, rew_ord, preconds}) =
   168     Rls {id="sym_"^id, scr=scr, calc=calc, errpatts=errpatts, erls=erls, srls=srls, 
   169 	 rules=rules, rew_ord=rew_ord, preconds=preconds}
   170   | sym_rls (Seq {id, scr, calc, errpatts, erls, srls, rules, rew_ord, preconds}) =
   171     Seq {id="sym_"^id, scr=scr, calc=calc, errpatts=errpatts,  erls=erls, srls=srls, 
   172 	 rules=rules, rew_ord=rew_ord, preconds=preconds}
   173   | sym_rls (Rrls {id, scr, calc, errpatts, erls, prepat, rew_ord}) = 
   174     Rrls {id="sym_"^id, scr=scr, calc=calc,  errpatts=errpatts, erls=erls, prepat=prepat, 
   175 	  rew_ord=rew_ord};
   176 
   177 (* toggles sym_* and keeps "#:" for ad-hoc calculations *)
   178 fun sym_rule (Thm (thmID, thm)) =
   179     let
   180       val thm' = sym_thm thm
   181       val thmID' = case Symbol.explode thmID of
   182         "s"::"y"::"m"::"_"::id => implode id
   183       |  "#"::":":: _ => "#: " ^ string_of_thmI thm'
   184       | _ => "sym_" ^ thmID
   185     in Thm (thmID', thm') end
   186   | sym_rule (Rls_ rls) = Rls_ (sym_rls rls) (* TODO? handle with interSteps ? *)
   187   | sym_rule r = error ("sym_rule: not for " ^ (rule2str r));
   188 (*
   189   val th =  Thm ("real_one_collect",num_str @{thm real_one_collect});
   190   sym_rule th;
   191 val th =
   192   Thm ("real_one_collect","?m is_const ==> ?n + ?m * ?n = (1 + ?m) * ?n")
   193   : rule
   194 ML> val it =
   195   Thm ("sym_real_one_collect","?m is_const ==> (1 + ?m) * ?n = ?n + ?m * ?n")*)
   196 
   197 
   198 (*version for reverse rewrite used before 040214*)
   199 fun rev_deriv (t, r, (t', a)) = (sym_rule r, (t, a));
   200 (* val (thy, erls, rs, ro, goal, t) = (thy, eval_rls, rules, ro, NONE, t');
   201    *)
   202 fun reverse_deriv thy erls (rs:rule list) ro(*rew_ord*) goal t =
   203     (rev o (map rev_deriv)) (make_deriv thy erls (rs:rule list) ro goal t);
   204 (*
   205   val rev_rew = reverse_deriv thy e_rls ; 
   206   tracing(rtas2str rev_rew);
   207 *)
   208 
   209 fun eq_Thm (Thm (id1,_), Thm (id2,_)) = id1 = id2
   210   | eq_Thm (Thm (id1,_), _) = false
   211   | eq_Thm (Rls_ r1, Rls_ r2) = id_rls r1 = id_rls r2
   212   | eq_Thm (Rls_ r1, _) = false
   213   | eq_Thm (r1, r2) = error ("eq_Thm: called with '"^
   214 				(rule2str r1)^"' '"^(rule2str r2)^"'");
   215 fun distinct_Thm r = gen_distinct eq_Thm r;
   216 
   217 fun eq_Thms thmIDs thm = (member op = thmIDs (id_of_thm thm))
   218     handle _ => false;
   219 
   220 
   221 (***. context to thy concerning rewriting .***)
   222 
   223 (*.create the unique handles and filenames for the theory-data.*)
   224 fun part2filename str = part2guh str ^ ".xml" : filename;
   225 fun thy2filename thy' = thy2guh thy' ^ ".xml" : filename;
   226 fun thypart2filename thy' = thypart2guh thy' ^ ".xml" : filename;
   227 
   228 fun thm2filename (isa_thyID: string * thyID) thmID =
   229     (thm2guh isa_thyID thmID) ^ ".xml" : filename;
   230 fun rls2filename (isa, thyID) rls' =
   231     rls2guh (isa, thyID) rls' ^ ".xml" : filename;
   232 fun cal2filename (isa, thyID:thyID) calID = 
   233     cal2guh (isa, thyID:thyID) calID ^ ".xml" : filename;
   234 fun ord2filename (isa, thyID:thyID) (rew_ord':rew_ord') =
   235     ord2guh (isa, thyID:thyID) (rew_ord':rew_ord') ^ ".xml" : filename;
   236 
   237 (**.set up isab_thm_thy in Isac.ML.**)
   238 
   239 fun rearrange (thyID, (thmID, thm)) = (thmID, (thyID, prop_of thm));
   240 (* WN120320: reconsider design since thmID and thyID can be retrieved from thm: *)
   241 fun rearrange' (thmID, thm) =
   242   (thmID_of_derivation_name thmID,
   243     (thyID_of_derivation_name thmID, prop_of thm)): (thmID * (thyID * term));
   244 fun rearrange_inv (thmID, (thyID, term)) = (thyID, (thmID, term));
   245 
   246 (*================= version before Isbelle2002 --> 2011 ===========================
   247 (*.lookup the missing theorems in some thy (of Isabelle).*)
   248 fun make_isa missthms thy =
   249     map (pair (theory2thyID thy)) 
   250 	((inter eq_thmI) missthms [] (*Global_Theory.all_thms_of thy WN11xxxx: THIS IS TOO EXPENSIVE*)) 
   251 	: (thyID * (thmID * Thm.thm)) list;
   252 
   253 (*.separate handling of sym_thms.*)
   254 fun make_isab rlsthmsNOTisac isab_thys = 
   255     let fun les ((s1,_), (s2,_)) = (s1 : string) < s2
   256 	val notsym = filter_out (is_sym o #1) rlsthmsNOTisac
   257 	val notsym_isab = (flat o (map (make_isa notsym))) isab_thys
   258 			  
   259 	val sym = filter (is_sym o #1) rlsthmsNOTisac
   260 		  
   261 	val symsym = map ((apfst sym_drop) o (apsnd sym_thm)) sym
   262 	val symsym_isab = (flat o (map (make_isa symsym))) isab_thys
   263 			  
   264 	val sym_isab = map (((apsnd o apfst) sym_drop) o 
   265 			    ((apsnd o apsnd) sym_thm)) symsym_isab
   266 		       
   267 	val isab = notsym_isab @ symsym_isab @ sym_isab
   268     in ((map rearrange) o (gen_sort les)) isab : (thmID * (thyID * term)) list
   269     end;
   270 ================= version before Isbelle2002 --> 2011 ===========================*)
   271 
   272 (*================= trials while Isbelle2002 --> 2011 ===========================
   273   WN120320 update Isabelle2002 --> 2011 gave up with expensiveness of Global_Theory.all_thms_of;
   274   the code below is outcommented too due to problems with sym_*:
   275 
   276   version with term instead of thm, for Theory.axioms_of in isa02
   277 fun make_isa missthms thy =
   278     map (pair (theory2thyID thy)) 
   279 	((inter eq_thmI') missthms (Theory.axioms_of thy))
   280 	: (thyID * (thmID * term)) list;
   281 (* separate handling of sym_thms *)
   282 fun make_isab rlsthmsNOTisac isab_thys = 
   283     let fun les ((s1,_), (s2,_)) = (s1 : string) < s2
   284 	val notsym = filter_out (is_sym o #1) rlsthmsNOTisac
   285 	val notsym_isab = (flat o (map (make_isa notsym))) isab_thys
   286 			  
   287 	val sym = filter (is_sym o #1) rlsthmsNOTisac
   288 		  
   289 	val symsym = map ((apfst sym_drop) o (apsnd sym_trm)) sym
   290 	val symsym_isab = (flat o (map (make_isa symsym))) isab_thys
   291 			  
   292 	val sym_isab = map (((apsnd o apfst) sym_drop) o 
   293 			    ((apsnd o apsnd) sym_trm)) symsym_isab
   294 		       
   295 	val isab = notsym_isab @ symsym_isab @ sym_isab
   296     in ((map rearrange) o (gen_sort les)) isab 
   297        : (thmID * (thyID * term)) list
   298     end;
   299 ================= trials while Isbelle2002 --> 2011 ===========================*)
   300 
   301 (*================= cheap version without sym_* thms ===========================*)
   302 fun make_isab rlsthmsNOTisac = map rearrange' rlsthmsNOTisac;
   303 
   304 fun thy_containing_thm thmDeriv =
   305   let
   306     val isabthys' = map Context.theory_name (isabthys ());
   307   in
   308     if member op= isabthys' (thyID_of_derivation_name thmDeriv)
   309     then ("Isabelle", thmID_of_derivation_name thmDeriv)
   310     else ("IsacKnowledge", thyID_of_derivation_name thmDeriv)
   311   end;
   312 
   313 (* which theory in ancestors of thy' contains a ruleset *)
   314 fun thy_containing_rls (thy' : theory') (rls' : rls') =
   315   let
   316     val thy = Thy_Info.get_theory thy'
   317   in
   318     case AList.lookup op= (KEStore_Elems.get_rlss thy) rls' of
   319       SOME (thy'', _) => (partID' thy'', thy'')
   320     | _ => error ("thy_containing_rls : rls '" ^ rls' ^ "' not in ancestors of thy '" ^ thy' ^ "'")
   321   end
   322 
   323 (* this function cannot work as long as the datastructure does not contain thy' *)
   324 fun thy_containing_cal (thy' : theory') (sop : prog_calcID) =
   325   let
   326     val thy = Thy_Info.get_theory thy'
   327   in
   328     case AList.lookup op= (KEStore_Elems.get_calcs thy) sop of
   329       SOME (_(*"Groups.plus_class.plus"*), _) => ("IsacKnowledge", "Atools" (*FIXME*))
   330     | _ => error ("thy_containing_cal : rls '" ^ sop ^ "' not in ancestors of thy '" ^ thy' ^ "'")
   331   end
   332 
   333 (*.packing return-values to matchTheory, contextToThy for xml-generation.*)
   334 datatype contthy =  (*also an item from KEStore on Browser ......#*)
   335 	 EContThy   (*not from KEStore ...........................*)
   336        | ContThm of (*a theorem in contex =============*)
   337 	 {thyID   : thyID,         (*for *2guh in sub-elems here .*)
   338 	  thm     : guh,           (*theorem in the context      .*)
   339 	  applto  : term,	   (*applied to formula ...      .*)
   340 	  applat  : term,	   (*...  with lhs inserted      .*)
   341 	  reword  : rew_ord',      (*order used for rewrite      .*)
   342 	  asms    : (term          (*asumption instantiated      .*)
   343 		     * term) list, (*asumption evaluated         .*)
   344 	  lhs     : term           (*lhs of the theorem ...      #*)
   345 		    * term,        (*... instantiated            .*)
   346 	  rhs     : term           (*rhs of the theorem ...      #*)
   347 		    * term,        (*... instantiated            .*)
   348 	  result  : term,	   (*resulting from the rewrite  .*)
   349 	  resasms : term list,     (*... with asms stored        .*)
   350 	  asmrls  : rls'           (*ruleset for evaluating asms .*)
   351 		    }						 
   352 	| ContThmInst of (*a theorem with bdvs in contex ======== *)
   353 	 {thyID   : thyID,         (*for *2guh in sub-elems here .*)
   354 	  thm     : guh,           (*theorem in the context      .*)
   355 	  bdvs    : subst,         (*bound variables to modify....*)
   356 	  thminst : term,          (*... theorem instantiated    .*)
   357 	  applto  : term,	   (*applied to formula ...      .*)
   358 	  applat  : term,	   (*...  with lhs inserted      .*)
   359 	  reword  : rew_ord',      (*order used for rewrite      .*)
   360 	  asms    : (term          (*asumption instantiated      .*)
   361 		     * term) list, (*asumption evaluated         .*)
   362 	  lhs     : term           (*lhs of the theorem ...      #*)
   363 		    * term,        (*... instantiated            .*)
   364 	  rhs     : term           (*rhs of the theorem ...      #*)
   365 		    * term,        (*... instantiated            .*)
   366 	  result  : term,	   (*resulting from the rewrite  .*)
   367 	  resasms : term list,     (*... with asms stored        .*)
   368 	  asmrls  : rls'           (*ruleset for evaluating asms .*)
   369 		      }						 
   370 	| ContRls of (*a rule set in contex ===================== *)
   371 	 {thyID   : thyID,         (*for *2guh in sub-elems here .*)
   372 	  rls     : guh,           (*rule set in the context     .*)
   373 	  applto  : term,	   (*rewrite this formula        .*)
   374 	  result  : term,	   (*resulting from the rewrite  .*)
   375 	  asms    : term list      (*... with asms stored        .*)
   376 		    }						 
   377 	| ContRlsInst of (*a rule set with bdvs in contex ======= *)
   378 	 {thyID   : thyID,         (*for *2guh in sub-elems here .*)
   379 	  rls     : guh,           (*rule set in the context     .*)
   380 	  bdvs    : subst,         (*for bound variables in thms .*)
   381 	  applto  : term,	   (*rewrite this formula        .*)
   382 	  result  : term,	   (*resulting from the rewrite  .*)
   383 	  asms    : term list      (*... with asms stored        .*)
   384 		    }
   385 	| ContNOrew of (*no rewrite for thm or rls ============== *)
   386 	 {thyID   : thyID,         (*for *2guh in sub-elems here .*)
   387 	  thm_rls : guh,           (*thm or rls in the context   .*)
   388 	  applto  : term	   (*rewrite this formula        .*)
   389 		    }						 
   390 	| ContNOrewInst of (*no rewrite for some instantiation == *)
   391 	 {thyID   : thyID,         (*for *2guh in sub-elems here .*)
   392 	  thm_rls : guh,           (*thm or rls in the context   .*)
   393 	  bdvs    : subst,         (*for bound variables in thms .*)
   394 	  thminst : term,          (*... theorem instantiated    .*)
   395 	  applto  : term	   (*rewrite this formula        .*)
   396 		    };
   397 
   398 (*.check a rewrite-tac for bdv (RL always used *_Inst !) TODO.WN060718
   399    pass other tacs unchanged.*)
   400 fun get_tac_checked pt ((p,p_) : pos') = get_obj g_tac pt p;
   401 
   402 (*..*)
   403 
   404 
   405 
   406 (*.get the formula f at ptp rewritten by the Rewrite_* already applied to f.*)
   407 (* val (Rewrite' (thy', ord', erls, _, (thmID,_), f, (res,asm))) = tac';
   408    *)
   409 fun context_thy (pt, pos as (p,p_)) (tac as Rewrite (thmID,_)) =
   410       (case applicable_in pos pt tac of
   411         Appl (Rewrite' (thy', ord', erls, _, (thmID,_), f, (res,asm))) =>
   412           let 
   413             val thmDeriv = "WN120320: AT Isa2009-2-->11 BROKEN"
   414             val thy = assoc_thy thy'
   415             val thm = (norm o #prop o rep_thm o (Global_Theory.get_thm thy)) thmID
   416           in
   417             ContThm
   418              {thyID   = theory'2thyID thy',
   419               thm     =
   420                 thm2guh (thy_containing_thm thmDeriv) (thmID_of_derivation_name thmDeriv),
   421               applto  = f,
   422               applat  = e_term,
   423               reword  = ord',
   424               asms    = [](*asms ~~ asms'*),
   425               lhs     = (e_term, e_term)(*(lhs, lhs')*),
   426               rhs     = (e_term, e_term)(*(rhs, rhs')*),
   427               result  = res,
   428               resasms = asm,
   429               asmrls  = id_rls erls}
   430 		       end
   431        | Notappl _ =>
   432            let
   433              val thmDeriv = "WN120320: AT Isa2009-2-->11 BROKEN"
   434              val pp = par_pblobj pt p
   435              val thy' = get_obj g_domID pt pp
   436              val f = case p_ of
   437                    Frm => get_obj g_form pt p
   438                  | Res => (fst o (get_obj g_result pt)) p
   439            in
   440              ContNOrew
   441               {thyID   = theory'2thyID thy',
   442                thm_rls = thm2guh (thy_containing_thm thmDeriv) (thmID_of_derivation_name thmDeriv),
   443                applto  = f}
   444 		       end)
   445     
   446   | context_thy (pt, pos as (p,p_)) (tac as Rewrite_Inst (subs, (thmID,_))) =
   447 	    (case applicable_in pos pt tac of
   448 	       Appl (Rewrite_Inst' (thy', ord', erls, _, subst, (thmID,_), f, (res, asm))) =>
   449 	         let
   450              val thmDeriv = "WN120320: get this from a reference variable ?!?"
   451 	           val thm = (norm o #prop o rep_thm o (Global_Theory.get_thm (assoc_thy thy'))) thmID
   452 	           val thminst = inst_bdv subst thm
   453 	         in
   454 	           ContThmInst
   455 	            {thyID   = theory'2thyID thy',
   456 	             thm     = thm2guh (thy_containing_thm thmDeriv) (thmID_of_derivation_name thmDeriv),
   457 	             bdvs    = subst,
   458 	             thminst = thminst,
   459 	             applto  = f,
   460 	             applat  = e_term,
   461 	             reword  = ord',
   462 	             asms    = [](*asms ~~ asms'*),
   463 	             lhs     = (e_term, e_term)(*(lhs, lhs')*),
   464 	             rhs     = (e_term, e_term)(*(rhs, rhs')*),
   465 	             result  = res,
   466 	             resasms = asm,
   467 	             asmrls  = id_rls erls}
   468 	         end
   469        | Notappl _ =>
   470            let
   471              val thmDeriv = "WN120320: get this from a reference variable ?!?"
   472              val pp = par_pblobj pt p
   473              val thy' = get_obj g_domID pt pp
   474              val subst = subs2subst (assoc_thy thy') subs
   475              val thm = (norm o #prop o rep_thm o (Global_Theory.get_thm (assoc_thy thy'))) thmID
   476              val thminst = inst_bdv subst thm
   477              val f = case p_ of
   478                  Frm => get_obj g_form pt p
   479                | Res => (fst o (get_obj g_result pt)) p
   480            in
   481              ContNOrewInst
   482               {thyID   = theory'2thyID thy',
   483                thm_rls =
   484                  "WN120320: thm2guh (thy_containing_thm thmDeriv) (thmID_of_derivation_name thmDeriv)",
   485                bdvs    = subst,
   486                thminst = thminst,
   487                applto  = f}
   488            end)
   489   | context_thy (pt,p) (tac as Rewrite_Set rls') =
   490       (case applicable_in p pt tac of
   491          Appl (Rewrite_Set' (thy', _, rls, f, (res,asm))) =>
   492            ContRls
   493             {thyID  = theory'2thyID thy',
   494              rls    = "WN120320:  rls2guh (thy_containing_rls thy' rls') rls'",
   495              applto = f,	  
   496              result = res,	  
   497              asms   = asm})
   498   | context_thy (pt,p) (tac as Rewrite_Set_Inst (subs, rls')) = 
   499       (case applicable_in p pt tac of
   500          Appl (Rewrite_Set_Inst' (thy', _, subst, rls, f, (res,asm))) =>
   501            ContRlsInst
   502             {thyID  = theory'2thyID thy',
   503              rls    = "WN120320: rls2guh (thy_containing_rls thy' rls') rls'",
   504              bdvs   = subst,
   505              applto = f,	  
   506              result = res,	  
   507              asms   = asm});
   508 
   509 (* get all theorems in a rule set (recursivley containing rule sets) *)
   510 fun thm_of_rule Erule = []
   511   | thm_of_rule (thm as Thm _) = [thm]
   512   | thm_of_rule (Calc _) = []
   513   | thm_of_rule (Cal1 _) = []
   514   | thm_of_rule (Rls_ rls) = thms_of_rls rls
   515 and thms_of_rls Erls = []
   516   | thms_of_rls (Rls {rules,...}) = (flat o (map  thm_of_rule)) rules
   517   | thms_of_rls (Seq {rules,...}) = (flat o (map  thm_of_rule)) rules
   518   | thms_of_rls (Rrls _) = [];
   519 (* val Hrls {thy_rls = (_, rls),...} =
   520        get_the ["IsacKnowledge", "Test", "Rulesets", "expand_binomtest"];
   521 > thms_of_rls rls;
   522    *)
   523 
   524 (*. check if a rule is contained in a rule-set (recursivley down in Rls_);
   525     this rule can even be a rule-set itself.*)
   526 fun contains_rule r rls = 
   527     let fun find (r, Rls_ rls) = finds (get_rules rls)
   528 	  | find r12 = eq_rule r12
   529 	and finds [] = false
   530 	  | finds (r1 :: rs) = if eq_rule (r, r1) then true else finds rs;
   531     in 
   532     (*tracing ("### contains_rule: r = "^rule2str r^", rls = "^rls2str rls);*)
   533     finds (get_rules rls) 
   534     end;
   535 
   536 (*. try if a rewrite-rule is applicable to a given formula; 
   537     in case of rule-sets (recursivley) collect all _atomic_ rewrites .*) 
   538 fun try_rew thy ((_, ro):rew_ord) erls (subst:subst) f (thm' as Thm(id, thm)) =
   539     if contains_bdv thm
   540     then case rewrite_inst_ thy ro erls false subst thm f of
   541 	      SOME (f',_) =>[rule2tac thy subst thm']
   542 	    | NONE => []
   543     else (case rewrite_ thy ro erls false thm f of
   544 	SOME (f',_) => [rule2tac thy [] thm']
   545 	    | NONE => [])
   546   | try_rew thy _ _ _ f (cal as Calc c) = 
   547     (case get_calculation_ thy c f of
   548 	SOME (str, _) => [rule2tac thy [] cal]
   549       | NONE => [])
   550   | try_rew thy _ _ _ f (cal as Cal1 c) = 
   551     (case get_calculation_ thy c f of
   552 	SOME (str, _) => [rule2tac thy [] cal]
   553       | NONE => [])
   554   | try_rew thy _ _ subst f (Rls_ rls) = filter_appl_rews thy subst f rls
   555 and filter_appl_rews thy subst f (Rls {rew_ord = ro, erls, rules,...}) = 
   556     distinct (flat (map (try_rew thy ro erls subst f) rules))
   557   | filter_appl_rews thy subst f (Seq {rew_ord = ro, erls, rules,...}) = 
   558     distinct (flat (map (try_rew thy ro erls subst f) rules))
   559   | filter_appl_rews thy subst f (Rrls _) = [];
   560 
   561 (*. decide if a tactic is applicable to a given formula; 
   562     in case of Rewrite_Set* go down to _atomic_ rewrite-tactics .*)
   563 (* val 
   564    *)
   565 fun atomic_appl_tacs thy _ _ f (Calculate scrID) =
   566     try_rew thy e_rew_ordX e_rls [] f (Calc (assoc_calc' thy scrID |> snd))
   567   | atomic_appl_tacs thy ro erls f (Rewrite (thm' as (thmID, _))) =
   568     try_rew thy (ro, assoc_rew_ord ro) erls [] f 
   569 	    (Thm (thmID, assoc_thm' thy thm'))
   570   | atomic_appl_tacs thy ro erls f (Rewrite_Inst (subs, thm' as (thmID, _))) =
   571     try_rew thy (ro, assoc_rew_ord ro) erls (subs2subst thy subs) f 
   572 	    (Thm (thmID, assoc_thm' thy thm'))
   573 
   574   | atomic_appl_tacs thy _ _ f (Rewrite_Set rls') =
   575     filter_appl_rews thy [] f (assoc_rls rls')
   576   | atomic_appl_tacs thy _ _ f (Rewrite_Set_Inst (subs, rls')) =
   577     filter_appl_rews thy (subs2subst thy subs) f (assoc_rls rls')
   578   | atomic_appl_tacs _ _ _ _ tac = 
   579     (tracing ("### atomic_appl_tacs: not impl. for tac = '"^ tac2str tac ^"'");
   580      []);
   581 
   582 (*.filenames not only for thydata, but also for thy's etc.*)
   583 fun theID2filename (theID:theID) = theID2guh theID ^ ".xml" : filename;
   584 
   585 fun guh2theID (guh:guh) =
   586     let val guh' = Symbol.explode guh
   587 	val part = implode (take_fromto 1 4 guh')
   588 	val isa = implode (take_fromto 5 9 guh')
   589     in if not (member op = ["exp_", "thy_", "pbl_", "met_"] part)
   590        then error ("guh '"^guh^"' does not begin with \
   591 				     \exp_ | thy_ | pbl_ | met_")
   592        else let val chap = case isa of
   593 				"isab_" => "Isabelle"
   594 			      | "scri_" => "IsacScripts"
   595 			      | "isac_" => "IsacKnowledge"
   596 			      | _ => 
   597 				error ("guh2theID: '"^guh^
   598 					     "' does not have isab_ | scri_ | \
   599 					     \isac_ at position 5..9")
   600 		val rest = takerest (9, guh') 
   601 		val thyID = takewhile [] (not o (curry op= "-")) rest
   602 		val rest' = dropuntil (curry op= "-") rest
   603 	    in case implode rest' of
   604 		   "-part" => [chap] : theID
   605 		 | "" => [chap, implode thyID]
   606 		 | "-Theorems" => [chap, implode thyID, "Theorems"]
   607 		 | "-Rulesets" => [chap, implode thyID, "Rulesets"]
   608 		 | "-Operations" => [chap, implode thyID, "Operations"]
   609 		 | "-Orders" => [chap, implode thyID, "Orders"]
   610 		 | _ => 
   611 		   let val sect = implode (take_fromto 1 5 rest')
   612 		       val sect' = 
   613 			   case sect of
   614 			       "-thm-" => "Theorems"
   615 			     | "-rls-" => "Rulesets"
   616 			     | "-cal-" => "Operations"
   617 			     | "-ord-" => "Orders"
   618 			     | str => 
   619 			       error ("guh2theID: '"^guh^"' has '"^sect^
   620 					    "' instead -thm- | -rls- | \
   621 					    \-cal- | -ord-")
   622 		   in [chap, implode thyID, sect', implode 
   623 						       (takerest (5, rest'))]
   624 		   end
   625 	    end	
   626     end;
   627 (*> guh2theID "thy_isac_Biegelinie-Theorems";
   628 val it = ["IsacKnowledge", "Biegelinie", "Theorems"] : theID
   629 > guh2theID "thy_scri_ListC-thm-zip_Nil";
   630 val it = ["IsacScripts", "ListC", "Theorems", "zip_Nil"] : theID*)
   631 
   632 fun guh2filename (guh : guh) = guh ^ ".xml" : filename;
   633 
   634 
   635 (*..*)
   636 fun guh2rewtac (guh:guh) ([] : subs) =
   637     let val [isa, thy, sect, xstr] = guh2theID guh
   638     in case sect of
   639 	   "Theorems" => Rewrite (xstr, "")
   640 	 | "Rulesets" => Rewrite_Set xstr
   641 	 | str => error ("guh2rewtac: not impl. for '"^xstr^"'") 
   642     end
   643   | guh2rewtac (guh:guh) subs =
   644     let val [isa, thy, sect, xstr] = guh2theID guh
   645     in case sect of
   646 	   "Theorems" => Rewrite_Inst (subs, (xstr, ""))
   647 	 | "Rulesets" => Rewrite_Set_Inst (subs,  xstr)
   648 	 | str => error ("guh2rewtac: not impl. for '"^xstr^"'") 
   649     end;
   650 (*> guh2rewtac "thy_isac_Test-thm-constant_mult_square" [];
   651 val it = Rewrite ("constant_mult_square", "") : tac
   652 > guh2rewtac "thy_isac_Test-thm-risolate_bdv_add" ["(bdv, x)"];
   653 val it = Rewrite_Inst (["(bdv, x)"], ("risolate_bdv_add", "")) : tac
   654 > guh2rewtac "thy_isac_Test-rls-Test_simplify" [];
   655 val it = Rewrite_Set "Test_simplify" : tac
   656 > guh2rewtac "thy_isac_Test-rls-isolate_bdv" ["(bdv, x)"];
   657 val it = Rewrite_Set_Inst (["(bdv, x)"], "isolate_bdv") : tac*)
   658 
   659 
   660 (*.the front-end may request a context for any element of the hierarchy.*)
   661 (* val guh = "thy_isac_Test-rls-Test_simplify";
   662    *)
   663 fun no_thycontext (guh : guh) = (guh2theID guh; false)
   664     handle _ => true;
   665 
   666 (*> has_thycontext  "thy_isac_Test";
   667 if has_thycontext  "thy_isac_Test" then "OK" else "NOTOK";
   668  *)
   669 
   670 
   671 
   672 (*.get the substitution of bound variables for matchTheory:
   673    # lookup the thm|rls' in the script
   674    # take the [(bdv, v_),..] from the respective Rewrite_(Set_)Inst
   675    # instantiate this subs with the istates env to [(bdv, x),..]
   676    # otherwise [].*)
   677 (*WN060617 hack assuming that all scripts use only one bound variable
   678 and use 'v_' as the formal argument for this bound variable*)
   679 (* val (ScrState (env,_,_,_,_,_), _, guh) = (is, "dummy", guh);
   680    *)
   681 fun subs_from (ScrState (env,_,_,_,_,_)) _ (guh:guh) =
   682     let val theID as [isa, thyID, sect, xstr] = guh2theID guh
   683     in case sect of
   684 	   "Theorems" => 
   685 	   let val thm = Global_Theory.get_thm (assoc_thy (thyID2theory' thyID)) xstr
   686 	   in if contains_bdv thm
   687 	      then let val formal_arg = str2term "v_"
   688 		       val value = subst_atomic env formal_arg
   689 		   in ["(bdv," ^ term2str value ^ ")"]:subs end
   690 	      else []
   691 	   end
   692 	 | "Rulesets" => 
   693 	   let val rules = (get_rules o assoc_rls) xstr
   694 	   in if contain_bdv rules
   695 	      then let val formal_arg = str2term"v_"
   696 		       val value = subst_atomic env formal_arg
   697 		   in ["(bdv,"^term2str value^")"]:subs end
   698 	      else []
   699 	   end
   700     end;
   701 
   702 (* get a substitution for "bdv*" from the current program and environment.
   703     returns a substitution: subst for rewriting and another: sube for Rewrite:*)
   704 fun get_bdv_subst prog env =
   705   let
   706     fun scan (Const _) = NONE
   707       | scan (Free _) = NONE
   708       | scan (Var _) = NONE
   709       | scan (Bound _) = NONE
   710       | scan (t as Const ("List.list.Cons", _) $
   711          (Const ("Product_Type.Pair", _) $ Free (str, _) $ _) $ _) =
   712            if is_bdv_subst t then SOME t else NONE
   713       | scan (Abs (_, _, body)) = scan body
   714       | scan (t1 $ t2) =
   715           case scan t1 of
   716             NONE => scan t2
   717           | SOME subst => SOME subst
   718   in
   719     case scan prog of
   720       NONE => (NONE: subs option, []: subst)
   721     | SOME tm =>
   722         let val subst = tm |> subst_atomic env |> isalist2list |> map isapair2pair
   723           (*"[(bdv,v_v)]": term
   724                           |> "[(bdv,x)]": term |> ["(bdv,x)"]: term list
   725                                                          |> [("bdv","x")]: (term * term) list*)
   726         in (SOME (subst2subs subst), subst) end
   727           (*"SOME [(bdv,v_v)]": term --> ["(bdv,v_v)"]: string list*)
   728   end;
   729 
   730 
   731 (* use"ME/rewtools.sml";
   732    *)
   733