src/Tools/isac/Interpret/script.sml
author Walther Neuper <walther.neuper@jku.at>
Wed, 13 Nov 2019 10:28:35 +0100
changeset 59695 cf12e1a182ea
parent 59691 53c60fa9c41c
child 59697 dd85e03d47e6
permissions -rw-r--r--
open Pos with Ctree; !!!in previous changeset no Build_Isac!!!
     1 (* Title:  interpreter for scripts
     2    Author: Walther Neuper 2000
     3    (c) due to copyright terms
     4 *)
     5 
     6 signature LUCAS_INTERPRETER_DEL =
     7 sig
     8 
     9   type step = Tactic.T * Generate.mout * Ctree.ctree * Ctree.pos' * Ctree.pos' list
    10   datatype ass =
    11     Ass of Tactic.T * term * Proof.context
    12   | Ass_Weak of Tactic.T * term * Proof.context
    13   | NotAss;
    14   val associate: Ctree.ctree -> Proof.context -> (Tactic.T * term) -> ass
    15   
    16 (* can these functions be local to Lucin or part of LItools ? *)
    17   val sel_rules : Ctree.ctree -> Ctree.pos' -> Tactic.input list 
    18   val init_form : 'a -> Rule.program -> (term * term) list -> term option
    19   val tac_2tac : Tactic.T -> Tactic.input
    20   val init_pstate : Rule.rls -> Proof.context -> Model.itm list -> Celem.metID -> Istate.T * Proof.context * Rule.program
    21 
    22   val get_simplifier : Ctree.state -> Rule.rls
    23 (*DEPR ^*)val from_pblobj' : Rule.theory' -> Ctree.pos' -> Ctree.ctree ->
    24     Rule.rls(*..\<in> ist*) * (Istate.T * Proof.context) * Rule.program
    25 (*DEPR*)val from_pblobj_or_detail' : Rule.theory' -> Ctree.pos' -> Ctree.ctree -> 
    26     Rule.rls(*..\<in> ist*) * (Istate.T * Proof.context) * Rule.program
    27   val rule2thm'' : Rule.rule -> Celem.thm''
    28   val rule2rls' : Rule.rule -> string
    29   val sel_appl_atomic_tacs : Ctree.ctree -> Ctree.pos' -> Tactic.input list
    30 (*cp here from "! aktivate for Test_Isac" below due to LucinNEW*)
    31   val stac2tac_ : Ctree.ctree -> theory -> term -> Tactic.input * Tactic.T
    32   val tac_2res : Tactic.T -> term
    33   val stac2tac : Ctree.ctree -> theory -> term -> Tactic.input
    34   val rew_only: (Tactic.T * Generate.mout * Ctree.ctree * Ctree.pos' * Ctree.pos' list) list -> bool
    35   val handle_leaf : (*TODO190625: shift to lucas-interpreter.sml ? <- sel_rules, sel_appl_atomic_tacs !*)
    36     string -> Rule.theory' -> Rule.rls -> (Env.T * (term option * term)) -> term -> 
    37       term option * Celem.stacexpr
    38 
    39 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
    40   (*NONE*)
    41 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
    42   val is_spec_pos : Ctree.pos_ -> bool
    43   val itms2args : 'a -> Celem.metID -> Model.itm list -> term list
    44 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
    45 
    46 end 
    47 
    48 (* traces the leaves (ie. non-tactical nodes) of Prog found by determine_next_tactic, see "and scr" *)   
    49 val trace_script = Unsynchronized.ref false; (* TODO: how are traces done in Isabelle? *)
    50 
    51 (**)
    52 structure Lucin(**): LUCAS_INTERPRETER_DEL(**) =
    53 struct
    54 (**)
    55 open Ctree
    56 open Pos
    57 (*TODO open Celem for L,R,D;
    58   the few other Celem.items are acceptable: metID, e_metID, assoc_thy, metID2str, thm''*)
    59 
    60 (**)
    61 (* data for creating a new node in ctree; designed for use as:
    62    fun ass* pstate steps = / ... case ass* pstate steps of /
    63    Assoc (pstate, steps) => ... ass* pstate steps *)
    64 type step = (*WN190713 REMOVE: "creating a new node" was never implemented for more than one node?!?
    65               WN190713 COMPARE: taci list, see papernote #139 *)
    66     Tactic.T        (*transformed from associated tac                   *)
    67     * Generate.mout (*result with indentation etc.                      *)
    68     * ctree         (*containing node created by tac_ + resp. pstate  *)
    69     * pos'          (*position in ctree; ctree * pos' is the proofstate *)
    70     * pos' list;    (*of ctree-nodes probably cut (by fst tac_)         
    71               WN190713 COMPARE: pos' list also in calcstate'*)
    72 
    73 fun rule2thm'' (Rule.Thm (id, thm)) = (id, thm)
    74   | rule2thm'' r = error ("rule2thm': not defined for " ^ Rule.rule2str r);
    75 fun rule2rls' (Rule.Rls_ rls) = Rule.id_rls rls
    76   | rule2rls' r = error ("rule2rls': not defined for " ^ Rule.rule2str r);
    77 
    78 (*check if there are tacs for rewriting only*)
    79 fun rew_only ([]:step list) = true
    80   | rew_only (((Tactic.Rewrite' _          ,_,_,_,_))::ss) = rew_only ss
    81   | rew_only (((Tactic.Rewrite_Inst' _     ,_,_,_,_))::ss) = rew_only ss
    82   | rew_only (((Tactic.Rewrite_Set' _      ,_,_,_,_))::ss) = rew_only ss
    83   | rew_only (((Tactic.Rewrite_Set_Inst' _ ,_,_,_,_))::ss) = rew_only ss
    84   | rew_only (((Tactic.Calculate' _        ,_,_,_,_))::ss) = rew_only ss
    85   | rew_only (((Tactic.Begin_Trans' _      ,_,_,_,_))::ss) = rew_only ss
    86   | rew_only (((Tactic.End_Trans' _        ,_,_,_,_))::ss) = rew_only ss
    87   | rew_only _ = false; 
    88 
    89 (* functions for the environment stack: NOT YET IMPLEMENTED
    90 fun accessenv id es = the (assoc ((top es) : Env.upd_env, id))
    91     handle _ => error ("accessenv: " ^ free2str id ^ " not in Env.upd_env");
    92 fun updateenv id vl (es : Env.upd_env stack) = 
    93     (push (overwrite(top es, (id, vl))) (pop es)) : Env.upd_env stack;
    94 fun pushenv id vl (es : Env.upd_env stack) = 
    95     (push (overwrite(top es, (id, vl))) es) : Env.upd_env stack;
    96 val popenv = pop : Env.upd_env stack -> Env.upd_env stack;
    97 *)
    98 
    99 fun de_esc_underscore str =
   100   let
   101     fun scan [] = []
   102     | scan (s :: ss) = if s = "'" then (scan ss) else (s :: (scan ss))
   103   in (implode o scan o Symbol.explode) str end;
   104 
   105 fun init_form thy (Rule.Prog sc) env =
   106     (case Prog_Tac.get_stac thy sc of NONE => NONE | SOME stac => SOME (subst_atomic env stac))
   107   | init_form _ _ _ = error "init_form: no match";
   108 
   109 type dsc = typ; (* <-> nam..unknow in Descript.thy *)
   110 
   111 (*.create the actual parameters (args) of script: their order 
   112   is given by the order in met.pat .*)
   113 (*WN.5.5.03: ?: does this allow for different descriptions ???
   114              ?: why not taken from formal args of script ???
   115 !: FIXXXME penv: push it here in itms2args into script-evaluation*)
   116 val errmsg = "ERROR: the guard is missing (#ppc in 'type met' added in prep_met)."
   117 fun errmsg2 d itms = ("itms2args: '" ^ Rule.term2str d ^ "' not in itms:\n" ^
   118 "itms:\n" ^ Model.itms2str_ @{context} itms)
   119 fun itms2args _ mI itms =
   120   let
   121     val mvat = Model.max_vt itms
   122     fun okv mvat (_, vats, b, _, _) = member op = vats mvat andalso b
   123     val itms = filter (okv mvat) itms
   124     fun test_dsc d (_, _, _, _, itm_) = (d = Model.d_in itm_)
   125     fun itm2arg itms (_,(d,_)) =
   126         case find_first (test_dsc d) itms of
   127           NONE => raise ERROR (errmsg2 d itms)
   128         | SOME (_, _, _, _, itm_) => Model.penvval_in itm_
   129       (*| SOME (_,_,_,_,itm_) => mk_arg thy (Model.d_in itm_) (ts_in itm_);
   130             penv postponed; presently penv holds already Env.upd_env for script*)
   131     val pats = (#ppc o Specify.get_met) mI
   132     val _ = if pats = [] then raise ERROR errmsg else ()
   133   in (flat o (map (itm2arg itms))) pats end;
   134 
   135 (* convert a script-tac 'stac' to 'tac' for users;
   136    for "Prog_Tac.SubProblem" also create a 'tac_' for internal use. FIXME separate?
   137    if stac is an initac, then convert to a 'tac_' (as required in scan_dn2).
   138    arg ctree for pushing the thy specified in rootpbl into subpbls    *)
   139 fun stac2tac_ _ thy (Const ("Prog_Tac.Rewrite", _) $ thmID $ _) =
   140     let
   141       val tid = HOLogic.dest_string thmID
   142     in (Tactic.Rewrite (tid, Rewrite.assoc_thm'' thy tid), Tactic.Empty_Tac_) end
   143   | stac2tac_ _ thy (Const ("Prog_Tac.Rewrite'_Inst", _) $ sub $ thmID $ _) =
   144     let
   145       val tid = HOLogic.dest_string thmID
   146     in (Tactic.Rewrite_Inst (Selem.subst'_to_sube sub, (tid, Rewrite.assoc_thm'' thy tid)), Tactic.Empty_Tac_) end
   147   | stac2tac_ _ _ (Const ("Prog_Tac.Rewrite'_Set",_) $ rls $ _) =
   148      (Tactic.Rewrite_Set (HOLogic.dest_string rls), Tactic.Empty_Tac_)
   149   | stac2tac_ _ _ (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ sub $ rls $ _) =
   150       (Tactic.Rewrite_Set_Inst (Selem.subst'_to_sube sub, HOLogic.dest_string rls), Tactic.Empty_Tac_)
   151   | stac2tac_ _ _ (Const ("Prog_Tac.Calculate", _) $ op_ $ _) =
   152       (Tactic.Calculate (HOLogic.dest_string op_), Tactic.Empty_Tac_)
   153   | stac2tac_ _ _ (Const ("Prog_Tac.Take", _) $ t) = (Tactic.Take (Rule.term2str t), Tactic.Empty_Tac_)
   154   | stac2tac_ _ _ (Const ("Prog_Tac.Substitute", _) $ isasub $ _) =
   155     (Tactic.Substitute ((Selem.subte2sube o TermC.isalist2list) isasub), Tactic.Empty_Tac_)
   156   | stac2tac_ _ thy (Const("Prog_Tac.Check'_elementwise", _) $ _ $ 
   157     (Const ("Set.Collect", _) $ Abs (_, _, pred))) =
   158       (Tactic.Check_elementwise (Rule.term_to_string''' thy pred), Tactic.Empty_Tac_)
   159   | stac2tac_ _ _ (Const("Prog_Tac.Or'_to'_List", _) $ _ ) = (Tactic.Or_to_List, Tactic.Empty_Tac_)
   160 
   161     (*compare "| associate _ (Subproblem'" ..TODO: extract common code *)
   162   | stac2tac_ pt _ (stac as Const ("Prog_Tac.SubProblem", _) $ spec' $ ags') =
   163     let
   164       val (dI, pI, mI) = Prog_Tac.dest_spec spec'
   165       val thy = Stool.common_subthy (Celem.assoc_thy dI, rootthy pt);
   166 	    val ags = TermC.isalist2list ags';
   167 	    val (pI, pors, mI) = 
   168 	      if mI = ["no_met"]
   169 	      then
   170           let
   171             val pors = (Chead.match_ags thy ((#ppc o Specify.get_pbt) pI) ags)
   172             (*    Chead.match_ags : theory -> pat list                 -> term list -> ori list
   173                                               ^^^ variables               ^^^ values          *)
   174 		          handle ERROR "actual args do not match formal args" 
   175 			        => (Chead.match_ags_msg pI stac ags(*raise exn*); [])
   176 		        val pI' = Specify.refine_ori' pors pI;
   177 		      in (pI', pors (* refinement over models with diff.prec only *), 
   178 		          (hd o #met o Specify.get_pbt) pI') end
   179 	      else (pI, (Chead.match_ags thy ((#ppc o Specify.get_pbt) pI) ags)
   180 		      handle ERROR "actual args do not match formal args"
   181 		      => (Chead.match_ags_msg pI stac ags(*raise exn*); []), mI);
   182       val (fmz_, vals) = Chead.oris2fmz_vals pors;
   183 	    val {cas,ppc,thy,...} = Specify.get_pbt pI
   184 	    val dI = Rule.theory2theory' thy (*.take dI from _refined_ pbl.*)
   185 	    val dI = Rule.theory2theory' (Stool.common_subthy (Celem.assoc_thy dI, rootthy pt));
   186       val ctxt = ContextC.initialise dI vals
   187 	    val hdl =
   188         case cas of
   189 		      NONE => Auto_Prog.pblterm dI pI
   190 		    | SOME t => subst_atomic ((Chead.vars_of_pbl_' ppc) ~~~ vals) t
   191       val f = Auto_Prog.subpbl (strip_thy dI) pI
   192     in (Tactic.Subproblem (dI, pI),	Tactic.Subproblem' ((dI, pI, mI), pors, hdl, fmz_, ctxt, f))
   193     end
   194   | stac2tac_ _ thy t = error ("stac2tac_ TODO: no match for " ^ Rule.term_to_string''' thy t);
   195 
   196 fun stac2tac pt thy t = (fst o stac2tac_ pt thy) t;
   197 
   198 datatype ass =
   199     Ass of
   200       Tactic.T        (* SubProblem gets args instantiated in associate     *)
   201       * term          (* for itr_arg, result in ets                         *)
   202       * Proof.context (* separate from Tactic.T like in loacte_input_tactic *)
   203   | Ass_Weak of Tactic.T * term * Proof.context
   204   | NotAss;
   205 
   206 (* check if tac_ is associated with stac.
   207    Note: this is the only fun in "fun locate_input_tactic", which handles tactics individually.
   208    Additional tasks: 
   209   (1) to "Subproblem'" add "pors, hdl, fmz_, ctxt, f" TODO: ctxt <-?-> sig locate_input_tac
   210   (2) check if term t (the result has been calculated from) in tac_
   211    has been changed (see "datatype tac_"); if yes, recalculate result
   212    TODO.WN120106 recalculate impl.only for Substitute'
   213 args
   214   pt     : ctree for pushing the thy specified in rootpbl into subpbls
   215   d      : unused (planned for data for comparison)
   216   tac_   : from user (via applicable_in); to be compared with ...
   217   stac   : found in program
   218 returns
   219   Ass    : associated: e.g. thmID in stac = thmID in m
   220                        +++ arg   in stac = arg   in m
   221   Ass_Weak: weakly ass.:e.g. thmID in stac = thmID in m, //arg//
   222   NotAss :             e.g. thmID in stac/=/thmID in m (not =)
   223 *)
   224 fun associate _ ctxt (m as Tactic.Rewrite_Inst'
   225       (_, _, _, _, _, thm'' as (thmID, _), f, (f', asms')), stac) =
   226     (case stac of
   227 	    (Const ("Prog_Tac.Rewrite'_Inst", _) $ _ $ thmID_ $ f_) =>
   228 	      if thmID = HOLogic.dest_string thmID_
   229         then 
   230 	        if f = f_ 
   231           then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   232 	        else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
   233 	      else ((*tracing"3### associate ..NotAss";*) NotAss)
   234     | (Const ("Prog_Tac.Rewrite'_Set'_Inst",_) $ _ $ rls_ $ f_) =>
   235 	      if Rtools.contains_rule (Rule.Thm thm'') (assoc_rls (HOLogic.dest_string rls_))
   236         then if f = f_ then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   237         else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
   238 	      else NotAss
   239     | _ => NotAss)
   240   | associate _ ctxt (m as Tactic.Rewrite' (_, _, _, _, thm'' as (thmID, _), f, (f', asms')), stac) =
   241     (case stac of
   242 	    (Const ("Prog_Tac.Rewrite", _) $ thmID_ $ f_) =>
   243 	      if thmID = HOLogic.dest_string thmID_
   244         then 
   245 	        if f = f_
   246           then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   247 	        else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
   248 	      else NotAss
   249     | (Const ("Prog_Tac.Rewrite'_Set", _) $ rls_ $ f_) =>
   250 	       if Rtools.contains_rule (Rule.Thm thm'') (assoc_rls (HOLogic.dest_string rls_))
   251          then
   252            if f = f_
   253            then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   254 	         else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
   255 	       else NotAss
   256     | _ => NotAss)
   257   | associate _ ctxt (m as Tactic.Rewrite_Set_Inst' (_, _, _, rls, f, (f', asms')),
   258       (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ _ $ rls_ $ f_)) = 
   259     if Rule.id_rls rls = HOLogic.dest_string rls_ 
   260     then
   261       if f = f_
   262       then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   263       else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
   264     else NotAss
   265   | associate _ ctxt (m as Tactic.Detail_Set_Inst' (_, _, _, rls, f, (f', asms')),
   266       (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ _ $ rls_ $ f_)) = 
   267     if Rule.id_rls rls = HOLogic.dest_string rls_
   268     then
   269       if f = f_
   270       then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   271       else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
   272     else NotAss
   273   | associate _ ctxt (m as Tactic.Rewrite_Set' (_, _, rls, f, (f', asms')),
   274       (Const ("Prog_Tac.Rewrite'_Set", _) $ rls_ $ f_)) = 
   275     if Rule.id_rls rls = HOLogic.dest_string rls_
   276     then
   277       if f = f_
   278       then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   279       else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
   280     else NotAss
   281   | associate _ ctxt (m as Tactic.Detail_Set' (_, _, rls, f, (f', asms')),
   282       (Const ("Prog_Tac.Rewrite'_Set", _) $ rls_ $ f_)) = 
   283     if Rule.id_rls rls = HOLogic.dest_string rls_
   284     then 
   285       if f = f_
   286       then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
   287       else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
   288     else NotAss
   289   | associate _ ctxt (m as Tactic.Calculate' (_, op_, f, (f', _)), stac) =
   290     (case stac of
   291 	    (Const ("Prog_Tac.Calculate",_) $ op__ $ f_) =>
   292 	      if op_ = HOLogic.dest_string op__
   293         then
   294           if f = f_
   295           then Ass (m, f', ctxt)
   296           else Ass_Weak (m ,f', ctxt)
   297 	      else NotAss
   298     | (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ _ $ rls_ $ f_)  =>
   299         let val thy = Celem.assoc_thy "Isac_Knowledge";
   300         in
   301           if Rtools.contains_rule (Rule.Calc (assoc_calc' thy op_ |> snd)) 
   302             (assoc_rls (HOLogic.dest_string rls_))
   303           then
   304             if f = f_
   305             then Ass (m, f', ctxt)
   306             else Ass_Weak (m ,f', ctxt)
   307           else NotAss
   308         end
   309     | (Const ("Prog_Tac.Rewrite'_Set",_) $ rls_ $ f_) =>
   310         let val thy = Celem.assoc_thy "Isac_Knowledge";
   311         in
   312           if Rtools.contains_rule (Rule.Calc (assoc_calc' thy op_ |> snd))
   313             (assoc_rls (HOLogic.dest_string rls_))
   314           then
   315             if f = f_
   316             then Ass (m, f', ctxt)
   317             else Ass_Weak (m ,f', ctxt)
   318           else NotAss
   319         end
   320     | _ => NotAss)
   321   | associate _ ctxt (m as Tactic.Check_elementwise' (consts, _, (consts_chkd, _)),
   322       (Const ("Prog_Tac.Check'_elementwise",_) $ consts' $ _)) =
   323     if consts = consts'
   324     then Ass (m, consts_chkd, ctxt)
   325     else NotAss
   326   | associate _ ctxt (m as Tactic.Or_to_List' (_, list), (Const ("Prog_Tac.Or'_to'_List", _) $ _)) =
   327     Ass (m, list, ctxt)
   328   | associate _ ctxt (m as Tactic.Take' term, (Const ("Prog_Tac.Take", _) $ _)) = Ass (m, term, ctxt)
   329   | associate _ ctxt (m as Tactic.Substitute' (ro, erls, subte, f, f'),
   330       (Const ("Prog_Tac.Substitute", _) $ _ $ t)) =
   331 	  if f = t then Ass (m, f', ctxt)
   332 	  else (*compare | applicable_in (p,p_) pt (m as Substitute sube)*)
   333 		  if foldl and_ (true, map TermC.contains_Var subte)
   334 		  then
   335 		    let val t' = subst_atomic (map HOLogic.dest_eq subte (*TODO subte2subst*)) t
   336 		    in if t = t' then error "associate: Substitute' not applicable to val of Expr"
   337 		       else Ass (Tactic.Substitute' (ro, erls, subte, t, t'), t', ctxt)
   338 		    end
   339 		  else (case Rewrite.rewrite_terms_ (Rule.Isac ()) ro erls subte t of
   340 		         SOME (t', _) =>  Ass (Tactic.Substitute' (ro, erls, subte, t, t'), t', ctxt)
   341 		       | NONE => error "associate: Substitute' not applicable to val of Expr")
   342 
   343     (*compare "| stac2tac_ thy (Const ("Prog_Tac.SubProblem",_)" ..TODO: extract common code *)
   344   | associate pt _ (Tactic.Subproblem' ((domID, pblID, _), _, _, _, _, _),
   345       (stac as Const ("Prog_Tac.SubProblem", _) $ spec' $ ags')) =
   346     let
   347       val (dI, pI, mI) = Prog_Tac.dest_spec spec'
   348       val thy = Stool.common_subthy (Celem.assoc_thy dI, rootthy pt);
   349 	    val ags = TermC.isalist2list ags';
   350 	    val (pI, pors, mI) = 
   351 	      if mI = ["no_met"]
   352 	      then
   353           let
   354             val pors = (Chead.match_ags thy ((#ppc o Specify.get_pbt) pI) ags)
   355 		          handle ERROR "actual args do not match formal args"
   356 			          => (Chead.match_ags_msg pI stac ags(*raise exn*);[]);
   357 		        val pI' = Specify.refine_ori' pors pI;
   358 		      in (pI', pors (*refinement over models with diff.prec only*), (hd o #met o Specify.get_pbt) pI')
   359           end
   360 	      else (pI, (Chead.match_ags thy ((#ppc o Specify.get_pbt) pI) ags)
   361 		      handle ERROR "actual args do not match formal args"
   362 		      => (Chead.match_ags_msg pI stac ags(*raise exn*); []), mI);
   363       val (fmz_, vals) = Chead.oris2fmz_vals pors;
   364 	    val {cas, ppc, thy, ...} = Specify.get_pbt pI
   365 	    val dI = Rule.theory2theory' thy (*take dI from _refined_ pbl*)
   366 	    val dI = Rule.theory2theory' (Stool.common_subthy (Celem.assoc_thy dI, rootthy pt))
   367 	    val ctxt = ContextC.initialise dI vals
   368 	    val hdl = 
   369         case cas of
   370 		      NONE => Auto_Prog.pblterm dI pI
   371 		    | SOME t => subst_atomic ((Chead.vars_of_pbl_' ppc) ~~~ vals) t
   372       val f = Auto_Prog.subpbl (strip_thy dI) pI
   373     in 
   374       if domID = dI andalso pblID = pI
   375       then Ass (Tactic.Subproblem' ((dI, pI, mI), pors, hdl, fmz_, ContextC.e_ctxt(*TODO rm*), f), f, ctxt)
   376       else NotAss
   377     end
   378   | associate _ _ (m, _) = 
   379     (if (!trace_script) 
   380      then tracing("@@@ the 'tac_' proposed to apply does NOT match the leaf found in the script:\n"
   381 		   ^ "@@@ tac_ = " ^ Tactic.tac_2str m)
   382      else ();
   383     NotAss);
   384 
   385 fun tac_2tac (Tactic.Refine_Tacitly' (pI, _, _, _, _)) = Tactic.Refine_Tacitly pI
   386   | tac_2tac (Tactic.Model_Problem' (_, _, _)) = Tactic.Model_Problem
   387   | tac_2tac (Tactic.Add_Given' (t, _)) = Tactic.Add_Given t
   388   | tac_2tac (Tactic.Add_Find' (t, _)) = Tactic.Add_Find t
   389   | tac_2tac (Tactic.Add_Relation' (t, _)) = Tactic.Add_Relation t
   390  
   391   | tac_2tac (Tactic.Specify_Theory' dI) = Tactic.Specify_Theory dI
   392   | tac_2tac (Tactic.Specify_Problem' (dI, _)) = Tactic.Specify_Problem dI
   393   | tac_2tac (Tactic.Specify_Method' (dI, _, _)) = Tactic.Specify_Method dI
   394   
   395   | tac_2tac (Tactic.Rewrite' (_, _, _, _, thm, _, _)) = Tactic.Rewrite thm
   396   | tac_2tac (Tactic.Rewrite_Inst' (_, _, _, _, sub, thm, _, _)) = Tactic.Rewrite_Inst (Selem.subst2subs sub, thm)
   397 
   398   | tac_2tac (Tactic.Rewrite_Set' (_, _, rls, _, _)) = Tactic.Rewrite_Set (Rule.id_rls rls)
   399   | tac_2tac (Tactic.Detail_Set' (_, _, rls, _, _)) = Tactic.Detail_Set (Rule.id_rls rls)
   400 
   401   | tac_2tac (Tactic.Rewrite_Set_Inst' (_, _, sub, rls, _, _)) = 
   402     Tactic.Rewrite_Set_Inst (Selem.subst2subs sub, Rule.id_rls rls)
   403   | tac_2tac (Tactic.Detail_Set_Inst' (_, _, sub, rls, _, _)) = 
   404     Tactic.Detail_Set_Inst (Selem.subst2subs sub, Rule.id_rls rls)
   405 
   406   | tac_2tac (Tactic.Calculate' (_, op_, _, _)) = Tactic.Calculate (op_)
   407   | tac_2tac (Tactic.Check_elementwise' (_, pred, _)) = Tactic.Check_elementwise pred
   408 
   409   | tac_2tac (Tactic.Or_to_List' _) = Tactic.Or_to_List
   410   | tac_2tac (Tactic.Take' term) = Tactic.Take (Rule.term2str term)
   411   | tac_2tac (Tactic.Substitute' (_, _, subte, _, _)) = Tactic.Substitute (Selem.subte2sube subte) 
   412   | tac_2tac (Tactic.Tac_ (_, _, id, _)) = Tactic.Tac id
   413 
   414   | tac_2tac (Tactic.Subproblem' ((domID, pblID, _), _, _, _,_ ,_)) = Tactic.Subproblem (domID, pblID)
   415   | tac_2tac (Tactic.Check_Postcond' (pblID, _)) = Tactic.Check_Postcond pblID
   416   | tac_2tac Tactic.Empty_Tac_ = Tactic.Empty_Tac
   417   | tac_2tac m = error ("tac_2tac: not impl. for "^(Tactic.tac_2str m));
   418 
   419 fun make_rule thy t =
   420   let val ct = Thm.global_cterm_of thy (HOLogic.Trueprop $ t)
   421   in Rule.Thm (Rule.term_to_string''' thy (Thm.term_of ct), Thm.make_thm ct) end;
   422 
   423 fun rep_tac_ (Tactic.Rewrite_Inst' (thy', _, _, _, subs, (thmID, _), f, (f', _))) = 
   424     let
   425       val subs' = Selem.subst_to_subst' subs;
   426       val sT' = type_of subs';
   427       val fT = type_of f;
   428       val lhs = Const ("Prog_Tac.Rewrite'_Inst", [sT', HOLogic.stringT, fT] ---> fT) 
   429         $ subs' $ HOLogic.mk_string thmID $ f;
   430     in (((make_rule (Celem.assoc_thy thy')) o HOLogic.mk_eq) (lhs, f'), (lhs, f')) end
   431   | rep_tac_ (Tactic.Rewrite' (thy', _, _, _, (thmID, _), f, (f', _)))=
   432     let 
   433       val fT = type_of f;
   434       val lhs = Const ("Prog_Tac.Rewrite", [HOLogic.stringT, fT] ---> fT)
   435         $ HOLogic.mk_string thmID $ f;
   436     in (((make_rule (Celem.assoc_thy thy')) o HOLogic.mk_eq) (lhs, f'), (lhs, f')) end
   437   | rep_tac_ (Tactic.Rewrite_Set_Inst' (thy', _, subs, rls, f, (f', _))) =
   438     let
   439       val subs' = Selem.subst_to_subst' subs;
   440       val sT' = type_of subs';
   441       val fT = type_of f;
   442       val lhs = Const ("Prog_Tac.Rewrite'_Set'_Inst", [sT', HOLogic.stringT, fT] ---> fT) 
   443         $ subs' $ HOLogic.mk_string (Rule.id_rls rls) $ f;
   444     in (((make_rule (Celem.assoc_thy thy')) o HOLogic.mk_eq) (lhs, f'), (lhs, f')) end
   445   | rep_tac_ (Tactic.Rewrite_Set' (thy', _, rls, f, (f', _))) =
   446     let 
   447       val fT = type_of f;
   448       val lhs = Const ("Prog_Tac.Rewrite'_Set", [HOLogic.stringT, fT] ---> fT) 
   449         $ HOLogic.mk_string (Rule.id_rls rls) $ f;
   450     in (((make_rule (Celem.assoc_thy thy')) o HOLogic.mk_eq) (lhs,f'),(lhs,f')) end
   451   | rep_tac_ (Tactic.Calculate' (thy', op_, f, (f', _)))=
   452     let
   453       val fT = type_of f;
   454       val lhs = Const ("Prog_Tac.Calculate",[HOLogic.stringT,fT] ---> fT) $ HOLogic.mk_string op_ $ f
   455     in (((make_rule (Celem.assoc_thy thy')) o HOLogic.mk_eq) (lhs,f'),(lhs,f')) end
   456   | rep_tac_ (Tactic.Check_elementwise' (_, _, (t', _))) = (Rule.Erule, (Rule.e_term, t'))
   457   | rep_tac_ (Tactic.Subproblem' (_, _, _, _, _, t')) = (Rule.Erule, (Rule.e_term, t'))
   458   | rep_tac_ (Tactic.Take' t') = (Rule.Erule, (Rule.e_term, t'))
   459   | rep_tac_ (Tactic.Substitute' (_, _, _, t, t')) = (Rule.Erule, (t, t'))
   460   | rep_tac_ (Tactic.Or_to_List' (t, t')) = (Rule.Erule, (t, t'))
   461   | rep_tac_ m = error ("rep_tac_: not impl.for " ^ Tactic.tac_2str m)
   462 
   463 fun tac_2res m = (snd o snd o rep_tac_) m;
   464 
   465 (* create the initial interpreter state
   466   from the items of the guard and the formal arguments of the partial_function.
   467 Note on progression from (a) type fmz_ \<longrightarrow> (e) arguments of the partial_function:
   468   (a) fmz is given by a math author
   469   (b) fmz_ is transformed to ori list as a prerequisite for efficient interactive modelling
   470   (c) modelling creates an itm list from ori list + possible user input
   471   (d) specifying a theory might add some items and create a guard for the partial_function
   472   (e) fun relate_args creates an environment for evaluating the partial_function.
   473 Note on sequence-relation (a) -- (e), i.e. the (formal) arguments of the partial_function:
   474   * Since the arguments of the partial_function have no description (see Descript.thy),
   475     (e) depends on the sequence in fmz_ and on the types of the formal arguments.
   476   * pairing formal arguments with itm's follows the sequence
   477   * Thus the resulting sequence-relation can be ambiguous.
   478   * Ambiguities are done by rearranging fmz_ or the formal arguments.
   479   * The latter is easier, albeit not optimal: a fmz_ can be used by different partial_functions.
   480   *)
   481 local
   482 val errmsg = "ERROR: found no actual arguments for prog. of "
   483 fun msg_miss sc metID caller f formals actuals =
   484   "ERROR in creating the environment from formal args. of partial_function \"" ^ fst (Program.get_fun_id sc) ^ "\"\n" ^
   485 	"and the actual args., ie. items of the guard of \"" ^ Celem.metID2str metID ^ "\" by \"" ^ caller ^ "\":\n" ^
   486 	"formal arg \"" ^ Rule.term2str f ^ "\" doesn't mach an actual arg.\n" ^
   487 	"with:\n" ^
   488 	(string_of_int o length) formals ^ " formal args: " ^ Rule.terms2str formals ^ "\n" ^
   489 	(string_of_int o length) actuals ^ " actual args: " ^ Rule.terms2str actuals
   490 fun msg_miss_type sc metID f formals actuals =
   491   "ERROR in creating the environment from formal args. of partial_function \"" ^ fst (Program.get_fun_id sc) ^ "\"\n" ^
   492 	"and the actual args., ie. items of the guard of \"" ^ Celem.metID2str metID ^ "\" by \"assoc_by_type\":\n" ^
   493 	"formal arg \"" ^ Rule.term2str f ^ "\" of type \"" ^ Rule.type2str (type_of f) ^
   494   "\" doesn't mach an actual arg.\nwith:\n" ^
   495 	(string_of_int o length) formals ^ " formal args: " ^ Rule.terms2str formals ^ "\n" ^
   496 	(string_of_int o length) actuals ^ " actual args: " ^ Rule.terms2str actuals ^ "\n" ^
   497   "   with types: " ^ (strs2str o (map (Rule.type2str o type_of))) actuals
   498 fun msg_ambiguous sc metID f aas formals actuals =
   499   "AMBIGUITY in creating the environment from formal args. of partial_function \"" ^ fst (Program.get_fun_id sc) ^ "\"\n" ^
   500 	"and the actual args., ie. items of the guard of \"" ^ Celem.metID2str metID ^ "\" by \"assoc_by_type\":\n" ^
   501   "formal arg. \"" ^ Rule.term2str f ^ "\" type-matches with several..."  ^
   502   "actual args. \"" ^ Rule.terms2str aas ^ "\"\n" ^
   503   "selected \"" ^ Rule.term2str (hd aas) ^ "\"\n" ^
   504 	"with\n" ^
   505 	"formals: " ^ Rule.terms2str formals ^ "\n" ^
   506 	"actuals: " ^ Rule.terms2str actuals
   507 fun trace_init metID =
   508   if (!trace_script) 
   509   then tracing("@@@ program " ^ strs2str metID)
   510   else ();
   511 fun trace_istate env =
   512   if (!trace_script) 
   513   then tracing("@@@ istate " ^ Env.env2str env)
   514   else ();
   515 in
   516 fun init_pstate srls ctxt itms metID =
   517   let
   518 (*//----------- hack for funpack: generalise handling of meths which extend problem items -----\\*)
   519 val itms =
   520   if metID = ["IntegrierenUndKonstanteBestimmen2"]
   521   then itms @
   522     [(4, [1], true, "#Given", Model.Cor ((Const ("Biegelinie.Biegelinie", Type ("fun", [Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]), Type ("Input_Descript.una", [])])),
   523         [Free ("y", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))]),
   524       (Free ("id_fun", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])])),
   525         [Free ("y", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))] ))),
   526     (5, [1], true, "#Given", Model.Cor ((Const ("Biegelinie.AbleitungBiegelinie", Type ("fun", [Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]), Type ("Input_Descript.una", [])])),
   527         [Free ("dy", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))]),
   528       (Free ("id_abl", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])])),
   529         [Free ("dy", Type ("fun", [Type ("Real.real", []), Type ("Real.real", [])]))] )))]
   530   else itms
   531 (*\\----------- hack for funpack: generalise handling of meths which extend problem items -----//*)
   532     val actuals = itms2args (Proof_Context.theory_of ctxt) metID itms
   533     val _ = if actuals <> [] then () else raise ERROR (errmsg ^ strs2str' metID)
   534     val (scr, sc) = (case (#scr o Specify.get_met) metID of
   535            scr as Rule.Prog sc => (trace_init metID; (scr, sc))
   536        | _ => raise ERROR ("init_pstate with " ^ Celem.metID2str metID))
   537     val formals = Program.formal_args sc    
   538     fun assoc_by_type f aa =
   539       case filter (curry (fn (f, a) => type_of f = type_of a) f) aa of
   540         [] => error (msg_miss_type sc metID f formals actuals)
   541       | [a] => (f, a)
   542       | aas as (a :: _) => (writeln (msg_ambiguous sc metID f aas formals actuals); (f, a));
   543 	  fun relate_args _ (f::_)  [] = error (msg_miss sc metID "relate_args" f formals actuals)
   544 	    | relate_args env [] _ = env (*may drop Find?*)
   545 	    | relate_args env (f::ff) (aas as (a::aa)) = 
   546 	      if type_of f = type_of a 
   547 	      then relate_args (env @ [(f, a)]) ff aa
   548         else
   549           let val (f, a) = assoc_by_type f aas
   550           in relate_args (env @ [(f, a)]) ff (remove op = a aas) end
   551     val {pre, prls, ...} = Specify.get_met metID;
   552     val pres = Stool.check_preconds (Proof_Context.theory_of ctxt) prls pre itms |> map snd;
   553     val ctxt = ctxt |> ContextC.insert_assumptions pres;
   554     val ist = Istate.e_scrstate
   555       |> Istate.upd_rls srls
   556       |> Istate.upd_env_true (relate_args [] formals actuals)
   557   in
   558     (Istate.Pstate ist, ctxt, scr)
   559   end;
   560 end (*local*)
   561 
   562 fun get_simplifier (pt, (p, _)) =
   563   let
   564     val p' = Ctree.par_pblobj pt p
   565 	  val metID = Ctree.get_obj Ctree.g_metID pt p'
   566 	  val {srls, ...} = Specify.get_met metID
   567   in srls end
   568 
   569 (* decide, where to get program/istate from:
   570    (* 1 *) from PblObj.Env.upd_env: at begin of program if no init_form
   571    (* 2 *) from PblObj/PrfObj: if Prog_Tac is in the middle of the program
   572    (* 3 *) from rls/PrfObj: in case of Math_Engine.detailstep *)
   573 fun from_pblobj_or_detail' _ (p, p_) pt =
   574   if member op = [Pbl, Met] p_
   575   then case get_obj g_env (*?DEPRECATED?*) pt p of
   576     NONE => error "from_pblobj_or_detail': no istate"
   577   | SOME (Istate.Pstate pst, ctxt) =>
   578       let
   579         val metID = get_obj g_metID pt p
   580         val {srls, ...} = Specify.get_met metID
   581       in
   582         (srls, (Istate.Pstate (Istate.upd_rls srls pst), ctxt), (#scr o Specify.get_met) metID)
   583       end
   584   | _ => raise ERROR "from_pblobj_or_detail': unexpected result from g_env"
   585   else
   586     let val (pbl, p', rls') = par_pbl_det pt p
   587     in if pbl
   588        then (*if last_elem p = 0 nothing written to pt yet*)                               (* 2 *)
   589          let
   590 	         val metID = get_obj g_metID pt p'
   591 	         val {srls, ...} = Specify.get_met metID
   592 	         val (is, ctxt) =
   593 	           case get_loc pt (p, p_) of
   594 	              (Istate.Pstate ist, ctxt) => (Istate.Pstate (Istate.upd_rls srls ist), ctxt)
   595 	           | _ => raise ERROR "from_pblobj_or_detail': unexpected result from get_loc"
   596 	       in (srls, (is, ctxt), (#scr o Specify.get_met) metID) end
   597        else
   598         let
   599         (*TODO.thy Auto_Prog.generate SHOULD REPLACE ALL HIS..*)
   600           val prog = case rls' of
   601 		          Rule.Rls {scr = Rule.Prog prog,...} => prog
   602 	          | Rule.Seq {scr = Rule.Prog prog,...} => prog
   603 	          | _ => raise ERROR ("from_pblobj_or_detail': not for rule-set \"" ^ Rule.id_rls rls' ^ "\"")
   604           val t = get_last_formula (pt, (p, p_))
   605           val prog' = Auto_Prog.subst_typs prog (type_of t) (TermC.guess_bdv_typ t)
   606         in (Rule.e_rls(*!!!*), get_loc pt (p, p_), Rule.Prog prog') end
   607     end
   608 
   609 fun from_pblobj' thy' (p,p_) pt = (*.get script and istate, UNUSED; see above             ( * 1 *)
   610   let
   611     val p' = par_pblobj pt p
   612 	  val itms =
   613 	    (case get_obj I pt p' of
   614 	      PblObj {meth = itms, ...} => itms
   615 	    | PrfObj _ => error "from_pblobj' NOT with PrfObj")
   616 	  val metID = get_obj g_metID pt p'
   617 	  val {srls, scr, ...} = Specify.get_met metID
   618   in
   619     if last_elem p = 0 (*nothing written to pt yet*)
   620     then
   621        let
   622          val ctxt = ContextC.initialise thy' (Model.vars_of itms)
   623          val (is, ctxt, scr) = init_pstate srls ctxt itms metID
   624 	     in (srls(*..\<in> is*), (is, ctxt), scr) end
   625     else (srls(*..\<in> is*), get_loc pt (p,p_), scr)
   626   end;
   627     
   628 (*.get the stactics and problems of a script as tacs
   629   instantiated with the current environment;
   630   l is the location which generated the given formula.*)
   631 (*WN.12.5.03: quick-and-dirty repair for listexpressions*)
   632 fun is_spec_pos Pbl = true
   633   | is_spec_pos Met = true
   634   | is_spec_pos _ = false;
   635 
   636 (* handle a leaf at the end of recursive descent:
   637    a leaf is either a tactic or an 'expr' in "let v = expr"
   638    where "expr" does not contain a tactic.
   639    Handling a leaf comprises
   640    (1) 'subst_stacexpr' substitute Env.upd_env and complete curried tactic
   641    (2) rewrite the leaf by 'srls'
   642 *)
   643 fun handle_leaf call thy srls (E, (a, v)) t =
   644       (*WN050916 'upd_env_opt' is a blind copy from previous version*)
   645     case Prog_Tac.subst_stacexpr E a v t of
   646 	    (a', Celem.STac stac) => (* Prog_Tac *)
   647 	      let val stac' =
   648             Rewrite.eval_listexpr_ (Celem.assoc_thy thy) srls (subst_atomic (Env.upd_env_opt E (a,v)) stac)
   649 	      in
   650           (if (! trace_script) 
   651 	         then tracing ("@@@ "^call^" leaf '" ^ Rule.term2str t ^ "' ---> STac '" ^ Rule.term2str stac ^ "'")
   652 	         else ();
   653 	         (a', Celem.STac stac'))
   654 	      end
   655     | (a', Celem.Expr lexpr) => (* Prog_Expr *)
   656 	      let val lexpr' =
   657             Rewrite.eval_listexpr_ (Celem.assoc_thy thy) srls (subst_atomic (Env.upd_env_opt E (a,v)) lexpr)
   658 	      in
   659           (if (! trace_script) 
   660 	         then tracing("@@@ "^call^" leaf '" ^ Rule.term2str t ^ "' ---> Expr '" ^ Rule.term2str lexpr' ^ "'")
   661 	         else ();
   662 	         (a', Celem.Expr lexpr')) (*lexpr' is the value of the Expr*)
   663 	      end;
   664 
   665 (*. fetch _all_ tactics from script .*)
   666 fun sel_rules _ (([],Res):pos') = 
   667     raise PTREE "no tactics applicable at the end of a calculation"
   668   | sel_rules pt (p,p_) =
   669     if is_spec_pos p_ 
   670     then [get_obj g_tac pt p]
   671     else
   672       let
   673         val pp = par_pblobj pt p;
   674         val thy' = get_obj g_domID pt pp;
   675         val thy = Celem.assoc_thy thy';
   676         val metID = get_obj g_metID pt pp;
   677         val metID' = if metID = Celem.e_metID then (thd3 o snd3) (get_obj g_origin pt pp) else metID
   678         val (sc, srls) = (case Specify.get_met metID' of
   679             {scr = Rule.Prog sc, srls, ...} => (sc, srls) | _ => error "sel_rules 1")
   680         val subst = get_istate pt (p, p_) |> Istate.the_pstate |> Istate.get_subst
   681       in map ((stac2tac pt thy) o Celem.rep_stacexpr o #2 o
   682   	    (handle_leaf "selrul" thy' srls subst)) (Auto_Prog.stacpbls sc)
   683   	  end;
   684 
   685 (* fetch tactics from script and filter _applicable_ tactics;
   686    in case of Rewrite_Set* go down to _atomic_ rewrite-tactics *)
   687 fun sel_appl_atomic_tacs _ (([], Res) : pos') = 
   688     raise PTREE "no tactics applicable at the end of a calculation"
   689   | sel_appl_atomic_tacs pt (p, p_) =
   690     if is_spec_pos p_ 
   691     then [get_obj g_tac pt p]
   692     else
   693       let
   694         val pp = par_pblobj pt p
   695         val thy' = get_obj g_domID pt pp
   696         val thy = Celem.assoc_thy thy'
   697         val metID = get_obj g_metID pt pp
   698         val metID' =
   699           if metID = Celem.e_metID 
   700           then (thd3 o snd3) (get_obj g_origin pt pp)
   701           else metID
   702         val (sc, srls, erls, ro) = (case Specify.get_met metID' of
   703             {scr = Rule.Prog sc, srls, erls, rew_ord' = ro, ...} => (sc, srls, erls, ro)
   704           | _ => error "sel_appl_atomic_tacs 1")
   705         val (env, (a, v)) = (case get_istate pt (p, p_) of
   706             Istate.Pstate pst => (Istate.get_subst pst) | _ => error "sel_appl_atomic_tacs 2")
   707         val alltacs = (*we expect at least 1 stac in a script*)
   708           map ((stac2tac pt thy) o Celem.rep_stacexpr o #2 o
   709            (handle_leaf "selrul" thy' srls (env, (a, v)))) (Auto_Prog.stacpbls sc)
   710         val f =
   711           (case p_ of Frm => get_obj g_form pt p | Res => (fst o (get_obj g_result pt)) p
   712           | _ => error "")
   713           (*WN071231 ? replace atomic_appl_tacs with applicable_in (ineff!) ?*)
   714       in ((gen_distinct Tactic.eq_tac) o flat o (map (Rtools.atomic_appl_tacs thy ro erls f))) alltacs end;
   715 (**)
   716 end
   717 (**)