src/Tools/isac/Interpret/appl.sml
author Walther Neuper <wneuper@ist.tugraz.at>
Mon, 10 Oct 2016 18:24:14 +0200
changeset 59250 727dff4f6b2c
parent 59186 d9c3e373f8f5
child 59252 7d3dbc1171ff
permissions -rw-r--r--
transport terms in theorems to frontend

Note: tests missing for both..
# Test_Isac.thy
# pbl/met/thy_hierarchy2file + genhtml to/from ~/tmp
     1 (* use"ME/appl.sml";
     2    use"appl.sml";
     3 
     4 12345678901234567890123456789012345678901234567890123456789012345678901234567890
     5         10        20        30        40        50        60        70        80
     6 *)
     7 val e_cterm' = empty_cterm';
     8 
     9 
    10 fun rew_info (Rls {erls,rew_ord=(rew_ord',_),calc=ca, ...}) =
    11     (rew_ord':rew_ord',erls,ca)
    12   | rew_info (Seq {erls,rew_ord=(rew_ord',_),calc=ca, ...}) =
    13     (rew_ord',erls,ca)
    14   | rew_info (Rrls {erls,rew_ord=(rew_ord',_),calc=ca, ...}) =
    15     (rew_ord',erls, ca)
    16   | rew_info rls = error ("rew_info called with '"^rls2str rls^"'");
    17 
    18 (*FIXME.3.4.03:re-organize from_pblobj_or_detail_thm after rls' --> rls*)
    19 fun from_pblobj_or_detail_thm thm' p pt = 
    20   let 
    21     val (pbl, p', rls') = par_pbl_det pt p
    22   in 
    23     if pbl
    24     then 
    25       let 
    26         val thy' = get_obj g_domID pt p'
    27         val {rew_ord', erls, ...} = get_met (get_obj g_metID pt p')              
    28 	    in ("OK", thy', rew_ord', erls, false) end
    29      else 
    30       let
    31         val thy' = get_obj g_domID pt (par_pblobj pt p)
    32 		    val (rew_ord', erls, _) = rew_info rls'
    33 		  in ("OK",thy',rew_ord',erls,false) end
    34   end;
    35 (*FIXME.3.4.03:re-organize from_pblobj_or_detail_calc after rls' --> rls*)
    36 fun from_pblobj_or_detail_calc scrop p pt = 
    37   let
    38     val (pbl,p',rls') = par_pbl_det pt p
    39   in
    40     if pbl
    41     then
    42       let
    43         val thy' = get_obj g_domID pt p'
    44         val {calc = scr_isa_fns,...} = get_met (get_obj g_metID pt p')
    45         val opt = assoc (scr_isa_fns, scrop)
    46 	    in
    47 	      case opt of
    48 	        SOME isa_fn => ("OK",thy',isa_fn)
    49 	      | NONE => ("applicable_in Calculate: unknown '" ^ scrop ^ "'", "", ("", e_evalfn))
    50 	    end
    51     else 
    52 		  let
    53 		    val thy' = get_obj g_domID pt (par_pblobj pt p);
    54 		    val (_,_,(*_,*)scr_isa_fns) = rew_info rls'(*rls*)
    55 		  in
    56 		    case assoc (scr_isa_fns, scrop) of
    57 		      SOME isa_fn => ("OK",thy',isa_fn)
    58 		    | NONE => ("applicable_in Calculate: unknown '" ^ scrop ^ "'", "", ("", e_evalfn))
    59 		  end
    60   end;
    61 
    62 val op_and = Const ("op &", [bool, bool] ---> bool);
    63 (*> (Thm.global_cterm_of thy) (op_and $ Free("a",bool) $ Free("b",bool));
    64 val it = "a & b" : cterm
    65 *)
    66 fun mk_and a b = op_and $ a $ b;
    67 (*> (Thm.global_cterm_of thy) 
    68      (mk_and (Free("a",bool)) (Free("b",bool)));
    69 val it = "a & b" : cterm*)
    70 
    71 fun mk_and [] = @{term True}
    72   | mk_and (t::[]) = t
    73   | mk_and (t::ts) = 
    74     let fun mk t' (t::[]) = op_and $ t' $ t
    75 	  | mk t' (t::ts) = mk (op_and $ t' $ t) ts
    76     in mk t ts end;
    77 (*> val pred = map (Thm.term_of o the o (parse thy)) 
    78              ["#0 <= #9 + #4 * x","#0 <= sqrt x + sqrt (#-3 + x)"];
    79 > (Thm.global_cterm_of thy) (mk_and pred);
    80 val it = "#0 <= #9 + #4 * x & #0 <= sqrt x + sqrt (#-3 + x)" : cterm*)
    81 
    82 
    83 
    84 
    85 (*for Check_elementwise in applicable_in: [x=1,..] Assumptions -> (x,0<=x&..)*)
    86 fun mk_set thy pt p (Const ("List.list.Nil",_)) pred = (e_term, [])
    87 
    88   | mk_set thy pt p (Const ("Tools.UniversalList",_)) pred =
    89     (e_term, if pred <> Const ("Script.Assumptions",bool)
    90 	     then [pred] 
    91 	     else get_assumptions_ pt (p,Res))
    92 
    93 (* val pred = (Thm.term_of o the o (parse thy)) pred;
    94    val consts as Const ("List.list.Cons",_) $ eq $ _ = ft;
    95    mk_set thy pt p consts pred;
    96    *)
    97   | mk_set thy pt p (consts as Const ("List.list.Cons",_) $ eq $ _) pred =
    98   let val (bdv,_) = HOLogic.dest_eq eq;
    99     val pred = if pred <> Const ("Script.Assumptions",bool)
   100 		 then [pred] 
   101 	       else get_assumptions_ pt (p,Res)
   102   in (bdv, pred) end
   103 
   104   | mk_set thy _ _ l _ = 
   105     error ("check_elementwise: no set " ^ term2str l);
   106 (*> val consts = str2term "[x=#4]";
   107 > val pred = str2term "Assumptions";
   108 > val pt = union_asm pt p 
   109    [("#0 <= sqrt x + sqrt (#5 + x)",[11]),("#0 <= #9 + #4 * x",[22]),
   110    ("#0 <= x ^^^ #2 + #5 * x",[33]),("#0 <= #2 + x",[44])];
   111 > val p = [];
   112 > val (sss,ttt) = mk_set thy pt p consts pred;
   113 > (term2str sss, term2str ttt);
   114 val it = ("x","((#0 <= sqrt x + sqrt (#5 + x) & #0 <= #9 + #4 * x) & ...
   115 
   116  val consts = str2term "UniversalList";
   117  val pred = str2term "Assumptions";
   118 
   119 *)
   120 
   121 
   122 
   123 (*check a list (/set) of constants [c_1,..,c_n] for c_i:set (: in)*)
   124 (* val (erls,consts,(bdv,pred)) = (erl,ft,vp);
   125    val (consts,(bdv,pred)) = (ft,vp);
   126    *)
   127 fun check_elementwise thy erls all_results (bdv, asm) =
   128     let   (*bdv extracted from ~~~~~~~~~~~ in mk_set already*)
   129 	fun check sub =
   130 	    let val inst_ = map (subst_atomic [sub]) asm
   131 	    in case eval__true thy 1 inst_ [] erls of
   132 		   (asm', true) => ([HOLogic.mk_eq sub], asm')
   133 		 | (_, false) => ([],[])
   134 	    end;
   135       (*val _= tracing("### check_elementwise: res= "^(term2str all_results)^
   136 		       ", bdv= "^(term2str bdv)^", asm= "^(terms2str asm));*)
   137 	val c' = isalist2list all_results
   138 	val c'' = map (snd o HOLogic.dest_eq) c' (*assumes [x=1,x=2,..]*)
   139 	val subs = map (pair bdv) c''
   140     in if asm = [] then (all_results, [])
   141        else ((apfst ((list2isalist bool) o flat)) o 
   142 	     (apsnd flat) o split_list o (map check)) subs end;
   143 (* 20.5.03
   144 > val all_results = str2term "[x=a+b,x=b,x=3]";
   145 > val bdv = str2term "x";
   146 > val asm = str2term "(x ~= a) & (x ~= b)";
   147 > val erls = e_rls;
   148 > val (t, ts) = check_elementwise thy erls all_results (bdv, asm);
   149 > term2str t; tracing(terms2str ts);
   150 val it = "[x = a + b, x = b, x = c]" : string
   151 ["a + b ~= a & a + b ~= b","b ~= a & b ~= b","c ~= a & c ~= b"]
   152 ... with appropriate erls this should be:
   153 val it = "[x = a + b,       x = c]" : string
   154 ["b ~= 0 & a ~= 0",         "3 ~= a & 3 ~= b"]
   155                     ////// because b ~= b False*)
   156 
   157 
   158 
   159 (*before 5.03-----
   160 > val ct = "((#0 <= #18 & #0 <= sqrt (#5 + #3) + sqrt (#5 - #3)) &\
   161 	   \ #0 <= #25 + #-1 * #3 ^^^ #2) & #0 <= #4";
   162 > val SOME(ct',_) = rewrite_set "Isac" false "eval_rls" ct;
   163 val ct' = "HOL.True" : cterm'
   164 
   165 > val ct = "((#0 <= #18 & #0 <= sqrt (#5 + #-3) + sqrt (#5 - #-3)) &\
   166 	   \ #0 <= #25 + #-1 * #-3 ^^^ #2) & #0 <= #4";
   167 > val SOME(ct',_) = rewrite_set "Isac"  false "eval_rls" ct;
   168 val ct' = "HOL.True" : cterm'
   169 
   170 
   171 > val const  = (Thm.term_of o the o (parse thy)) "(#3::real)";
   172 > val pred' = subst_atomic [(bdv,const)] pred;
   173 
   174 
   175 > val consts = (Thm.term_of o the o (parse thy)) "[x = #-3, x = #3]";
   176 > val bdv    = (Thm.term_of o the o (parse thy)) "(x::real)";
   177 > val pred   = (Thm.term_of o the o (parse thy)) 
   178   "((#0 <= #18 & #0 <= sqrt (#5 + x) + sqrt (#5 - x)) & #0 <= #25 + #-1 * x ^^^ #2) & #0 <= #4";
   179 > val ttt = check_elementwise thy consts (bdv, pred);
   180 > (Thm.global_cterm_of thy) ttt;
   181 val it = "[x = #-3, x = #3]" : cterm
   182 
   183 > val consts = (Thm.term_of o the o (parse thy)) "[x = #4]";
   184 > val bdv    = (Thm.term_of o the o (parse thy)) "(x::real)";
   185 > val pred   = (Thm.term_of o the o (parse thy)) 
   186  "#0 <= sqrt x + sqrt (#5 + x) & #0 <= #9 + #4 * x & #0 <= x ^^^ #2 + #5 * x & #0 <= #2 + x";
   187 > val ttt = check_elementwise thy consts (bdv,pred);
   188 > (Thm.global_cterm_of thy) ttt;
   189 val it = "[x = #4]" : cterm
   190 
   191 > val consts = (Thm.term_of o the o (parse thy)) "[x = #-12 // #5]";
   192 > val bdv    = (Thm.term_of o the o (parse thy)) "(x::real)";
   193 > val pred   = (Thm.term_of o the o (parse thy))
   194  " #0 <= sqrt x + sqrt (#-3 + x) & #0 <= #9 + #4 * x & #0 <= x ^^^ #2 + #-3 * x & #0 <= #6 + x";
   195 > val ttt = check_elementwise thy consts (bdv,pred);
   196 > (Thm.global_cterm_of thy) ttt;
   197 val it = "[]" : cterm*)
   198 
   199 
   200 (* 14.1.01: for Tac-dummies in root-equ only: skip str until "("*)
   201 fun split_dummy str = 
   202 let fun scan s' [] = (implode s', "")
   203       | scan s' (s::ss) = if s=" " then (implode s', implode  ss)
   204 			  else scan (s'@[s]) ss;
   205 in ((scan []) o Symbol.explode) str end;
   206 (* split_dummy "subproblem_equation_dummy (x=-#5//#12)";
   207 val it = ("subproblem_equation_dummy","(x=-#5//#12)") : string * string
   208 > split_dummy "x=-#5//#12";
   209 val it = ("x=-#5//#12","") : string * string*)
   210 
   211 
   212 
   213 
   214 (*.applicability of a tacic wrt. a calc-state (ptree,pos').
   215    additionally used by next_tac in the script-interpreter for script-tacs.
   216    tests for applicability are so expensive, that results (rewrites!)
   217    are kept in the return-value of 'type tac_'.
   218 .*)
   219 fun applicable_in (_:pos') _ (Init_Proof (ct', spec)) = Appl (Init_Proof' (ct', spec))
   220 
   221   | applicable_in (p,p_) pt Model_Problem = 
   222       if not (is_pblobj (get_obj I pt p)) orelse p_ = Res
   223       then Notappl ((tac2str Model_Problem) ^ " not for pos " ^ (pos'2str (p,p_)))
   224       else 
   225         let 
   226           val (PblObj{origin=(_,(_,pI',_),_),...}) = get_obj I pt p
   227 	        val {ppc,...} = get_pbt pI'
   228 	        val pbl = init_pbl ppc
   229         in Appl (Model_Problem' (pI', pbl, [])) end
   230 
   231   | applicable_in (p,p_) pt (Refine_Tacitly pI) = 
   232       if not (is_pblobj (get_obj I pt p)) orelse p_ = Res
   233       then Notappl ((tac2str (Refine_Tacitly pI)) ^ " not for pos " ^ (pos'2str (p,p_)))
   234       else 
   235         let 
   236           val (PblObj {origin = (oris, (dI',_,_),_), ...}) = get_obj I pt p;
   237           val opt = refine_ori oris pI;
   238         in case opt of
   239 	           SOME pblID => 
   240 	             Appl (Refine_Tacitly' (pI, pblID, 
   241 				         e_domID, e_metID, [](*filled in specify*)))
   242 	         | NONE => Notappl ((tac2str (Refine_Tacitly pI)) ^ " not applicable")
   243         end
   244 
   245   | applicable_in (p,p_) pt (Refine_Problem pI) = 
   246   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   247     then Notappl ((tac2str (Refine_Problem pI))^
   248 	   " not for pos "^(pos'2str (p,p_)))
   249   else
   250     let val (PblObj {origin=(_,(dI,_,_),_),spec=(dI',_,_),
   251 		     probl=itms, ...}) = get_obj I pt p;
   252 	val thy = if dI' = e_domID then dI else dI';
   253 	val rfopt = refine_pbl (assoc_thy thy) pI itms;
   254     in case rfopt of
   255 	   NONE => Notappl ((tac2str (Refine_Problem pI))^" not applicable")
   256 	 | SOME (rf as (pI',_)) =>
   257 (* val SOME (rf as (pI',_)) = rfopt;
   258    *)
   259 	   if pI' = pI
   260 	   then Notappl ((tac2str (Refine_Problem pI))^" not applicable")
   261 	   else Appl (Refine_Problem' rf)
   262     end
   263 
   264   (*the specify-tacs have cterm' instead term: 
   265    parse+error here!!!: see appl_add*)  
   266   | applicable_in (p,p_) pt (Add_Given ct') = 
   267   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   268     then Notappl ((tac2str (Add_Given ct'))^
   269 	   " not for pos "^(pos'2str (p,p_)))
   270   else Appl (Add_Given' (ct', [(*filled in specify_additem*)]))
   271   (*Add_.. should reject (dsc //) (see fmz=[] in sqrt*)
   272 
   273   | applicable_in (p,p_) pt (Del_Given ct') =
   274   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   275     then Notappl ((tac2str (Del_Given ct'))^
   276 	   " not for pos "^(pos'2str (p,p_)))
   277   else Appl (Del_Given' ct')
   278 
   279   | applicable_in (p,p_) pt (Add_Find ct') =                   
   280   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   281     then Notappl ((tac2str (Add_Find ct'))^
   282 	   " not for pos "^(pos'2str (p,p_)))
   283   else Appl (Add_Find' (ct', [(*filled in specify_additem*)]))
   284 
   285   | applicable_in (p,p_) pt (Del_Find ct') =
   286   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   287     then Notappl ((tac2str (Del_Find ct'))^
   288 	   " not for pos "^(pos'2str (p,p_)))
   289   else Appl (Del_Find' ct')
   290 
   291   | applicable_in (p,p_) pt (Add_Relation ct') =               
   292   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   293     then Notappl ((tac2str (Add_Relation ct'))^
   294 	   " not for pos "^(pos'2str (p,p_)))
   295   else Appl (Add_Relation' (ct', [(*filled in specify_additem*)]))
   296 
   297   | applicable_in (p,p_) pt (Del_Relation ct') =
   298   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   299     then Notappl ((tac2str (Del_Relation ct'))^
   300 	   " not for pos "^(pos'2str (p,p_)))
   301   else Appl (Del_Relation' ct')
   302 
   303   | applicable_in (p,p_) pt (Specify_Theory dI) =              
   304   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   305     then Notappl ((tac2str (Specify_Theory dI))^
   306 	   " not for pos "^(pos'2str (p,p_)))
   307   else Appl (Specify_Theory' dI)
   308 (* val (p,p_) = p; val Specify_Problem pID = m;
   309    val Specify_Problem pID = m;
   310    *)
   311   | applicable_in (p,p_) pt (Specify_Problem pID) = 
   312   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   313     then Notappl ((tac2str (Specify_Problem pID))^
   314 	   " not for pos "^(pos'2str (p,p_)))
   315   else
   316     let val (PblObj {origin=(oris,(dI,pI,_),_),spec=(dI',pI',_),
   317 		     probl=itms, ...}) = get_obj I pt p;
   318 	val thy = assoc_thy (if dI' = e_domID then dI else dI');
   319         val {ppc,where_,prls,...} = get_pbt pID;
   320 	val pbl = if pI'=e_pblID andalso pI=e_pblID
   321 		  then (false, (init_pbl ppc, []))
   322 		  else match_itms_oris thy itms (ppc,where_,prls) oris;
   323     in Appl (Specify_Problem' (pID, pbl)) end
   324 (* val Specify_Method mID = nxt; val (p,p_) = p; 
   325    *)
   326   | applicable_in (p,p_) pt (Specify_Method mID) =              
   327   if not (is_pblobj (get_obj I pt p)) orelse p_ = Res               
   328     then Notappl ((tac2str (Specify_Method mID))^
   329 	   " not for pos "^(pos'2str (p,p_)))
   330   else Appl (Specify_Method' (mID,[(*filled in specify*)],
   331 			      [(*filled in specify*)]))
   332 
   333   | applicable_in (p,p_) pt (Apply_Method mI) =                
   334       if not (is_pblobj (get_obj I pt p)) orelse p_ = Res                  
   335       then Notappl ((tac2str (Apply_Method mI)) ^ " not for pos " ^ (pos'2str (p,p_)))
   336       else
   337         let
   338           val (PblObj{origin = (_, (dI, pI, _), _), probl, ctxt, ...}) = get_obj I pt p;
   339           val {where_, ...} = get_pbt pI
   340           val pres = map (mk_env probl |> subst_atomic) where_
   341           val ctxt = 
   342             if is_e_ctxt ctxt
   343             then assoc_thy dI |> Proof_Context.init_global |> insert_assumptions pres
   344             else ctxt
   345          (*TODO.WN110416 here do evalprecond according to fun check_preconds'
   346          and then decide on Notappl/Appl accordingly once more.
   347          Implement after all tests are running, since this changes
   348          overall system behavior*)
   349       in Appl (Apply_Method' (mI, NONE, e_istate (*filled in solve*), ctxt)) end
   350 
   351   | applicable_in (p,p_) pt (Check_Postcond pI) =
   352       if member op = [Pbl,Met] p_                  
   353       then Notappl ((tac2str (Check_Postcond pI)) ^ " not for pos "^(pos'2str (p,p_)))
   354       else Appl (Check_Postcond' (pI, (e_term, [(*fun solve assignes the returnvalue of scr*)])))
   355 
   356   (*these are always applicable*)
   357   | applicable_in (p,p_) _ (Take str) = Appl (Take' (str2term str))
   358   | applicable_in (p,p_) _ (Free_Solve) = Appl (Free_Solve')
   359 
   360   | applicable_in (p, p_) pt (m as Rewrite_Inst (subs, thm'')) = 
   361     if member op = [Pbl, Met] p_ 
   362     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   363     else
   364       let 
   365         val pp = par_pblobj pt p;
   366         val thy' = (get_obj g_domID pt pp): theory';
   367         val thy = assoc_thy thy';
   368         val {rew_ord' = ro', erls = erls, ...} = get_met (get_obj g_metID pt pp);
   369         val (f, p) = case p_ of (*p 12.4.00 unnecessary*)
   370                       Frm => (get_obj g_form pt p, p)
   371                     | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
   372                     | _ => error ("applicable_in: call by " ^ pos'2str (p,p_));
   373       in 
   374         let
   375           val subst = subs2subst thy subs;
   376           val subs' = subst2subs' subst;
   377           val thm = assoc_thm'' thy thm''
   378         in case rewrite_inst_ thy (assoc_rew_ord ro') erls false subst thm f of
   379              SOME (f',asm) =>
   380                Appl (Rewrite_Inst' (thy', ro', erls, false, subst, thm, f, (f', asm)))
   381            | NONE => Notappl (fst thm'' ^ " not applicable")
   382         end
   383         handle _ => Notappl ("syntax error in "^(subs2str subs))
   384       end
   385 
   386 | applicable_in (p,p_) pt (m as Rewrite thm'') = 
   387   if member op = [Pbl,Met] p_ 
   388     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   389   else
   390   let val (msg,thy',ro,rls',(*put_asm*)_)= from_pblobj_or_detail_thm thm'' p pt;
   391     val thy = assoc_thy thy';
   392     val f = case p_ of
   393               Frm => get_obj g_form pt p
   394 	    | Res => (fst o (get_obj g_result pt)) p
   395 	    | _ => error ("applicable_in Rewrite: call by "^
   396 				(pos'2str (p,p_)));
   397   in if msg = "OK" 
   398      then
   399       ((*tracing("### applicable_in rls'= "^rls');*)
   400        (* val SOME (f',asm)=rewrite thy' ro (id_rls rls') put_asm thm' f;
   401 	  *) 
   402 	    let val thm = assoc_thm'' thy thm''
   403 	    in case rewrite_ thy (assoc_rew_ord ro) rls' false thm f of
   404         SOME (f',asm) => Appl (Rewrite' (thy', ro, rls', false, thm, f, (f', asm)))
   405       | NONE => Notappl ("'" ^ fst thm'' ^"' not applicable") 
   406       end)
   407      else Notappl msg
   408   end
   409 
   410 | applicable_in (p,p_) pt (m as Rewrite_Asm thm'') = 
   411   if member op = [Pbl,Met] p_ 
   412     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   413   else
   414   let 
   415     val pp = par_pblobj pt p; 
   416     val thy' = (get_obj g_domID pt pp):theory';
   417     val thy = assoc_thy thy';
   418     val {rew_ord'=ro',erls=erls,...} = 
   419       get_met (get_obj g_metID pt pp);
   420     (*val put_asm = true;*)
   421     val (f, _) = case p_ of
   422               Frm => (get_obj g_form pt p, p)
   423 	    | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
   424 	    | _ => error ("applicable_in: call by "^
   425 				(pos'2str (p,p_)));
   426     val thm = assoc_thm'' thy thm''
   427   in case rewrite_ thy (assoc_rew_ord ro') erls false thm f of
   428        SOME (f',asm) => Appl (
   429 	   Rewrite' (thy', ro', erls, false, thm, f, (f', asm)))
   430      | NONE => Notappl ("'" ^ fst thm'' ^ "' not applicable") end
   431 
   432   | applicable_in (p,p_) pt (m as Detail_Set_Inst (subs, rls)) = 
   433   if member op = [Pbl,Met] p_ 
   434     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   435   else
   436   let 
   437     val pp = par_pblobj pt p;
   438     val thy' = (get_obj g_domID pt pp):theory';
   439     val thy = assoc_thy thy';
   440     val {rew_ord'=ro',...} = get_met (get_obj g_metID pt pp);
   441     val f = case p_ of Frm => get_obj g_form pt p
   442 		     | Res => (fst o (get_obj g_result pt)) p
   443 		     | _ => error ("applicable_in: call by "^
   444 					 (pos'2str (p,p_)));
   445   in 
   446       let val subst = subs2subst thy subs
   447 	  val subs' = subst2subs' subst
   448       in case rewrite_set_inst_ thy false subst (assoc_rls rls) f of
   449       SOME (f',asm) => Appl (
   450 	  Detail_Set_Inst' (thy',false,subst,assoc_rls rls, f, (f', asm)))
   451     | NONE => Notappl (rls^" not applicable") end
   452   handle _ => Notappl ("syntax error in "^(subs2str subs)) end
   453 
   454   | applicable_in (p,p_) pt (m as Rewrite_Set_Inst (subs, rls)) = 
   455   if member op = [Pbl,Met] p_ 
   456     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   457   else
   458   let 
   459     val pp = par_pblobj pt p;
   460     val thy' = (get_obj g_domID pt pp):theory';
   461     val thy = assoc_thy thy';
   462     val {rew_ord'=ro',(*asm_rls=asm_rls,*)...} = 
   463       get_met (get_obj g_metID pt pp);
   464     val (f,p) = case p_ of  (*p 12.4.00 unnecessary*)
   465               Frm => (get_obj g_form pt p, p)
   466 	    | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
   467 	    | _ => error ("applicable_in: call by "^
   468 				(pos'2str (p,p_)));
   469   in 
   470     let val subst = subs2subst thy subs;
   471 	val subs' = subst2subs' subst;
   472     in case rewrite_set_inst_ thy (*put_asm*)false subst (assoc_rls rls) f of
   473       SOME (f',asm) => Appl (
   474 	  Rewrite_Set_Inst' (thy',(*put_asm*)false,subst,assoc_rls rls, f, (f', asm)))
   475     | NONE => Notappl (rls^" not applicable") end
   476   handle _ => Notappl ("syntax error in "^(subs2str subs)) end
   477 
   478   | applicable_in (p,p_) pt (m as Rewrite_Set rls) = 
   479   if member op = [Pbl,Met] p_ 
   480     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   481   else
   482   let 
   483     val pp = par_pblobj pt p; 
   484     val thy' = (get_obj g_domID pt pp):theory';
   485     val (f,p) = case p_ of  (*p 12.4.00 unnecessary*)
   486               Frm => (get_obj g_form pt p, p)
   487 	    | Res => ((fst o (get_obj g_result pt)) p, lev_on p)
   488 	    | _ => error ("applicable_in: call by "^
   489 				(pos'2str (p,p_)));
   490   in case rewrite_set_ (assoc_thy thy') false (assoc_rls rls) f of
   491        SOME (f',asm) => 
   492 	((*tracing("#.# applicable_in Rewrite_Set,2f'= "^f');*)
   493 	 Appl (Rewrite_Set' (thy',(*put_asm*)false,assoc_rls rls, f, (f', asm)))
   494 	 )
   495      | NONE => Notappl (rls^" not applicable") end
   496 
   497   | applicable_in (p,p_) pt (m as Detail_Set rls) =
   498     if member op = [Pbl,Met] p_ 
   499     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   500     else
   501 	let val pp = par_pblobj pt p 
   502 	    val thy' = (get_obj g_domID pt pp):theory'
   503 	    val f = case p_ of
   504 			Frm => get_obj g_form pt p
   505 		      | Res => (fst o (get_obj g_result pt)) p
   506 		      | _ => error ("applicable_in: call by "^
   507 					  (pos'2str (p,p_)));
   508 	in case rewrite_set_ (assoc_thy thy') false (assoc_rls rls) f of
   509 	       SOME (f',asm) => 
   510 	       Appl (Detail_Set' (thy',false,assoc_rls rls, f, (f',asm)))
   511 	     | NONE => Notappl (rls^" not applicable") end
   512 
   513 
   514   | applicable_in p pt (End_Ruleset) = 
   515   error ("applicable_in: not impl. for "^
   516 	       (tac2str End_Ruleset))
   517 
   518 (* val ((p,p_), pt, (m as Calculate op_)) = (p, pt, m);
   519    *)
   520 | applicable_in (p,p_) pt (m as Calculate op_) = 
   521   if member op = [Pbl,Met] p_
   522     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   523   else
   524   let 
   525     val (msg,thy',isa_fn) = from_pblobj_or_detail_calc op_ p pt;
   526     val f = case p_ of
   527               Frm => get_obj g_form pt p
   528 	    | Res => (fst o (get_obj g_result pt)) p
   529   in if msg = "OK" then
   530 	 case calculate_ (assoc_thy thy') isa_fn f of
   531 	     SOME (f', (id, thm)) => 
   532 	     Appl (Calculate' (thy',op_, f, (f', (id, string_of_thmI thm))))
   533 	   | NONE => Notappl ("'calculate "^op_^"' not applicable") 
   534      else Notappl msg
   535   end
   536 
   537 (*Substitute combines two different kind of "substitution":
   538   (1) subst_atomic: for ?a..?z
   539   (2) Pattern.match: for solving equational systems 
   540       (which raises exn for ?a..?z)*)
   541   | applicable_in (p,p_) pt (m as Substitute sube) = 
   542       if member op = [Pbl,Met] p_ 
   543       then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   544       else 
   545         let
   546           val pp = par_pblobj pt p
   547           val thy = assoc_thy (get_obj g_domID pt pp)
   548           val f = case p_ of
   549 		        Frm => get_obj g_form pt p
   550 		      | Res => (fst o (get_obj g_result pt)) p
   551 		      val {rew_ord',erls,...} = get_met (get_obj g_metID pt pp)
   552 		      val subte = sube2subte sube
   553 		      val subst = sube2subst thy sube
   554 		      val ro = assoc_rew_ord rew_ord'
   555 		    in
   556 		      if foldl and_ (true, map contains_Var subte)
   557 		      (*1*)
   558 		      then
   559 		        let val f' = subst_atomic subst f
   560 		        in if f = f' then Notappl (sube2str sube^" not applicable")
   561 		           else Appl (Substitute' (ro, erls, subte, f, f'))
   562 		        end
   563 		        (*2*)
   564 		      else 
   565 		        case rewrite_terms_ thy ro erls subte f of
   566 		            SOME (f', _) =>  Appl (Substitute' (ro, erls, subte, f, f'))
   567 		          | NONE => Notappl (sube2str sube^" not applicable")
   568 		    end
   569 
   570   | applicable_in p pt (Apply_Assumption cts') = 
   571       (error ("applicable_in: not impl. for " ^ (tac2str (Apply_Assumption cts'))))
   572   
   573   (*'logical' applicability wrt. script in locate: Inconsistent?*)
   574   | applicable_in (p,p_) pt (m as Take ct') = 
   575       if member op = [Pbl,Met] p_ 
   576       then Notappl (tac2str m ^ " not for pos " ^ pos'2str (p,p_))
   577       else
   578         let val thy' = get_obj g_domID pt (par_pblobj pt p);
   579         in (case parseNEW (assoc_thy thy' |> thy2ctxt) ct' of
   580 	            SOME ct => Appl (Take' ct)
   581 	          | NONE => Notappl ("syntax error in " ^ ct'))
   582         end
   583 
   584   | applicable_in p pt (Take_Inst ct') = 
   585       error ("applicable_in: not impl. for " ^ tac2str (Take_Inst ct'))
   586   | applicable_in p pt (Group (con, ints)) = 
   587       error ("applicable_in: not impl. for " ^ tac2str (Group (con, ints)))
   588 
   589   | applicable_in (p,p_) pt (m as Subproblem (domID, pblID)) = 
   590      if member op = [Pbl,Met] p_
   591      then (*maybe Apply_Method has already been done FIXME.WN150511: declare_constraints*)
   592 	      case get_obj g_env pt p of
   593 	        SOME is => 
   594             Appl (Subproblem' ((domID, pblID, e_metID), [], 
   595 					    e_term, [], e_ctxt(*FIXME.WN150511*), subpbl domID pblID))
   596 	      | NONE => Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   597      else (*somewhere later in the script*)
   598        Appl (Subproblem' ((domID, pblID, e_metID), [], 
   599 			   e_term, [], e_ctxt, subpbl domID pblID))
   600 
   601   | applicable_in p pt (End_Subproblem) =
   602       error ("applicable_in: not impl. for " ^ tac2str End_Subproblem)
   603   | applicable_in p pt (CAScmd ct') = 
   604       error ("applicable_in: not impl. for " ^ tac2str (CAScmd ct'))  
   605   | applicable_in p pt (Split_And) = 
   606       error ("applicable_in: not impl. for " ^ tac2str Split_And)
   607   | applicable_in p pt (Conclude_And) = 
   608       error ("applicable_in: not impl. for " ^ tac2str Conclude_And)
   609   | applicable_in p pt (Split_Or) = 
   610       error ("applicable_in: not impl. for " ^ tac2str Split_Or)
   611   | applicable_in p pt (Conclude_Or) = 
   612       error ("applicable_in: not impl. for " ^ tac2str Conclude_Or)
   613 
   614   | applicable_in (p,p_) pt (Begin_Trans) =
   615     let
   616       val (f,p) = case p_ of   (*p 12.4.00 unnecessary*)
   617 	                             (*_____ implizit Take in gen*)
   618 	Frm => (get_obj g_form pt p, (lev_on o lev_dn) p)
   619       | Res => ((fst o (get_obj g_result pt)) p, (lev_on o lev_dn o lev_on) p)
   620       | _ => error ("applicable_in: call by "^
   621 				(pos'2str (p,p_)));
   622       val thy' = get_obj g_domID pt (par_pblobj pt p);
   623     in (Appl (Begin_Trans' f))
   624       handle _ => error ("applicable_in: Begin_Trans finds \
   625                                \syntaxerror in '"^(term2str f)^"'") end
   626 
   627     (*TODO: check parent branches*)
   628   | applicable_in (p,p_) pt (End_Trans) =
   629     let val thy' = get_obj g_domID pt (par_pblobj pt p);
   630     in if p_ = Res 
   631 	     then Appl (End_Trans' (get_obj g_result pt p))
   632        else Notappl "'End_Trans' is not applicable at the beginning of a transitive sequence"
   633        (*TODO: check parent branches*)
   634     end
   635   | applicable_in p pt (Begin_Sequ) = 
   636       error ("applicable_in: not impl. for " ^ tac2str (Begin_Sequ))
   637   | applicable_in p pt (End_Sequ) = 
   638       error ("applicable_in: not impl. for " ^ tac2str (End_Sequ))
   639   | applicable_in p pt (Split_Intersect) = 
   640       error ("applicable_in: not impl. for " ^ tac2str (Split_Intersect))
   641   | applicable_in p pt (End_Intersect) = 
   642       error ("applicable_in: not impl. for " ^ tac2str (End_Intersect))
   643 
   644   | applicable_in (p,p_) pt (m as Check_elementwise pred) = 
   645     if member op = [Pbl,Met] p_ 
   646     then Notappl ((tac2str m)^" not for pos "^(pos'2str (p,p_)))
   647     else
   648       let 
   649         val pp = par_pblobj pt p; 
   650         val thy' = (get_obj g_domID pt pp):theory';
   651         val thy = assoc_thy thy'
   652         val metID = (get_obj g_metID pt pp)
   653         val {crls,...} =  get_met metID
   654         val (f,asm) = case p_ of Frm => (get_obj g_form pt p , [])
   655                                | Res => get_obj g_result pt p;
   656         val vp = (thy2ctxt thy, pred) |-> parseNEW |> the |> mk_set thy pt p f;
   657       in case f of
   658            Const ("List.list.Cons",_) $ _ $ _ =>
   659              Appl (Check_elementwise' (f, pred, check_elementwise thy crls f vp))
   660          | Const ("Tools.UniversalList",_) => 
   661              Appl (Check_elementwise' (f, pred, (f,asm)))
   662          | Const ("List.list.Nil",_) => 
   663              Appl (Check_elementwise' (f, pred, (f, asm)))
   664          | _ => Notappl ("Check_elementwise not applicable: "^(term2str f)^" should be constants")
   665       end
   666 
   667   | applicable_in (p,p_) pt Or_to_List = 
   668   if member op = [Pbl,Met] p_ 
   669     then Notappl ((tac2str Or_to_List)^" not for pos "^(pos'2str (p,p_)))
   670   else
   671   let 
   672     val pp = par_pblobj pt p; 
   673     val thy' = (get_obj g_domID pt pp):theory';
   674     val thy = assoc_thy thy';
   675     val f = case p_ of
   676               Frm => get_obj g_form pt p
   677 	    | Res => (fst o (get_obj g_result pt)) p;
   678   in (let val ls = or2list f
   679       in Appl (Or_to_List' (f, ls)) end) 
   680      handle _ => Notappl ("'Or_to_List' not applicable to "^(term2str f))
   681   end
   682 
   683   | applicable_in p pt (Collect_Trues) = 
   684   error ("applicable_in: not impl. for "^
   685 	       (tac2str (Collect_Trues)))
   686 
   687   | applicable_in p pt (Empty_Tac) = 
   688   Notappl "Empty_Tac is not applicable"
   689 
   690   | applicable_in (p,p_) pt (Tac id) =
   691   let 
   692     val pp = par_pblobj pt p; 
   693     val thy' = (get_obj g_domID pt pp):theory';
   694     val thy = assoc_thy thy';
   695     val f = case p_ of
   696               Frm => get_obj g_form pt p
   697             | Pbl => error "applicable_in (p,Pbl) pt (Tac id): not at Pbl"
   698 	    | Res => (fst o (get_obj g_result pt)) p;
   699   in case id of
   700       "subproblem_equation_dummy" =>
   701 	  if is_expliceq f
   702 	  then Appl (Tac_ (thy, term2str f, id,
   703 			     "subproblem_equation_dummy ("^(term2str f)^")"))
   704 	  else Notappl "applicable only to equations made explicit"
   705     | "solve_equation_dummy" =>
   706 	  let (*val _= tracing("### applicable_in: solve_equation_dummy: f= "
   707 				 ^f);*)
   708 	    val (id',f') = split_dummy (term2str f);
   709 	    (*val _= tracing("### applicable_in: f'= "^f');*)
   710 	    (*val _= (Thm.term_of o the o (parse thy)) f';*)
   711 	    (*val _= tracing"### applicable_in: solve_equation_dummy";*)
   712 	  in if id' <> "subproblem_equation_dummy" then Notappl "no subproblem"
   713 	     else if (thy2ctxt thy, f') |-> parseNEW |> the |> is_expliceq
   714 		      then Appl (Tac_ (thy, term2str f, id, "[" ^ f' ^ "]"))
   715 		  else error ("applicable_in: f= " ^ f') end
   716     | _ => Appl (Tac_ (thy, term2str f, id, term2str f)) end
   717 
   718   | applicable_in p pt End_Proof' = Appl End_Proof''
   719 
   720   | applicable_in _ _ m = 
   721   error ("applicable_in called for "^(tac2str m));
   722 
   723 (*WN060614 unused*)
   724 fun tac2tac_ pt p m = 
   725     case applicable_in p pt m of
   726 	Appl (m') => m' 
   727       | Notappl _ => error ("tac2mstp': fails with"^
   728 				  (tac2str m));
   729