src/Tools/isac/Interpret/li-tool.sml
author Walther Neuper <walther.neuper@jku.at>
Tue, 10 Mar 2020 13:25:00 +0100
changeset 59826 fac2f374d001
parent 59825 b40d5da06c59
child 59831 edf1643edde5
permissions -rw-r--r--
tuned
walther@59790
     1
(* Title:  interpreter for scripts
walther@59790
     2
   Author: Walther Neuper 2000
walther@59790
     3
   (c) due to copyright terms
walther@59790
     4
*)
walther@59790
     5
walther@59790
     6
signature LUCAS_INTERPRETER_TOOL =
walther@59790
     7
sig
walther@59790
     8
  datatype ass =
walther@59790
     9
    Ass of Tactic.T * term * Proof.context
walther@59790
    10
  | Ass_Weak of Tactic.T * term * Proof.context
walther@59790
    11
  | NotAss;
walther@59790
    12
  val associate: Ctree.ctree -> Proof.context -> (Tactic.T * term) -> ass
walther@59790
    13
  
walther@59790
    14
  val init_form : 'a -> Program.T -> (term * term) list -> term option
walther@59826
    15
  val init_pstate : Rule.rls -> Proof.context -> Model.itm list -> Celem.metID ->
walther@59826
    16
    Istate.T * Proof.context * Program.T
walther@59790
    17
walther@59790
    18
  val get_simplifier : Calc.T -> Rule.rls
walther@59816
    19
