src/Tools/isac/Interpret/appl.sml
author Walther Neuper <wneuper@ist.tugraz.at>
Thu, 02 Feb 2017 06:32:30 +0100
changeset 59305 370b0001b02a
parent 59304 185c1f9c844b
child 59306 a2baef20c741
permissions -rw-r--r--
tuned
wneuper@59305
     1
(* Title:  Is a tacitc applicable ?
wneuper@59305
     2
           TODO: allocate these functions in appropriate structures
wneuper@59305
     3
   Author: Walther Neuper
wneuper@59305
     4
   (c) due to copyright terms
neuper@37936
     5
*)
wneuper@59272
     6
wneuper@59284
     7
signature APPLICABLE =
wneuper@59284
     8
sig
wneuper@59284
     9
  exception PTREE of string
wneuper@59302
    10
  val applicable_in : Ctree.pos' -> Ctree.ctree -> Tac.tac -> Chead.appl
wneuper@59286
    11
(* ---- for tests only: made visible in order to remove the warning --------------------------- *)
wneuper@59302
    12
  val tac2tac_ : Ctree.ctree -> Ctree.pos' -> Tac.tac -> Tac.tac_
wneuper@59299
    13
(*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
wneuper@59285
    14
  val mk_set : 'a -> ctree -> pos -> term -> term -> term * term list
wneuper@59299
    15
( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
wneuper@59284
    16
end
wneuper@59285
    17
wneuper@59284
    18
(**)
wneuper@59284
    19
structure Applicable(**): APPLICABLE(**) =
wneuper@59272
    20
struct
wneuper@59284
    21
(**)
wneuper@59276
    22
open Ctree
wneuper@59272
    23
wneuper@59285
    24
fun rew_info (Rls {erls, rew_ord = (rew_ord', _), calc = ca, ...}) =
wneuper@59285
    25
    (rew_ord', erls, ca)
wneuper@59285
    26
  | rew_info (Seq {erls, rew_ord = (rew_ord', _), calc = ca, ...}) =
wneuper@59285
    27
    (rew_ord', erls, ca)
wneuper@59285
    28
  | rew_info (Rrls {erls, rew_ord = (rew_ord', _), calc = ca, ...}) =
wneuper@59285
    29
    (rew_ord', erls, ca)
wneuper@59285
    30
  | rew_info rls = error ("rew_info called with '" ^ rls2str rls ^ "'");
neuper@37906
    31
neuper@37906
    32
(*FIXME.3.4.03:re-organize from_pblobj_or_detail_thm after rls' --> rls*)
wneuper@59285
    33
fun from_pblobj_or_detail_thm _ p pt = 
neuper@52155
    34
  let 
neuper@52155
    35
    val (pbl, p', rls') = par_pbl_det pt p
neuper@52155
    36
  in 
neuper@52155
    37
    if pbl
neuper@52155
    38
    then 
neuper@52155
    39
      let 
neuper@52155
    40
        val thy' = get_obj g_domID pt p'
wneuper@59269
    41
        val {rew_ord', erls, ...} = Specify.get_met (get_obj g_metID pt p')              
neuper@52155
    42
	    in ("OK", thy', rew_ord', erls, false) end
neuper@52155
    43
     else 
neuper@52155
    44
      let
neuper@52155
    45
        val thy' = get_obj g_domID pt (par_pblobj pt p)
neuper@52155
    46
		    val (rew_ord', erls, _) = rew_info rls'
wneuper@59285
    47
		  in ("OK", thy', rew_ord', erls, false) end
neuper@52155
    48
  end;
neuper@37906
    49
(*FIXME.3.4.03:re-organize from_pblobj_or_detail_calc after rls' --> rls*)
neuper@37906
    50
fun from_pblobj_or_detail_calc scrop p pt = 
neuper@52155
    51
  let
wneuper@59285
    52
    val (pbl, p', rls') = par_pbl_det pt p
neuper@52155
    53
  in
neuper@52155
    54
    if pbl
neuper@52155
    55
    then
neuper@52155
    56
      let
neuper@52155
    57
        val thy' = get_obj g_domID pt p'
wneuper@59285
    58
        val {calc = scr_isa_fns, ...} = Specify.get_met (get_obj g_metID pt p')
neuper@52155
    59
        val opt = assoc (scr_isa_fns, scrop)
neuper@52155
    60
	    in
neuper@52155
    61
	      case opt of
wneuper@59285
    62
	        SOME isa_fn => ("OK", thy', isa_fn)
neuper@52155
    63
	      | NONE => ("applicable_in Calculate: unknown '" ^ scrop ^ "'", "", ("", e_evalfn))
neuper@52155
    64
	    end
neuper@52155
    65
    else 
neuper@52155
    66
		  let
neuper@52155
    67
		    val thy' = get_obj g_domID pt (par_pblobj pt p);
wneuper@59285
    68
		    val (_, _,(*_,*)scr_isa_fns) = rew_info rls'(*rls*)
neuper@52155
    69
		  in
neuper@52155
    70
		    case assoc (scr_isa_fns, scrop) of
neuper@52155
    71
		      SOME isa_fn => ("OK",thy',isa_fn)
neuper@52155
    72
		    | NONE => ("applicable_in Calculate: unknown '" ^ scrop ^ "'", "", ("", e_evalfn))
neuper@52155
    73
		  end
neuper@52155
    74
  end;
neuper@37906
    75
wneuper@59285
    76
(*for Check_elementwise in applicable_in: [x=1,..] Assumptions -> (x,0<=x&..)*)
wneuper@59285
    77
fun mk_set _(*thy*) _ _ (Const ("List.list.Nil", _)) _ = (e_term, [])
wneuper@59285
    78
  | mk_set _ pt p (Const ("Tools.UniversalList", _)) pred =
wneuper@59285
    79
    (e_term, if pred <> Const ("Script.Assumptions", bool)
wneuper@59285
    80
	     then [pred] 
wneuper@59285
    81
	     else get_assumptions_ pt (p, Res))
wneuper@59285
    82
  | mk_set _ pt p (Const ("List.list.Cons",_) $ eq $ _) pred =
wneuper@59285
    83
    let
wneuper@59285
    84
      val (bdv,_) = HOLogic.dest_eq eq;
wneuper@59285
    85
      val pred = if pred <> Const ("Script.Assumptions",bool)
wneuper@59285
    86
  		  then [pred] 
wneuper@59285
    87
  	    else get_assumptions_ pt (p, Res)
wneuper@59285
    88
    in (bdv, pred) end
wneuper@59285
    89
  | mk_set _ _ _ l _ = 
wneuper@59285
    90
    error ("check_elementwise: no set " ^ term2str l);
neuper@37906
    91
wneuper@59285
    92
(* check a list (/set) of constants [c_1,..,c_n] for c_i:set (: in)*)
neuper@37906
    93
fun check_elementwise thy erls all_results (bdv, asm) =
wneuper@59285
    94
  let   (*bdv extracted from ~~~~~~~~~~~ in mk_set already*)
wneuper@59285
    95
	  fun check sub =
neuper@37906
    96
	    let val inst_ = map (subst_atomic [sub]) asm
neuper@37906
    97
	    in case eval__true thy 1 inst_ [] erls of
wneuper@59285
    98
		    (asm', true) => ([HOLogic.mk_eq sub], asm')
wneuper@59285
    99
		  | (_, false) => ([],[])
neuper@37906
   100
	    end;
wneuper@59285
   101
  	val c' = isalist2list all_results
wneuper@59285
   102
  	val c'' = map (snd o HOLogic.dest_eq) c' (*assumes [x=1,x=2,..]*)
wneuper@59285
   103
  	val subs = map (pair bdv) c''
wneuper@59285
   104
  in
wneuper@59285
   105
    if asm = []
wneuper@59285
   106
    then (all_results, [])
wneuper@59285
   107
    else ((apfst ((list2isalist bool) o flat)) o (apsnd flat) o split_list o (map check)) subs
wneuper@59285
   108
  end;
neuper@37906
   109
wneuper@59285
   110
(* for Tac-dummies in root-equ only: skip str until "("*)
wneuper@59285
   111
fun split_dummy str = 
wneuper@59285
   112
  let
wneuper@59285
   113
    fun scan s' [] = (implode s', "")
wneuper@59285
   114
      | scan s' (s :: ss) = if s = " " then (implode s', implode  ss)
wneuper@59285
   115
			  else scan (s' @ [s]) ss;
wneuper@59285
   116
  in ((scan []) o Symbol.explode) str end;
neuper@37906
   117
wneuper@59285
   118
(* applicability of a tacic wrt. a calc-state (ctree,pos').
neuper@41980
   119
   additionally used by next_tac in the script-interpreter for script-tacs.
neuper@37906
   120
   tests for applicability are so expensive, that results (rewrites!)
wneuper@59285
   121
   are kept in the return-value of 'type tac_'                            *)
wneuper@59302
   122
fun applicable_in _ _ (Tac.Init_Proof (ct', spec)) = Chead.Appl (Tac.Init_Proof' (ct', spec))
wneuper@59304
   123
  | applicable_in (p, p_) pt Tac.Model_Problem = 
neuper@41975
   124
      if not (is_pblobj (get_obj I pt p)) orelse p_ = Res
wneuper@59304
   125
      then Chead.Notappl ((Tac.tac2str Tac.Model_Problem) ^ " not for pos " ^ (pos'2str (p, p_)))
neuper@41975
   126
      else 
neuper@41975
   127
        let 
wneuper@59285
   128
          val pI' = case get_obj I pt p of
wneuper@59285
   129
            PblObj {origin = (_, (_, pI', _),_), ...} => pI'
wneuper@59285
   130
          | _ => error "applicable_in Init_Proof: uncovered case get_obj"
wneuper@59285
   131
	        val {ppc, ...} = Specify.get_pbt pI'
wneuper@59271
   132
	        val pbl = Generate.init_pbl ppc
wneuper@59302
   133
        in Chead.Appl (Tac.Model_Problem' (pI', pbl, [])) end
wneuper@59302
   134
  | applicable_in (p, p_) pt (Tac.Refine_Tacitly pI) = 
neuper@41975
   135
      if not (is_pblobj (get_obj I pt p)) orelse p_ = Res
wneuper@59302
   136
      then Chead.Notappl ((Tac.tac2str (Tac.Refine_Tacitly pI)) ^ " not for pos " ^ (pos'2str (p, p_)))
neuper@41975
   137
      else 
neuper@41975
   138
        let 
wneuper@59285
   139
          val oris = case get_obj I pt p of
wneuper@59285
   140
            PblObj {origin = (oris, _, _), ...} => oris
wneuper@59285
   141
          | _ => error "applicable_in Refine_Tacitly: uncovered case get_obj"
wneuper@59285
   142
        in
wneuper@59285
   143
          case Specify.refine_ori oris pI of
wneuper@59285
   144
	          SOME pblID => 
wneuper@59302
   145
	            Chead.Appl (Tac.Refine_Tacitly' (pI, pblID, e_domID, e_metID, [](*filled in specify*)))
wneuper@59302
   146
	        | NONE => Chead.Notappl ((Tac.tac2str (Tac.Refine_Tacitly pI)) ^ " not applicable")
neuper@41975
   147
        end
wneuper@59302
   148
  | applicable_in (p, p_) pt (Tac.Refine_Problem pI) = 
wneuper@59285
   149
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   150
    then Chead.Notappl ((Tac.tac2str (Tac.Refine_Problem pI)) ^ " not for pos "^(pos'2str (p, p_)))
wneuper@59285
   151
    else
wneuper@59285
   152
      let
wneuper@59285
   153
        val (dI, dI', itms) = case get_obj I pt p of
wneuper@59285
   154
            PblObj {origin= (_, (dI, _, _), _), spec= (dI', _, _), probl = itms, ...}
wneuper@59285
   155
              => (dI, dI', itms)
wneuper@59285
   156
          | _ => error "applicable_in Refine_Problem: uncovered case get_obj"
wneuper@59285
   157
      	val thy = if dI' = e_domID then dI else dI';
wneuper@59285
   158
      in
wneuper@59285
   159
        case Specify.refine_pbl (assoc_thy thy) pI itms of
wneuper@59302
   160
          NONE => Chead.Notappl ((Tac.tac2str (Tac.Refine_Problem pI)) ^ " not applicable")
wneuper@59285
   161
	      | SOME (rf as (pI', _)) =>
wneuper@59285
   162
      	   if pI' = pI
wneuper@59302
   163
      	   then Chead.Notappl ((Tac.tac2str (Tac.Refine_Problem pI)) ^ " not applicable")
wneuper@59302
   164
      	   else Chead.Appl (Tac.Refine_Problem' rf)
neuper@37906
   165
    end
wneuper@59285
   166
  (*the specify-tacs have cterm' instead term: parse+error here!!!: see appl_add*)  
wneuper@59302
   167
  | applicable_in (p, p_) pt (Tac.Add_Given ct') = 
wneuper@59285
   168
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   169
    then Chead.Notappl ((Tac.tac2str (Tac.Add_Given ct')) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   170
    else Chead.Appl (Tac.Add_Given' (ct', [(*filled in specify_additem*)]))
wneuper@59285
   171
      (*Add_.. should reject (dsc //) (see fmz=[] in sqrt*)
wneuper@59302
   172
  | applicable_in (p, p_) pt (Tac.Del_Given ct') =
wneuper@59285
   173
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   174
    then Chead.Notappl ((Tac.tac2str (Tac.Del_Given ct')) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   175
    else Chead.Appl (Tac.Del_Given' ct')
wneuper@59302
   176
  | applicable_in (p, p_) pt (Tac.Add_Find ct') =                   
wneuper@59285
   177
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   178
    then Chead.Notappl ((Tac.tac2str (Tac.Add_Find ct')) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   179
    else Chead.Appl (Tac.Add_Find' (ct', [(*filled in specify_additem*)]))
wneuper@59302
   180
  | applicable_in (p, p_) pt (Tac.Del_Find ct') =
wneuper@59285
   181
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   182
    then Chead.Notappl ((Tac.tac2str (Tac.Del_Find ct')) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   183
    else Chead.Appl (Tac.Del_Find' ct')
wneuper@59302
   184
  | applicable_in (p, p_) pt (Tac.Add_Relation ct') =               
wneuper@59285
   185
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   186
    then Chead.Notappl ((Tac.tac2str (Tac.Add_Relation ct')) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   187
    else Chead.Appl (Tac.Add_Relation' (ct', [(*filled in specify_additem*)]))
wneuper@59302
   188
  | applicable_in (p, p_) pt (Tac.Del_Relation ct') =
wneuper@59285
   189
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   190
    then Chead.Notappl ((Tac.tac2str (Tac.Del_Relation ct')) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   191
    else Chead.Appl (Tac.Del_Relation' ct')
wneuper@59302
   192
  | applicable_in (p, p_) pt (Tac.Specify_Theory dI) =              
wneuper@59285
   193
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   194
    then Chead.Notappl ((Tac.tac2str (Tac.Specify_Theory dI)) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   195
    else Chead.Appl (Tac.Specify_Theory' dI)
wneuper@59302
   196
  | applicable_in (p, p_) pt (Tac.Specify_Problem pID) = 
wneuper@59285
   197
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   198
    then Chead.Notappl ((Tac.tac2str (Tac.Specify_Problem pID)) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59285
   199
    else
wneuper@59285
   200
      let
wneuper@59285
   201
		    val (oris, dI, pI, dI', pI', itms) = case get_obj I pt p of
wneuper@59285
   202
		      PblObj {origin = (oris, (dI, pI, _), _), spec = (dI', pI', _), probl = itms, ...}
wneuper@59285
   203
		        => (oris, dI, pI, dI', pI', itms)
wneuper@59285
   204
        | _ => error "applicable_in Specify_Problem: uncovered case get_obj"
wneuper@59285
   205
	      val thy = assoc_thy (if dI' = e_domID then dI else dI');
wneuper@59285
   206
        val {ppc, where_, prls, ...} = Specify.get_pbt pID;
wneuper@59285
   207
        val pbl = if pI' = e_pblID andalso pI = e_pblID
wneuper@59285
   208
          then (false, (Generate.init_pbl ppc, []))
wneuper@59285
   209
          else Specify.match_itms_oris thy itms (ppc, where_, prls) oris;
wneuper@59285
   210
       in
wneuper@59302
   211
        Chead.Appl (Tac.Specify_Problem' (pID, pbl))
wneuper@59285
   212
      end
wneuper@59302
   213
  | applicable_in (p, p_) pt (Tac.Specify_Method mID) =              
wneuper@59285
   214
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res               
wneuper@59302
   215
    then Chead.Notappl ((Tac.tac2str (Tac.Specify_Method mID)) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   216
    else Chead.Appl (Tac.Specify_Method' (mID, [(*filled in specify*)], [(*filled in specify*)]))
wneuper@59302
   217
  | applicable_in (p, p_) pt (Tac.Apply_Method mI) =                
wneuper@59285
   218
    if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
wneuper@59302
   219
    then Chead.Notappl ((Tac.tac2str (Tac.Apply_Method mI)) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59285
   220
    else
wneuper@59285
   221
      let
wneuper@59285
   222
        val (dI, pI, probl, ctxt) = case get_obj I pt p of
wneuper@59285
   223
          PblObj {origin = (_, (dI, pI, _), _), probl, ctxt, ...} => (dI, pI, probl, ctxt)
wneuper@59285
   224
        | _ => error "applicable_in Apply_Method: uncovered case get_obj"
wneuper@59285
   225
        val {where_, ...} = Specify.get_pbt pI
wneuper@59285
   226
        val pres = map (mk_env probl |> subst_atomic) where_
wneuper@59285
   227
        val ctxt = if is_e_ctxt ctxt
wneuper@59285
   228
          then assoc_thy dI |> Proof_Context.init_global |> insert_assumptions pres
wneuper@59285
   229
          else ctxt
wneuper@59285
   230
       (*TODO.WN110416 here do evalprecond according to fun check_preconds'
wneuper@59285
   231
       and then decide on Chead.Notappl/Appl accordingly once more.
wneuper@59285
   232
       Implement after all tests are running, since this changes
wneuper@59285
   233
       overall system behavior*)
wneuper@59285
   234
    in
wneuper@59302
   235
      Chead.Appl (Tac.Apply_Method' (mI, NONE, Selem.e_istate (*filled in solve*), ctxt))
wneuper@59285
   236
    end
wneuper@59302
   237
  | applicable_in (p, p_) _ (Tac.Check_Postcond pI) =
wneuper@59285
   238
      if member op = [Pbl, Met] p_                  
wneuper@59302
   239
      then Chead.Notappl ((Tac.tac2str (Tac.Check_Postcond pI)) ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59302
   240
      else Chead.Appl (Tac.Check_Postcond' (pI, (e_term, [(*fun solve assigns returnvalue of scr*)])))
wneuper@59302
   241
  | applicable_in _ _ (Tac.Take str) = Chead.Appl (Tac.Take' (str2term str)) (* always applicable ?*)
wneuper@59304
   242
  | applicable_in _ _ (Tac.Free_Solve) = Chead.Appl (Tac.Free_Solve')        (* always applicable *)
wneuper@59302
   243
  | applicable_in (p, p_) pt (m as Tac.Rewrite_Inst (subs, thm'')) = 
neuper@42394
   244
    if member op = [Pbl, Met] p_ 
wneuper@59302
   245
    then Chead.Notappl ((Tac.tac2str m)^" not for pos " ^ pos'2str (p, p_))
neuper@42394
   246
    else
neuper@42394
   247
      let 
neuper@42394
   248
        val pp = par_pblobj pt p;
neuper@42394
   249
        val thy' = (get_obj g_domID pt pp): theory';
neuper@42394
   250
        val thy = assoc_thy thy';
wneuper@59269
   251
        val {rew_ord' = ro', erls = erls, ...} = Specify.get_met (get_obj g_metID pt pp);
wneuper@59285
   252
        val (f, _) = case p_ of (*p 12.4.00 unnecessary*)
neuper@42394
   253
                      Frm => (get_obj g_form pt p, p)
neuper@42394
   254
                    | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
wneuper@59285
   255
                    | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
neuper@42394
   256
      in 
neuper@42394
   257
        let
wneuper@59301
   258
          val subst = Selem.subs2subst thy subs;
wneuper@59285
   259
        in
wneuper@59285
   260
          case rewrite_inst_ thy (assoc_rew_ord ro') erls false subst (snd thm'') f of
wneuper@59285
   261
            SOME (f',asm) =>
wneuper@59302
   262
              Chead.Appl (Tac.Rewrite_Inst' (thy', ro', erls, false, subst, thm'', f, (f', asm)))
wneuper@59285
   263
          | NONE => Chead.Notappl ((fst thm'')^" not applicable")
neuper@42394
   264
        end
wneuper@59265
   265
        handle _ => Chead.Notappl ("syntax error in "^(subs2str subs))
neuper@42394
   266
      end
wneuper@59302
   267
  | applicable_in (p, p_) pt (m as Tac.Rewrite thm'') = 
wneuper@59285
   268
    if member op = [Pbl, Met] p_ 
wneuper@59302
   269
    then Chead.Notappl ((Tac.tac2str m)^" not for pos "^(pos'2str (p, p_)))
neuper@37906
   270
    else
wneuper@59285
   271
      let
wneuper@59285
   272
        val (msg, thy', ro, rls', _)= from_pblobj_or_detail_thm thm'' p pt;
wneuper@59285
   273
        val thy = assoc_thy thy';
wneuper@59285
   274
        val f = case p_ of
wneuper@59285
   275
          Frm => get_obj g_form pt p
wneuper@59285
   276
	      | Res => (fst o (get_obj g_result pt)) p
wneuper@59285
   277
	      | _ => error ("applicable_in Rewrite: call by " ^ pos'2str (p, p_));
wneuper@59285
   278
      in
wneuper@59285
   279
        if msg = "OK" 
wneuper@59285
   280
        then
wneuper@59285
   281
          case rewrite_ thy (assoc_rew_ord ro) rls' false (snd thm'') f of
wneuper@59302
   282
            SOME (f',asm) => Chead.Appl (Tac.Rewrite' (thy', ro, rls', false, thm'', f, (f', asm)))
wneuper@59285
   283
          | NONE => Chead.Notappl ("'" ^ fst thm'' ^"' not applicable") 
wneuper@59285
   284
        else Chead.Notappl msg
wneuper@59285
   285
      end
wneuper@59302
   286
  | applicable_in (p, p_) pt (m as Tac.Rewrite_Asm thm'') = 
wneuper@59285
   287
    if member op = [Pbl, Met] p_ 
wneuper@59302
   288
    then Chead.Notappl ((Tac.tac2str m)^" not for pos "^(pos'2str (p,p_)))
wneuper@59285
   289
    else
wneuper@59285
   290
      let 
wneuper@59285
   291
        val pp = par_pblobj pt p; 
wneuper@59285
   292
        val thy' = (get_obj g_domID pt pp):theory';
wneuper@59285
   293
        val thy = assoc_thy thy';
wneuper@59285
   294
        val {rew_ord'=ro',erls=erls,...} = Specify.get_met (get_obj g_metID pt pp);
wneuper@59285
   295
        val (f, _) = case p_ of
wneuper@59285
   296
          Frm => (get_obj g_form pt p, p)
wneuper@59285
   297
	      | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
wneuper@59285
   298
	      | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59285
   299
      in
wneuper@59285
   300
        case rewrite_ thy (assoc_rew_ord ro') erls false (snd thm'') f of
wneuper@59302
   301
          SOME (f',asm) => Chead.Appl (Tac.Rewrite' (thy', ro', erls, false, thm'', f, (f', asm)))
wneuper@59285
   302
        | NONE => Chead.Notappl ("'" ^ fst thm'' ^ "' not applicable") end
wneuper@59302
   303
  | applicable_in (p, p_) pt (m as Tac.Detail_Set_Inst (subs, rls)) = 
wneuper@59285
   304
    if member op = [Pbl, Met] p_ 
wneuper@59302
   305
    then Chead.Notappl ((Tac.tac2str m)^" not for pos "^(pos'2str (p, p_)))
wneuper@59285
   306
    else
wneuper@59285
   307
      let 
wneuper@59285
   308
        val pp = par_pblobj pt p;
wneuper@59285
   309
        val thy' = get_obj g_domID pt pp;
wneuper@59285
   310
        val thy = assoc_thy thy';
wneuper@59285
   311
        val f = case p_ of Frm => get_obj g_form pt p
wneuper@59285
   312
    		| Res => (fst o (get_obj g_result pt)) p
wneuper@59285
   313
    		| _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59301
   314
        val subst = Selem.subs2subst thy subs
wneuper@59285
   315
      in 
wneuper@59285
   316
        case rewrite_set_inst_ thy false subst (assoc_rls rls) f of
wneuper@59285
   317
          SOME (f', asm)
wneuper@59302
   318
            => Chead.Appl (Tac.Detail_Set_Inst' (thy', false, subst, assoc_rls rls, f, (f', asm)))
wneuper@59285
   319
        | NONE => Chead.Notappl (rls ^ " not applicable")
wneuper@59285
   320
        handle _ => Chead.Notappl ("syntax error in " ^ subs2str subs)
wneuper@59285
   321
      end
wneuper@59302
   322
  | applicable_in (p, p_) pt (m as Tac.Rewrite_Set_Inst (subs, rls)) = 
wneuper@59285
   323
    if member op = [Pbl, Met] p_ 
wneuper@59302
   324
    then Chead.Notappl ((Tac.tac2str m)^" not for pos "^(pos'2str (p,p_)))
wneuper@59285
   325
    else
wneuper@59285
   326
      let 
wneuper@59285
   327
        val pp = par_pblobj pt p;
wneuper@59285
   328
        val thy' = get_obj g_domID pt pp;
wneuper@59285
   329
        val thy = assoc_thy thy';
wneuper@59285
   330
        val (f, _) = case p_ of
wneuper@59285
   331
          Frm => (get_obj g_form pt p, p)
wneuper@59285
   332
    	  | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
wneuper@59285
   333
    	  | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59301
   334
    	  val subst = Selem.subs2subst thy subs;
wneuper@59285
   335
      in 
wneuper@59285
   336
        case rewrite_set_inst_ thy (*put_asm*)false subst (assoc_rls rls) f of
wneuper@59285
   337
          SOME (f',asm)
wneuper@59302
   338
            => Chead.Appl (Tac.Rewrite_Set_Inst' (thy', false, subst, assoc_rls rls, f, (f', asm)))
wneuper@59285
   339
        | NONE => Chead.Notappl (rls ^ " not applicable")
wneuper@59285
   340
        handle _ => Chead.Notappl ("syntax error in " ^(subs2str subs))
wneuper@59285
   341
      end
wneuper@59302
   342
  | applicable_in (p, p_) pt (m as Tac.Rewrite_Set rls) = 
wneuper@59285
   343
    if member op = [Pbl, Met] p_ 
wneuper@59302
   344
    then Chead.Notappl (Tac.tac2str m ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59285
   345
    else
wneuper@59285
   346
      let 
wneuper@59285
   347
        val pp = par_pblobj pt p; 
wneuper@59285
   348
        val thy' = get_obj g_domID pt pp;
wneuper@59285
   349
        val (f, _) = case p_ of
wneuper@59285
   350
          Frm => (get_obj g_form pt p, p)
wneuper@59285
   351
    	  | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
wneuper@59285
   352
    	  | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59285
   353
      in
wneuper@59285
   354
        case rewrite_set_ (assoc_thy thy') false (assoc_rls rls) f of
wneuper@59285
   355
          SOME (f', asm)
wneuper@59302
   356
            => Chead.Appl (Tac.Rewrite_Set' (thy', false, assoc_rls rls, f, (f', asm)))
wneuper@59285
   357
          | NONE => Chead.Notappl (rls ^ " not applicable")
wneuper@59285
   358
      end
wneuper@59302
   359
  | applicable_in (p, p_) pt (m as Tac.Detail_Set rls) =
wneuper@59285
   360
    if member op = [Pbl, Met] p_ 
wneuper@59302
   361
    then Chead.Notappl (Tac.tac2str m ^ " not for pos " ^ pos'2str (p, p_))
wneuper@59285
   362
    else
wneuper@59285
   363
    	let
wneuper@59285
   364
    	  val pp = par_pblobj pt p 
wneuper@59285
   365
    	  val thy' = get_obj g_domID pt pp
wneuper@59285
   366
    	  val f = case p_ of
wneuper@59285
   367
    			Frm => get_obj g_form pt p
wneuper@59285
   368
    		| Res => (fst o (get_obj g_result pt)) p
wneuper@59285
   369
    		| _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59285
   370
    	in
wneuper@59285
   371
    	  case rewrite_set_ (assoc_thy thy') false (assoc_rls rls) f of
wneuper@59302
   372
    	    SOME (f',asm) => Chead.Appl (Tac.Detail_Set' (thy', false, assoc_rls rls, f, (f', asm)))
wneuper@59285
   373
    	  | NONE => Chead.Notappl (rls^" not applicable")
wneuper@59285
   374
    	end
wneuper@59304
   375
  | applicable_in _ _ Tac.End_Ruleset = error ("applicable_in: not impl. for " ^ Tac.tac2str Tac.End_Ruleset)
wneuper@59302
   376
  | applicable_in (p, p_) pt (m as Tac.Calculate op_) = 
wneuper@59285
   377
    if member op = [Pbl, Met] p_
wneuper@59302
   378
    then Chead.Notappl ((Tac.tac2str m)^" not for pos "^(pos'2str (p,p_)))
wneuper@59285
   379
    else
wneuper@59285
   380
      let 
wneuper@59285
   381
        val (msg,thy',isa_fn) = from_pblobj_or_detail_calc op_ p pt;
wneuper@59285
   382
        val f = case p_ of
wneuper@59285
   383
          Frm => get_obj g_form pt p
wneuper@59285
   384
    	  | Res => (fst o (get_obj g_result pt)) p
wneuper@59285
   385
      	| _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59285
   386
      in
wneuper@59285
   387
        if msg = "OK"
wneuper@59285
   388
        then
wneuper@59285
   389
    	    case calculate_ (assoc_thy thy') isa_fn f of
wneuper@59285
   390
    	      SOME (f', (id, thm))
wneuper@59302
   391
    	        => Chead.Appl (Tac.Calculate' (thy', op_, f, (f', (id, string_of_thmI thm))))
wneuper@59285
   392
    	    | NONE => Chead.Notappl ("'calculate "^op_^"' not applicable") 
wneuper@59285
   393
        else Chead.Notappl msg
wneuper@59285
   394
      end
wneuper@59285
   395
    (*Substitute combines two different kind of "substitution":
wneuper@59285
   396
      (1) subst_atomic: for ?a..?z
wneuper@59285
   397
      (2) Pattern.match: for solving equational systems (which raises exn for ?a..?z)*)
wneuper@59302
   398
  | applicable_in (p, p_) pt (m as Tac.Substitute sube) = 
wneuper@59285
   399
      if member op = [Pbl, Met] p_ 
wneuper@59302
   400
      then Chead.Notappl (Tac.tac2str m ^ " not for pos " ^ pos'2str (p, p_))
neuper@42360
   401
      else 
neuper@42360
   402
        let
neuper@42360
   403
          val pp = par_pblobj pt p
neuper@42360
   404
          val thy = assoc_thy (get_obj g_domID pt pp)
neuper@42360
   405
          val f = case p_ of
neuper@42360
   406
		        Frm => get_obj g_form pt p
neuper@42360
   407
		      | Res => (fst o (get_obj g_result pt)) p
wneuper@59285
   408
      	  | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59269
   409
		      val {rew_ord',erls,...} = Specify.get_met (get_obj g_metID pt pp)
wneuper@59301
   410
		      val subte = Selem.sube2subte sube
wneuper@59301
   411
		      val subst = Selem.sube2subst thy sube
neuper@42360
   412
		      val ro = assoc_rew_ord rew_ord'
neuper@42360
   413
		    in
neuper@42360
   414
		      if foldl and_ (true, map contains_Var subte)
wneuper@59285
   415
		      then (*1*)
neuper@42360
   416
		        let val f' = subst_atomic subst f
wneuper@59285
   417
		        in if f = f'
wneuper@59301
   418
		          then Chead.Notappl (Selem.sube2str sube^" not applicable")
wneuper@59302
   419
		          else Chead.Appl (Tac.Substitute' (ro, erls, subte, f, f'))
neuper@42360
   420
		        end
wneuper@59285
   421
		      else (*2*)
neuper@42360
   422
		        case rewrite_terms_ thy ro erls subte f of
wneuper@59302
   423
		          SOME (f', _) =>  Chead.Appl (Tac.Substitute' (ro, erls, subte, f, f'))
wneuper@59301
   424
		        | NONE => Chead.Notappl (Selem.sube2str sube ^ " not applicable")
neuper@42360
   425
		    end
wneuper@59302
   426
  | applicable_in _ _ (Tac.Apply_Assumption cts') = 
wneuper@59302
   427
    error ("applicable_in: not impl. for " ^ Tac.tac2str (Tac.Apply_Assumption cts'))
wneuper@59285
   428
    (* 'logical' applicability wrt. script in locate: Inconsistent? *)
wneuper@59302
   429
  | applicable_in _ _ (Tac.Take_Inst ct') =
wneuper@59302
   430
    error ("applicable_in: not impl. for " ^ Tac.tac2str (Tac.Take_Inst ct'))
wneuper@59302
   431
  | applicable_in (p, p_) pt (m as Tac.Subproblem (domID, pblID)) = 
neuper@37935
   432
     if member op = [Pbl,Met] p_
neuper@41993
   433
     then (*maybe Apply_Method has already been done FIXME.WN150511: declare_constraints*)
neuper@41993
   434
	      case get_obj g_env pt p of
wneuper@59285
   435
	        SOME _ => 
wneuper@59302
   436
            Chead.Appl (Tac.Subproblem' ((domID, pblID, e_metID), [], 
wneuper@59301
   437
					    e_term, [], Selem.e_ctxt(*FIXME.WN150511*), subpbl domID pblID))
wneuper@59302
   438
	      | NONE => Chead.Notappl ((Tac.tac2str m)^" not for pos "^(pos'2str (p,p_)))
neuper@37906
   439
     else (*somewhere later in the script*)
wneuper@59302
   440
       Chead.Appl (Tac.Subproblem' ((domID, pblID, e_metID), [], 
wneuper@59301
   441
			   e_term, [], Selem.e_ctxt, subpbl domID pblID))
wneuper@59304
   442
  | applicable_in _ _ (Tac.End_Subproblem) =
wneuper@59304
   443
    error ("applicable_in: not impl. for " ^ Tac.tac2str Tac.End_Subproblem)
wneuper@59302
   444
  | applicable_in _ _ (Tac.CAScmd ct') = 
wneuper@59302
   445
    error ("applicable_in: not impl. for " ^ Tac.tac2str (Tac.CAScmd ct'))  
wneuper@59303
   446
  | applicable_in _ _ (Tac.Split_And) = 
wneuper@59303
   447
    error ("applicable_in: not impl. for " ^ Tac.tac2str Tac.Split_And)
wneuper@59303
   448
  | applicable_in _ _ (Tac.Conclude_And) = 
wneuper@59303
   449
    error ("applicable_in: not impl. for " ^ Tac.tac2str Tac.Conclude_And)
wneuper@59303
   450
  | applicable_in _ _ (Tac.Split_Or) = 
wneuper@59303
   451
    error ("applicable_in: not impl. for " ^ Tac.tac2str Tac.Split_Or)
wneuper@59303
   452
  | applicable_in _ _ (Tac.Conclude_Or) = 
wneuper@59303
   453
    error ("applicable_in: not impl. for " ^ Tac.tac2str Tac.Conclude_Or)
wneuper@59304
   454
  | applicable_in (p, p_) pt (Tac.Begin_Trans) =
neuper@37906
   455
    let
wneuper@59285
   456
      val (f, _) = case p_ of   (*p 12.4.00 unnecessary, implizit Take in gen*)
wneuper@59285
   457
        Frm => (get_obj g_form pt p, (lev_on o lev_dn) p)
neuper@37906
   458
      | Res => ((fst o (get_obj g_result pt)) p, (lev_on o lev_dn o lev_on) p)
wneuper@59285
   459
      | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59302
   460
    in (Chead.Appl (Tac.Begin_Trans' f))
wneuper@59285
   461
      handle _ => error ("applicable_in: Begin_Trans finds  syntaxerror in '" ^ term2str f ^ "'")
neuper@37906
   462
    end
wneuper@59304
   463
  | applicable_in (p, p_) pt (Tac.End_Trans) = (*TODO: check parent branches*)
wneuper@59285
   464
    if p_ = Res 
wneuper@59302
   465
	  then Chead.Appl (Tac.End_Trans' (get_obj g_result pt p))
wneuper@59285
   466
    else Chead.Notappl "'End_Trans' is not applicable at the beginning of a transitive sequence"
wneuper@59304
   467
  | applicable_in _ _ (Tac.Begin_Sequ) = 
wneuper@59304
   468
    error ("applicable_in: not impl. for " ^ Tac.tac2str (Tac.Begin_Sequ))
wneuper@59304
   469
  | applicable_in _ _ (Tac.End_Sequ) = 
wneuper@59304
   470
    error ("applicable_in: not impl. for " ^ Tac.tac2str (Tac.End_Sequ))
wneuper@59304
   471
  | applicable_in _ _ (Tac.Split_Intersect) = 
wneuper@59304
   472
    error ("applicable_in: not impl. for " ^ Tac.tac2str (Tac.Split_Intersect))
wneuper@59304
   473
  | applicable_in _ _ (Tac.End_Intersect) = 
wneuper@59304
   474
    error ("applicable_in: not impl. for " ^ Tac.tac2str (Tac.End_Intersect))
wneuper@59302
   475
  | applicable_in (p, p_) pt (m as Tac.Check_elementwise pred) = 
neuper@42394
   476
    if member op = [Pbl,Met] p_ 
wneuper@59302
   477
    then Chead.Notappl ((Tac.tac2str m)^" not for pos " ^ pos'2str (p, p_))
neuper@42394
   478
    else
neuper@42394
   479
      let 
neuper@42394
   480
        val pp = par_pblobj pt p; 
neuper@42394
   481
        val thy' = (get_obj g_domID pt pp):theory';
neuper@42394
   482
        val thy = assoc_thy thy'
neuper@42394
   483
        val metID = (get_obj g_metID pt pp)
wneuper@59269
   484
        val {crls,...} =  Specify.get_met metID
wneuper@59285
   485
        val (f, asm) = case p_ of
wneuper@59285
   486
          Frm => (get_obj g_form pt p , [])
wneuper@59285
   487
        | Res => get_obj g_result pt p
wneuper@59285
   488
        | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
neuper@42394
   489
        val vp = (thy2ctxt thy, pred) |-> parseNEW |> the |> mk_set thy pt p f;
neuper@42394
   490
      in case f of
wneuper@59285
   491
        Const ("List.list.Cons",_) $ _ $ _ =>
wneuper@59302
   492
          Chead.Appl (Tac.Check_elementwise' (f, pred, check_elementwise thy crls f vp))
wneuper@59285
   493
      | Const ("Tools.UniversalList",_) => 
wneuper@59302
   494
          Chead.Appl (Tac.Check_elementwise' (f, pred, (f,asm)))
wneuper@59285
   495
      | Const ("List.list.Nil",_) => 
wneuper@59302
   496
          Chead.Appl (Tac.Check_elementwise' (f, pred, (f, asm)))
wneuper@59285
   497
      | _ => Chead.Notappl ("Check_elementwise not appl.: " ^ term2str f ^ " should be constants")
neuper@42394
   498
      end
wneuper@59304
   499
  | applicable_in (p, p_) pt Tac.Or_to_List = 
wneuper@59285
   500
    if member op = [Pbl, Met] p_ 
wneuper@59304
   501
    then Chead.Notappl ((Tac.tac2str Tac.Or_to_List)^" not for pos "^(pos'2str (p,p_)))
wneuper@59285
   502
    else
wneuper@59285
   503
      let 
wneuper@59285
   504
        val f = case p_ of
wneuper@59285
   505
          Frm => get_obj g_form pt p
wneuper@59285
   506
    	  | Res => (fst o (get_obj g_result pt)) p
wneuper@59285
   507
        | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59285
   508
      in (let val ls = or2list f
wneuper@59302
   509
          in Chead.Appl (Tac.Or_to_List' (f, ls)) end) 
wneuper@59285
   510
         handle _ => Chead.Notappl ("'Or_to_List' not applicable to "^(term2str f))
wneuper@59285
   511
      end
wneuper@59303
   512
  | applicable_in _ _ Tac.Collect_Trues = 
wneuper@59303
   513
    error ("applicable_in: not impl. for " ^ Tac.tac2str Tac.Collect_Trues)
wneuper@59303
   514
  | applicable_in _ _ Tac.Empty_Tac = Chead.Notappl "Empty_Tac is not applicable"
wneuper@59302
   515
  | applicable_in (p, p_) pt (Tac.Tac id) =
wneuper@59285
   516
    let 
wneuper@59285
   517
      val pp = par_pblobj pt p; 
wneuper@59285
   518
      val thy' = (get_obj g_domID pt pp):theory';
wneuper@59285
   519
      val thy = assoc_thy thy';
wneuper@59285
   520
      val f = case p_ of
wneuper@59285
   521
         Frm => get_obj g_form pt p
wneuper@59285
   522
      | Pbl => error "applicable_in (p,Pbl) pt (Tac id): not at Pbl"
wneuper@59285
   523
  	  | Res => (fst o (get_obj g_result pt)) p
wneuper@59285
   524
      | _ => error ("applicable_in: call by " ^ pos'2str (p, p_));
wneuper@59285
   525
    in case id of
wneuper@59285
   526
      "subproblem_equation_dummy" =>
wneuper@59285
   527
  	  if is_expliceq f
wneuper@59302
   528
  	  then Chead.Appl (Tac.Tac_ (thy, term2str f, id, "subproblem_equation_dummy (" ^ term2str f ^ ")"))
wneuper@59285
   529
  	  else Chead.Notappl "applicable only to equations made explicit"
wneuper@59285
   530
    | "solve_equation_dummy" =>
wneuper@59285
   531
  	  let val (id', f') = split_dummy (term2str f);
wneuper@59285
   532
  	  in
wneuper@59285
   533
  	    if id' <> "subproblem_equation_dummy"
wneuper@59285
   534
  	    then Chead.Notappl "no subproblem"
wneuper@59285
   535
  	    else if (thy2ctxt thy, f') |-> parseNEW |> the |> is_expliceq
wneuper@59302
   536
  		    then Chead.Appl (Tac.Tac_ (thy, term2str f, id, "[" ^ f' ^ "]"))
wneuper@59285
   537
  		    else error ("applicable_in: f= " ^ f')
wneuper@59285
   538
      end
wneuper@59302
   539
    | _ => Chead.Appl (Tac.Tac_ (thy, term2str f, id, term2str f))
wneuper@59285
   540
    end
wneuper@59304
   541
  | applicable_in _ _ Tac.End_Proof' = Chead.Appl Tac.End_Proof''
wneuper@59302
   542
  | applicable_in _ _ m = error ("applicable_in called for " ^ Tac.tac2str m);
neuper@37906
   543
wneuper@59285
   544
fun tac2tac_ pt p m = 
wneuper@59285
   545
  case applicable_in p pt m of
wneuper@59285
   546
	  Chead.Appl m' => m' 
wneuper@59302
   547
  | Chead.Notappl _ => error ("tac2mstp': fails with" ^ Tac.tac2str m);
neuper@37906
   548
wneuper@59285
   549
end;