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