(*vvv initialise : Rule.theory'(*?!?*) -> Calc.T -> (Istate.T * Proof.context) * Program.T*)
walther@59802
    20
  val from_pblobj_or_detail' : Rule.theory' -> Ctree.pos' -> Ctree.ctree -> 
walther@59802
    21
    Rule.rls(*..\<in> ist \<rightarrow> REMOVE*) * (Istate.T * Proof.context) * Program.T
walther@59824
    22
walther@59823
    23
  val tac_from_prog : Ctree.ctree -> theory -> term -> Tactic.input
walther@59824
    24
  val check_leaf : string -> Proof.context -> Rule.rls -> (Env.T * (term option * term)) -> term -> 
walther@59790
    25
      Program.leaf * term option
walther@59790
    26
(* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
walther@59826
    27
  (*NONE*)
walther@59790
    28
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
walther@59790
    29
  val itms2args : 'a -> Celem.metID -> Model.itm list -> term list
walther@59790
    30
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
walther@59790
    31
end 
walther@59790
    32
walther@59790
    33
(* traces the leaves (ie. non-tactical nodes) of Prog found by find_next_step, see "and scr" *)   
walther@59790
    34
val trace_script = Unsynchronized.ref false; (* TODO: how are traces done in Isabelle? *)
walther@59790
    35
walther@59790
    36
(**)
walther@59790
    37
structure LItool(**): LUCAS_INTERPRETER_TOOL(**) =
walther@59790
    38
struct
walther@59790
    39
(**)
walther@59790
    40
open Ctree
walther@59790
    41
open Pos
walther@59790
    42
walther@59826
    43
(* determine the first tactic in case of a program with one argument (like simplification)
walther@59826
    44
  and without an initial Tactic.Take *)
walther@59826
    45
fun init_form thy (Rule.Prog prog) env =
walther@59826
    46
    (case Prog_Tac.get_first thy prog of
walther@59826
    47
      NONE => NONE 
walther@59826
    48
    | SOME prog_tac => SOME (subst_atomic env prog_tac))
walther@59790
    49
  | init_form _ _ _ = error "init_form: no match";
walther@59790
    50
walther@59790
    51
type dsc = typ; (* <-> nam..unknow in Descript.thy *)
walther@59790
    52
walther@59790
    53
(*.create the actual parameters (args) of script: their order 
walther@59790
    54
  is given by the order in met.pat .*)
walther@59790
    55
(*WN.5.5.03: ?: does this allow for different descriptions ???
walther@59790
    56
             ?: why not taken from formal args of script ???
walther@59790
    57
!: FIXXXME penv: push it here in itms2args into script-evaluation*)
walther@59790
    58
val errmsg = "ERROR: the guard is missing (#ppc in 'type met' added in prep_met)."
walther@59790
    59
fun errmsg2 d itms = ("itms2args: '" ^ Rule.term2str d ^ "' not in itms:\n" ^
walther@59790
    60
"itms:\n" ^ Model.itms2str_ @{context} itms)
walther@59790
    61
fun itms2args _ mI itms =
walther@59790
    62
  let
walther@59790
    63
    val mvat = Model.max_vt itms
walther@59790
    64
    fun okv mvat (_, vats, b, _, _) = member op = vats mvat andalso b
walther@59790
    65
    val itms = filter (okv mvat) itms
walther@59790
    66
    fun test_dsc d (_, _, _, _, itm_) = (d = Model.d_in itm_)
walther@59790
    67
    fun itm2arg itms (_,(d,_)) =
walther@59790
    68
        case find_first (test_dsc d) itms of
walther@59790
    69
          NONE => raise ERROR (errmsg2 d itms)
walther@59790
    70
        | SOME (_, _, _, _, itm_) => Model.penvval_in itm_
walther@59790
    71
      (*| SOME (_,_,_,_,itm_) => mk_arg thy (Model.d_in itm_) (ts_in itm_);
walther@59790
    72
            penv postponed; presently penv holds already Env.update for script*)
walther@59790
    73
    val pats = (#ppc o Specify.get_met) mI
walther@59790
    74
    val _ = if pats = [] then raise ERROR errmsg else ()
walther@59790
    75
  in (flat o (map (itm2arg itms))) pats end;
walther@59790
    76
walther@59824
    77
(* convert a Prog_Tac to Tactic.input *)
walther@59825
    78
fun tac_from_prog _ thy (Const ("Prog_Tac.Rewrite", _) $ thmID $ _) =
walther@59790
    79
    let
walther@59790
    80
      val tid = HOLogic.dest_string thmID
walther@59825
    81
    in (Tactic.Rewrite (tid, Rewrite.assoc_thm'' thy tid)) end
walther@59825
    82
  | tac_from_prog _ thy (Const ("Prog_Tac.Rewrite'_Inst", _) $ sub $ thmID $ _) =
walther@59790
    83
    let
walther@59790
    84
      val tid = HOLogic.dest_string thmID
walther@59825
    85
    in (Tactic.Rewrite_Inst (Selem.subst'_to_sube sub, (tid, Rewrite.assoc_thm'' thy tid))) end
walther@59825
    86
  | tac_from_prog _ _ (Const ("Prog_Tac.Rewrite'_Set",_) $ rls $ _) =
walther@59825
    87
     (Tactic.Rewrite_Set (HOLogic.dest_string rls))
walther@59825
    88
  | tac_from_prog _ _ (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ sub $ rls $ _) =
walther@59825
    89
      (Tactic.Rewrite_Set_Inst (Selem.subst'_to_sube sub, HOLogic.dest_string rls))
walther@59825
    90
  | tac_from_prog _ _ (Const ("Prog_Tac.Calculate", _) $ op_ $ _) =
walther@59825
    91
      (Tactic.Calculate (HOLogic.dest_string op_))
walther@59825
    92
  | tac_from_prog _ _ (Const ("Prog_Tac.Take", _) $ t) = (Tactic.Take (Rule.term2str t))
walther@59825
    93
  | tac_from_prog _ _ (Const ("Prog_Tac.Substitute", _) $ isasub $ _) =
walther@59825
    94
    (Tactic.Substitute ((Selem.subte2sube o TermC.isalist2list) isasub))
walther@59825
    95
  | tac_from_prog _ thy (Const("Prog_Tac.Check'_elementwise", _) $ _ $ 
walther@59790
    96
    (Const ("Set.Collect", _) $ Abs (_, _, pred))) =
walther@59825
    97
      (Tactic.Check_elementwise (Rule.term_to_string''' thy pred))
walther@59825
    98
  | tac_from_prog _ _ (Const("Prog_Tac.Or'_to'_List", _) $ _ ) = Tactic.Or_to_List
walther@59825
    99
  | tac_from_prog pt _ (ptac as Const ("Prog_Tac.SubProblem", _) $ _ $ _) =
walther@59825
   100
    fst (Sub_Problem.tac_from_prog pt ptac) (*might involve problem refinement etc*)
walther@59825
   101
  | tac_from_prog _ thy t = error ("stac2tac_ TODO: no match for " ^ Rule.term_to_string''' thy t);
walther@59790
   102
walther@59790
   103
datatype ass =
walther@59790
   104
    Ass of
walther@59790
   105
      Tactic.T        (* SubProblem gets args instantiated in associate     *)
walther@59790
   106
      * term          (* for itr_arg, result in ets                         *)
walther@59790
   107
      * Proof.context (* separate from Tactic.T like in locate_input_tactic *)
walther@59790
   108
  | Ass_Weak of Tactic.T * term * Proof.context
walther@59790
   109
  | NotAss;
walther@59790
   110
walther@59790
   111
(* check if tac_ is associated with stac.
walther@59790
   112
   Note: this is the only fun in "fun locate_input_tactic", which handles tactics individually.
walther@59790
   113
   Additional tasks: 
walther@59790
   114
  (1) to "Subproblem'" add "pors, hdl, fmz_, ctxt, f" TODO: ctxt <-?-> sig locate_input_tac
walther@59790
   115
  (2) check if term t (the result has been calculated from) in tac_
walther@59790
   116
   has been changed (see "datatype tac_"); if yes, recalculate result
walther@59790
   117
   TODO.WN120106 recalculate impl.only for Substitute'
walther@59790
   118
args
walther@59790
   119
  pt     : ctree for pushing the thy specified in rootpbl into subpbls
walther@59790
   120
  d      : unused (planned for data for comparison)
walther@59790
   121
  tac_   : from user (via applicable_in); to be compared with ...
walther@59790
   122
  stac   : found in program
walther@59790
   123
returns
walther@59790
   124
  Ass    : associated: e.g. thmID in stac = thmID in m
walther@59790
   125
                       +++ arg   in stac = arg   in m
walther@59790
   126
  Ass_Weak: weakly ass.:e.g. thmID in stac = thmID in m, //arg//
walther@59790
   127
  NotAss :             e.g. thmID in stac/=/thmID in m (not =)
walther@59790
   128
*)
walther@59790
   129
fun associate _ ctxt (m as Tactic.Rewrite_Inst'
walther@59790
   130
      (_, _, _, _, _, thm'' as (thmID, _), f, (f', asms')), stac) =
walther@59790
   131
    (case stac of
walther@59790
   132
	    (Const ("Prog_Tac.Rewrite'_Inst", _) $ _ $ thmID_ $ f_) =>
walther@59790
   133
	      if thmID = HOLogic.dest_string thmID_
walther@59790
   134
        then 
walther@59790
   135
	        if f = f_ 
walther@59790
   136
          then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   137
	        else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   138
	      else ((*tracing"3### associate ..NotAss";*) NotAss)
walther@59790
   139
    | (Const ("Prog_Tac.Rewrite'_Set'_Inst",_) $ _ $ rls_ $ f_) =>
walther@59790
   140
	      if Rtools.contains_rule (Rule.Thm thm'') (assoc_rls (HOLogic.dest_string rls_))
walther@59790
   141
        then if f = f_ then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   142
        else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   143
	      else NotAss
walther@59790
   144
    | _ => NotAss)
walther@59790
   145
  | associate _ ctxt (m as Tactic.Rewrite' (_, _, _, _, thm'' as (thmID, _), f, (f', asms')), stac) =
walther@59790
   146
    (case stac of
walther@59790
   147
	    (Const ("Prog_Tac.Rewrite", _) $ thmID_ $ f_) =>
walther@59790
   148
	      if thmID = HOLogic.dest_string thmID_
walther@59790
   149
        then 
walther@59790
   150
	        if f = f_
walther@59790
   151
          then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   152
	        else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   153
	      else NotAss
walther@59790
   154
    | (Const ("Prog_Tac.Rewrite'_Set", _) $ rls_ $ f_) =>
walther@59790
   155
	       if Rtools.contains_rule (Rule.Thm thm'') (assoc_rls (HOLogic.dest_string rls_))
walther@59790
   156
         then
walther@59790
   157
           if f = f_
walther@59790
   158
           then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   159
	         else Ass_Weak (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   160
	       else NotAss
walther@59790
   161
    | _ => NotAss)
walther@59790
   162
  | associate _ ctxt (m as Tactic.Rewrite_Set_Inst' (_, _, _, rls, f, (f', asms')),
walther@59790
   163
      (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ _ $ rls_ $ f_)) = 
walther@59790
   164
    if Rule.id_rls rls = HOLogic.dest_string rls_ 
walther@59790
   165
    then
walther@59790
   166
      if f = f_
walther@59790
   167
      then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   168
      else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   169
    else NotAss
walther@59790
   170
  | associate _ ctxt (m as Tactic.Detail_Set_Inst' (_, _, _, rls, f, (f', asms')),
walther@59790
   171
      (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ _ $ rls_ $ f_)) = 
walther@59790
   172
    if Rule.id_rls rls = HOLogic.dest_string rls_
walther@59790
   173
    then
walther@59790
   174
      if f = f_
walther@59790
   175
      then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   176
      else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   177
    else NotAss
walther@59790
   178
  | associate _ ctxt (m as Tactic.Rewrite_Set' (_, _, rls, f, (f', asms')),
walther@59790
   179
      (Const ("Prog_Tac.Rewrite'_Set", _) $ rls_ $ f_)) = 
walther@59790
   180
    if Rule.id_rls rls = HOLogic.dest_string rls_
walther@59790
   181
    then
walther@59790
   182
      if f = f_
walther@59790
   183
      then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   184
      else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   185
    else NotAss
walther@59790
   186
  | associate _ ctxt (m as Tactic.Detail_Set' (_, _, rls, f, (f', asms')),
walther@59790
   187
      (Const ("Prog_Tac.Rewrite'_Set", _) $ rls_ $ f_)) = 
walther@59790
   188
    if Rule.id_rls rls = HOLogic.dest_string rls_
walther@59790
   189
    then 
walther@59790
   190
      if f = f_
walther@59790
   191
      then Ass (m, f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   192
      else Ass_Weak (m ,f', ContextC.insert_assumptions asms' ctxt)
walther@59790
   193
    else NotAss
walther@59790
   194
  | associate _ ctxt (m as Tactic.Calculate' (_, op_, f, (f', _)), stac) =
walther@59790
   195
    (case stac of
walther@59790
   196
	    (Const ("Prog_Tac.Calculate",_) $ op__ $ f_) =>
walther@59790
   197
	      if op_ = HOLogic.dest_string op__
walther@59790
   198
        then
walther@59790
   199
          if f = f_
walther@59790
   200
          then Ass (m, f', ctxt)
walther@59790
   201
          else Ass_Weak (m ,f', ctxt)
walther@59790
   202
	      else NotAss
walther@59790
   203
    | (Const ("Prog_Tac.Rewrite'_Set'_Inst", _) $ _ $ rls_ $ f_)  =>
walther@59790
   204
        let val thy = Celem.assoc_thy "Isac_Knowledge";
walther@59790
   205
        in
walther@59790
   206
          if Rtools.contains_rule (Rule.Num_Calc (assoc_calc' thy op_ |> snd)) 
walther@59790
   207
            (assoc_rls (HOLogic.dest_string rls_))
walther@59790
   208
          then
walther@59790
   209
            if f = f_
walther@59790
   210
            then Ass (m, f', ctxt)
walther@59790
   211
            else Ass_Weak (m ,f', ctxt)
walther@59790
   212
          else NotAss
walther@59790
   213
        end
walther@59790
   214
    | (Const ("Prog_Tac.Rewrite'_Set",_) $ rls_ $ f_) =>
walther@59790
   215
        let val thy = Celem.assoc_thy "Isac_Knowledge";
walther@59790
   216
        in
walther@59790
   217
          if Rtools.contains_rule (Rule.Num_Calc (assoc_calc' thy op_ |> snd))
walther@59790
   218
            (assoc_rls (HOLogic.dest_string rls_))
walther@59790
   219
          then
walther@59790
   220
            if f = f_
walther@59790
   221
            then Ass (m, f', ctxt)
walther@59790
   222
            else Ass_Weak (m ,f', ctxt)
walther@59790
   223
          else NotAss
walther@59790
   224
        end
walther@59790
   225
    | _ => NotAss)
walther@59790
   226
  | associate _ ctxt (m as Tactic.Check_elementwise' (consts, _, (consts_chkd, _)),
walther@59790
   227
      (Const ("Prog_Tac.Check'_elementwise",_) $ consts' $ _)) =
walther@59790
   228
    if consts = consts'
walther@59790
   229
    then Ass (m, consts_chkd, ctxt)
walther@59790
   230
    else NotAss
walther@59790
   231
  | associate _ ctxt (m as Tactic.Or_to_List' (_, list), (Const ("Prog_Tac.Or'_to'_List", _) $ _)) =
walther@59790
   232
    Ass (m, list, ctxt)
walther@59790
   233
  | associate _ ctxt (m as Tactic.Take' term, (Const ("Prog_Tac.Take", _) $ _)) = Ass (m, term, ctxt)
walther@59790
   234
  | associate _ ctxt (m as Tactic.Substitute' (ro, erls, subte, f, f'),
walther@59790
   235
      (Const ("Prog_Tac.Substitute", _) $ _ $ t)) =
walther@59790
   236
	  if f = t then Ass (m, f', ctxt)
walther@59790
   237
	  else (*compare | applicable_in (p,p_) pt (m as Substitute sube)*)
walther@59790
   238
		  if foldl and_ (true, map TermC.contains_Var subte)
walther@59790
   239
		  then
walther@59790
   240
		    let val t' = subst_atomic (map HOLogic.dest_eq subte (*TODO subte2subst*)) t
walther@59790
   241
		    in if t = t' then error "associate: Substitute' not applicable to val of Expr"
walther@59790
   242
		       else Ass (Tactic.Substitute' (ro, erls, subte, t, t'), t', ctxt)
walther@59790
   243
		    end
walther@59790
   244
		  else (case Rewrite.rewrite_terms_ (Rule.Isac ()) ro erls subte t of
walther@59790
   245
		         SOME (t', _) =>  Ass (Tactic.Substitute' (ro, erls, subte, t, t'), t', ctxt)
walther@59790
   246
		       | NONE => error "associate: Substitute' not applicable to val of Expr")
walther@59817
   247
  | associate pt ctxt (Tactic.Subproblem' ((domID, pblID, _), _, _, _, _, _),
walther@59817
   248
      (stac as Const ("Prog_Tac.SubProblem", _) $ _ $ _)) =
walther@59823
   249
    (case Sub_Problem.tac_from_prog pt stac of
walther@59817
   250
      (_, tac as Tactic.Subproblem' ((dI, pI, _), _, _, _, _, f)) =>
walther@59817
   251
        if domID = dI andalso pblID = pI
walther@59817
   252
        then Ass (tac, f, ctxt)
walther@59817
   253
        else NotAss
walther@59817
   254
    | _ => raise ERROR ("associate: uncovered case"))
walther@59790
   255
  | associate _ _ (m, _) = 
walther@59790
   256
    (if (!trace_script) 
walther@59790
   257
     then tracing("@@@ the 'tac_' proposed to apply does NOT match the leaf found in the script:\n"
walther@59790
   258
		   ^ "@@@ tac_ = " ^ Tactic.string_of m)
walther@59790
   259
     else ();
walther@59790
   260
    NotAss);
walther@59790
   261
walther@59790
   262
(* create the initial interpreter state
walther@59790
   263
  from the items of the guard and the formal arguments of the partial_function.
walther@59790
   264
Note on progression from (a) type fmz_ \<longrightarrow> (e) arguments of the partial_function:
walther@59790
   265
  (a) fmz is given by a math author
walther@59790
   266
  (b) fmz_ is transformed to ori list as a prerequisite for efficient interactive modelling
walther@59790
   267
  (c) modelling creates an itm list from ori list + possible user input
walther@59790
   268
  (d) specifying a theory might add some items and create a guard for the partial_function
walther@59790
   269
  (e) fun relate_args creates an environment for evaluating the partial_function.
walther@59790
   270
Note on sequence-relation (a) -- (e), i.e. the (formal) arguments of the partial_function:
walther@59790
   271
  * Since the arguments of the partial_function have no description (see Descript.thy),
walther@59790
   272
    (e) depends on the sequence in fmz_ and on the types of the formal arguments.
walther@59790
   273
  * pairing formal arguments with itm's follows the sequence
walther@59790
   274
  * Thus the resulting sequence-relation can be ambiguous.
walther@59790
   275
  * Ambiguities are done by rearranging fmz_ or the formal arguments.
walther@59790
   276
  * The latter is easier, albeit not optimal: a fmz_ can be used by different partial_functions.
walther@59790
   277
  *)
walther@59790
   278
local
walther@59790
   279
val errmsg = "ERROR: found no actual arguments for prog. of "
walther@59790
   280
fun msg_miss sc metID caller f formals actuals =
walther@59790
   281
  "ERROR in creating the environment from formal args. of partial_function \"" ^ fst (Program.get_fun_id sc) ^ "\"\n" ^
walther@59790
   282
	"and the actual args., ie. items of the guard of \"" ^ Celem.metID2str metID ^ "\" by \"" ^ caller ^ "\":\n" ^
walther@59790
   283
	"formal arg \"" ^ Rule.term2str f ^ "\" doesn't mach an actual arg.\n" ^
walther@59790
   284
	"with:\n" ^
walther@59790
   285
	(string_of_int o length) formals ^ " formal args: " ^ Rule.terms2str formals ^ "\n" ^
walther@59790
   286
	(string_of_int o length) actuals ^ " actual args: " ^ Rule.terms2str actuals
walther@59790
   287
fun msg_miss_type sc metID f formals actuals =
walther@59790
   288
  "ERROR in creating the environment from formal args. of partial_function \"" ^ fst (Program.get_fun_id sc) ^ "\"\n" ^
walther@59790
   289
	"and the actual args., ie. items of the guard of \"" ^ Celem.metID2str metID ^ "\" by \"assoc_by_type\":\n" ^
walther@59790
   290
	"formal arg \"" ^ Rule.term2str f ^ "\" of type \"" ^ Rule.type2str (type_of f) ^
walther@59790
   291
  "\" doesn't mach an actual arg.\nwith:\n" ^
walther@59790
   292
	(string_of_int o length) formals ^ " formal args: " ^ Rule.terms2str formals ^ "\n" ^
walther@59790
   293
	(string_of_int o length) actuals ^ " actual args: " ^ Rule.terms2str actuals ^ "\n" ^
walther@59790
   294
  "   with types: " ^ (strs2str o (map (Rule.type2str o type_of))) actuals
walther@59790
   295
fun msg_ambiguous sc metID f aas formals actuals =
walther@59790
   296
  "AMBIGUITY in creating the environment from formal args. of partial_function \"" ^ fst (Program.get_fun_id sc) ^ "\"\n" ^
walther@59790
   297
	"and the actual args., ie. items of the guard of \"" ^ Celem.metID2str metID ^ "\" by \"assoc_by_type\":\n" ^
walther@59790
   298
  "formal arg. \"" ^ Rule.term2str f ^ "\" type-matches with several..."  ^
walther@59790
   299
  "actual args. \"" ^ Rule.terms2str aas ^ "\"\n" ^
walther@59790
   300
  "selected \"" ^ Rule.term2str (hd aas) ^ "\"\n" ^
walther@59790
   301
	"with\n" ^
walther@59790
   302
	"formals: " ^ Rule.terms2str formals ^ "\n" ^
walther@59790
   303
	"actuals: " ^ Rule.terms2str actuals
walther@59790
   304
fun trace_init metID =
walther@59790
   305
  if (!trace_script) 
walther@59790
   306
  then tracing("@@@ program " ^ strs2str metID)
walther@59790
   307
  else ();
walther@59790
   308
in
walther@59790
   309
fun init_pstate srls ctxt itms metID =
walther@59790
   310
  let
walther@59790
   311
    val itms = Specify.hack_until_review_Specify_2 metID itms
walther@59790
   312
    val actuals = itms2args (Proof_Context.theory_of ctxt) metID itms
walther@59790
   313
    val _ = if actuals <> [] then () else raise ERROR (errmsg ^ strs2str' metID)
walther@59790
   314
    val (scr, sc) = (case (#scr o Specify.get_met) metID of
walther@59790
   315
           scr as Rule.Prog sc => (trace_init metID; (scr, sc))
walther@59790
   316
       | _ => raise ERROR ("init_pstate with " ^ Celem.metID2str metID))
walther@59790
   317
    val formals = Program.formal_args sc    
walther@59790
   318
    fun assoc_by_type f aa =
walther@59790
   319
      case filter (curry (fn (f, a) => type_of f = type_of a) f) aa of
walther@59790
   320
        [] => error (msg_miss_type sc metID f formals actuals)
walther@59790
   321
      | [a] => (f, a)
walther@59790
   322
      | aas as (a :: _) => (writeln (msg_ambiguous sc metID f aas formals actuals); (f, a));
walther@59790
   323
	  fun relate_args _ (f::_)  [] = error (msg_miss sc metID "relate_args" f formals actuals)
walther@59790
   324
	    | relate_args env [] _ = env (*may drop Find?*)
walther@59790
   325
	    | relate_args env (f::ff) (aas as (a::aa)) = 
walther@59790
   326
	      if type_of f = type_of a 
walther@59790
   327
	      then relate_args (env @ [(f, a)]) ff aa
walther@59790
   328
        else
walther@59790
   329
          let val (f, a) = assoc_by_type f aas
walther@59790
   330
          in relate_args (env @ [(f, a)]) ff (remove op = a aas) end
walther@59790
   331
    val {pre, prls, ...} = Specify.get_met metID;
walther@59790
   332
    val pres = Stool.check_preconds (Proof_Context.theory_of ctxt) prls pre itms |> map snd;
walther@59790
   333
    val ctxt = ctxt |> ContextC.insert_assumptions pres;
walther@59790
   334
    val ist = Istate.e_pstate
walther@59790
   335
      |> Istate.set_eval srls
walther@59790
   336
      |> Istate.set_env_true (relate_args [] formals actuals)
walther@59790
   337
  in
walther@59790
   338
    (Istate.Pstate ist, ctxt, scr)
walther@59790
   339
  end;
walther@59790
   340
end (*local*)
walther@59790
   341
walther@59790
   342
fun get_simplifier (pt, (p, _)) =
walther@59790
   343
  let
walther@59790
   344
    val p' = Ctree.par_pblobj pt p
walther@59790
   345
	  val metID = Ctree.get_obj Ctree.g_metID pt p'
walther@59790
   346
	  val {srls, ...} = Specify.get_met metID
walther@59790
   347
  in srls end
walther@59790
   348
walther@59790
   349
(* decide, where to get program/istate from:
walther@59802
   350
   (* 1 *) from PblObj: at begin of program if no init_form
walther@59790
   351
   (* 2 *) from PblObj/PrfObj: if Prog_Tac is in the middle of the program
walther@59802
   352
   (* 3 *) from PrfOb: in case of Math_Engine.detailstep
walther@59802
   353
 *)
walther@59802
   354
fun from_pblobj_or_detail' thy (p, p_) pt =
walther@59803
   355
  if Pos.on_specification p_
walther@59803
   356
  then case get_obj g_env (*!DEPRECATED!*) pt p of                                         (* 1 *)
walther@59802
   357
      NONE => error "from_pblobj_or_detail': no istate"
walther@59802
   358
    | SOME (Istate.Pstate pst, ctxt) =>
walther@59802
   359
        let
walther@59802
   360
          val metID = get_obj g_metID pt p
walther@59802
   361
          val {srls, ...} = Specify.get_met metID
walther@59802
   362
        in
walther@59802
   363
          (srls, (Istate.Pstate (Istate.set_eval srls pst), ctxt), (#scr o Specify.get_met) metID)
walther@59802
   364
        end
walther@59802
   365
    | _ => raise ERROR "from_pblobj_or_detail': unexpected result from g_env"
walther@59790
   366
  else
walther@59790
   367
    let val (pbl, p', rls') = par_pbl_det pt p
walther@59790
   368
    in if pbl
walther@59790
   369
       then (*if last_elem p = 0 nothing written to pt yet*)                               (* 2 *)
walther@59790
   370
         let
walther@59790
   371
	         val metID = get_obj g_metID pt p'
walther@59790
   372
	         val {srls, ...} = Specify.get_met metID
walther@59790
   373
	         val (is, ctxt) =
walther@59790
   374
	           case get_loc pt (p, p_) of
walther@59790
   375
	              (Istate.Pstate ist, ctxt) => (Istate.Pstate (Istate.set_eval srls ist), ctxt)
walther@59790
   376
	           | _ => raise ERROR "from_pblobj_or_detail': unexpected result from get_loc"
walther@59790
   377
	       in (srls, (is, ctxt), (#scr o Specify.get_met) metID) end
walther@59802
   378
       else                                                                                (* 3 *)
walther@59802
   379
         (Rule.e_rls(*!!!*),
walther@59802
   380
         get_loc pt (p, p_),
walther@59802
   381
         Rule.Prog (Auto_Prog.gen (Celem.assoc_thy thy) (get_last_formula (pt, (p, p_))) rls'))
walther@59790
   382
    end
walther@59790
   383
walther@59816
   384
(* handle a leaf at the end of recursive descent; a leaf is either a Prog_Tac or a Prog_Expr.
walther@59816
   385
  TODO: what is a' ??? *)
walther@59790
   386
fun check_leaf call ctxt srls (E, (a, v)) t =
walther@59790
   387
    case Prog_Tac.eval_leaf E a v t of
walther@59790
   388
	    (Program.Tac stac, a') =>
walther@59790
   389
	      let val stac' =
walther@59790
   390
            Rewrite.eval_prog_expr (Proof_Context.theory_of ctxt) srls 
walther@59801
   391
              (subst_atomic (Env.update_opt E (a, v)) stac)
walther@59790
   392
	      in
walther@59790
   393
          (if (! trace_script) 
walther@59790
   394
	         then tracing ("@@@ " ^ call ^ " leaf '" ^ Rule.term2str t ^ "' ---> Tac '" ^ Rule.term2str stac ^ "'")
walther@59790
   395
	         else ();
walther@59790
   396
	         (Program.Tac stac', a'))
walther@59790
   397
	      end
walther@59790
   398
    | (Program.Expr lexpr, a') =>
walther@59790
   399
	      let val lexpr' =
walther@59801
   400
            Rewrite.eval_prog_expr (Proof_Context.theory_of ctxt) srls
walther@59801
   401
              (subst_atomic (Env.update_opt E (a, v)) lexpr)
walther@59790
   402
	      in
walther@59790
   403
          (if (! trace_script) 
walther@59801
   404
	         then tracing("@@@ " ^ call ^ " leaf '" ^ Rule.term2str t ^ "' ---> Expr '" ^ Rule.term2str lexpr' ^ "'")
walther@59790
   405
	         else ();
walther@59800
   406
	         (Program.Expr lexpr', a'))
walther@59790
   407
	      end;
walther@59790
   408
walther@59790
   409
(**)end(**)