src/Tools/isac/Interpret/mathengine.sml
author Walther Neuper <wneuper@ist.tugraz.at>
Sat, 27 Aug 2016 11:26:28 +0200
changeset 59239 3c4cc053f553
parent 59238 b0c4aafb9d06
child 59261 61a1bcd51e0e
permissions -rw-r--r--
push "ERROR in creating the environment.." up to math-engine
     1 (* The _functional_ mathematics engine, ie. without a state.
     2    Input and output are Isabelle's formulae as strings.
     3    authors: Walther Neuper 2000
     4    (c) due to copyright terms
     5 
     6 use"mathengine.sml";
     7 *)
     8 
     9 signature MATHENGINE =
    10   sig
    11     type nxt_
    12     (* datatype nxt_ = HElpless | Nexts of CalcHead.calcstate *)
    13     type NEW
    14     type lOc_
    15     (*datatype
    16       lOc_ =
    17           ERror of string
    18         | UNsafe of CalcHead.calcstate'
    19         | Updated of CalcHead.calcstate' *)
    20 
    21     val CalcTreeTEST :
    22        fmz list ->
    23        pos' * NEW * mout * (string * tac) * safe * ptree
    24 
    25     val TESTg_form : ptree * (int list * pos_) -> mout
    26     val autocalc :
    27        pos' list ->
    28        pos' ->
    29        (ptree * pos') * taci list ->
    30        auto -> string * pos' list * (ptree * pos')
    31     val detailstep : ptree -> pos' -> string * ptree * pos'
    32    (* val e_tac_ : tac_ *)
    33     val f2str : mout -> cterm'
    34    (* val get_pblID : ptree * pos' -> pblID option *)
    35     val initmatch : ptree -> pos' -> ptform
    36    (* val loc_solve_ :
    37        string * tac_ -> ptree * (int list * pos_) -> lOc_ *)
    38    (* val loc_specify_ : tac_ -> ptree * pos' -> lOc_ *)
    39     val locatetac :     (*tests only*)
    40        tac ->
    41        ptree * (posel list * pos_) ->
    42        string * (taci list * pos' list * (ptree * (posel list * pos_)))
    43     val me :
    44        tac'_ ->
    45        pos' ->
    46        NEW ->
    47        ptree -> pos' * NEW * mout * tac'_ * safe * ptree
    48 
    49     val nxt_specify_ : ptree * (int list * pos_) -> calcstate'(*tests only*)
    50     val set_method : metID -> ptree * pos' -> ptree * ocalhd
    51     val set_problem : pblID -> ptree * pos' -> ptree * ocalhd
    52     val set_theory : thyID -> ptree * pos' -> ptree * ocalhd
    53     val step : pos' -> calcstate -> string * calcstate'
    54     val trymatch : pblID -> ptree -> pos' -> ptform
    55     val tryrefine : pblID -> ptree -> pos' -> ptform
    56   end
    57 
    58 
    59 
    60 (*------------------------------------------------------------------(**)
    61 structure MathEngine : MATHENGINE =
    62 struct
    63 (**)------------------------------------------------------------------*)
    64 
    65 fun get_pblID (pt, (p,_):pos') =
    66     let val p' = par_pblobj pt p
    67 	val (_,pI,_) = get_obj g_spec pt p'
    68 	val (_,(_,oI,_),_) = get_obj g_origin pt p'
    69     in if pI <> e_pblID then SOME pI
    70        else if oI <> e_pblID then SOME oI
    71        else NONE end;
    72 (*fun get_pblID (pt, (p,_):pos') =
    73     ((snd3 o (get_obj g_spec pt)) (par_pblobj pt p));*)
    74 
    75 
    76 (*--vvv--dummies for test*)
    77 val e_tac_ = Tac_ (Pure.thy,"","","");
    78 datatype lOc_ =
    79   ERror of string         (*after loc_specify, loc_solve*)
    80 | UNsafe of calcstate'    (*after loc_specify, loc_solve*)
    81 | Updated of calcstate';   (*after loc_specify, loc_solve*)
    82 fun loc_specify_ m (pt,pos) =
    83 (* val pos = ip;
    84    *)
    85     let val (p,_,f,_,s,pt) = specify m pos [] pt;
    86 (*      val (_,_,_,_,_,pt')= specify m pos [] pt;
    87    *) 
    88    in case f of
    89 	   (Error' (Error_ e)) => ERror e
    90 	 | _ => Updated ([], [], (pt,p)) end;
    91 
    92 (*. TODO push return-value cs' into solve and rename solve->loc_solve?_? .*)
    93 (* val (m, pos) = ((mI,m), ip);
    94    val (m,(pt,pos) ) = ((mI,m), ptp);
    95    *)  
    96 fun loc_solve_ m (pt,pos) =
    97     let val (msg, cs') = solve m (pt, pos);
    98 (* val (tacis,dels,(pt',p')) = cs';
    99    (tracing o istate2str) (get_istate pt' p');
   100    (term2str o fst) (get_obj g_result pt' (fst p'));
   101    *)
   102     in case msg of
   103 	   "ok" => Updated cs' 
   104 	 | msg => ERror msg 
   105     end;
   106 
   107 datatype nxt_ =
   108 	 HElpless  (**)
   109        | Nexts of calcstate; (**)
   110 
   111 (*. locate a tactic in a script and apply it if possible .*)
   112 (*report applicability of tac in tacis; pt is dropped in setNextTactic*)
   113 fun locatetac _ (ptp as (_,([],Res))) = ("end-of-calculation", ([], [], ptp))
   114   | locatetac tac (ptp as (pt, p)) =
   115       let val (mI,m) = mk_tac'_ tac;
   116       in case applicable_in p pt m of
   117 	         Notappl e => ("not-applicable", ([],[],  ptp):calcstate')
   118 	       | Appl m =>
   119 	           let 
   120                val x = if member op = specsteps mI
   121 		             then loc_specify_ m ptp else loc_solve_ (mI,m) ptp
   122 	           in case x of 
   123 		              ERror e => ("failure", ([], [], ptp))
   124 		              (*FIXXXXXME: loc_specify_, loc_solve_ TOGETHER with dropping meOLD+detail.sml*)
   125 		            | UNsafe cs' => ("unsafe-ok", cs')
   126 		            | Updated (cs' as (_,_,(_,p'))) => (*ev.SEVER.tacs like Begin_Trans*)
   127 		                (if p' = ([],Res) then "end-of-calculation" else "ok", cs')
   128                     (*for SEVER.tacs user to ask ? *)
   129 	           end
   130       end;
   131 
   132 (*iterated by nxt_me; there (the resulting) ptp dropped
   133   may call nxt_solve Apply_Method --- thus evaluated here after solve.sml*)
   134 fun nxt_specify_ (ptp as (pt, pos as (p,p_))) =
   135   let val pblobj as (PblObj{meth,origin=origin as (oris,(dI',pI',mI'),_),
   136 			  probl,spec=(dI,pI,mI), ...}) = get_obj I pt p;
   137   in 
   138     if just_created_ pblobj (*by Subproblem*) andalso origin <> e_origin
   139     then 
   140       case mI' of
   141 	      ["no_met"] => nxt_specif (Refine_Tacitly pI') (pt, (p, Pbl))
   142       | _ => nxt_specif Model_Problem (pt, (p,Pbl))
   143     else 
   144       let 
   145         val cpI = if pI = e_pblID then pI' else pI;
   146 		    val cmI = if mI = e_metID then mI' else mI;
   147 		    val {ppc, prls, where_, ...} = get_pbt cpI;
   148 		    val pre = check_preconds "thy 100820" prls where_ probl;
   149 		    val pb = foldl and_ (true, map fst pre);
   150 		    (*FIXME.WN0308:    ~~~~~: just check true in itms of pbl/met?*)
   151 		    val (_,tac) = nxt_spec p_ pb oris (dI',pI',mI') (probl, meth) 
   152 			    (ppc, (#ppc o get_met) cmI) (dI, pI, mI);
   153 	    in case tac of
   154 		       Apply_Method mI => 
   155 		         nxt_solv (Apply_Method' (mI, NONE, e_istate, e_ctxt)) (e_istate, e_ctxt) ptp
   156 		     | _ => nxt_specif tac ptp end
   157    end;
   158 
   159 (*.specify a new method;
   160    WN0512 impl.incomplete, see 'nxt_specif (Specify_Method ' .*)
   161 fun set_method (mI:metID) ptp =
   162     let val ([(_, Specify_Method' (_, _, mits), _)], [], (pt, pos as (p,_))) = 
   163 	    nxt_specif (Specify_Method mI) ptp
   164 	val pre = []        (*...from Specify_Method'*)
   165 	val complete = true (*...from Specify_Method'*)
   166 	(*from Specify_Method'  ? vvv,  vvv ?*)
   167 	val PblObj {origin = (_,_,hdf), spec,...} = get_obj I pt p
   168     in (pt, (complete, Met, hdf, mits, pre, spec):ocalhd) end;
   169 
   170 (*.specify a new problem;
   171    WN0512 impl.incomplete, see 'nxt_specif (Specify_Problem ' .*)
   172 fun set_problem pI (ptp: ptree * pos') =
   173     let val ([(_, Specify_Problem' (_, (complete, (pits, pre))),_)],
   174 	     _, (pt, pos as (p,_))) = nxt_specif (Specify_Problem pI) ptp
   175 	(*from Specify_Problem' ? vvv,  vvv ?*)
   176 	val PblObj {origin = (_,_,hdf), spec,...} = get_obj I pt p
   177     in (pt, (complete, Pbl, hdf, pits, pre, spec):ocalhd) end;
   178 
   179 fun set_theory (tI:thyID) (ptp: ptree * pos') =
   180     let val ([(_, Specify_Problem' (_, (complete, (pits, pre))),_)],
   181 	     _, (pt, pos as (p,_))) = nxt_specif (Specify_Theory tI) ptp
   182 	(*from Specify_Theory'  ? vvv,  vvv ?*)
   183 	val PblObj {origin = (_,_,hdf), spec,...} = get_obj I pt p
   184     in (pt, (complete, Pbl, hdf, pits, pre, spec):ocalhd) end;
   185 
   186 (* does a step forward; returns tactic used, ctree updated.
   187 TODO.WN0512 redesign after specify-phase became more separated from solve-phase *)
   188 fun step ((ip as (_,p_)):pos') ((ptp as (pt,p), tacis):calcstate) =
   189   let val pIopt = get_pblID (pt,ip);
   190   in
   191     if ip = ([],Res)
   192     then ("end-of-calculation", (tacis, [], ptp):calcstate') 
   193     else
   194       case tacis of
   195 	      (_::_) => 
   196           if ip = p (*the request is done where ptp waits for*)
   197 	        then 
   198             let val (pt',c',p') = generate tacis (pt,[],p)
   199 		        in ("ok", (tacis, c', (pt', p'))) end
   200 	        else (case (if member op = [Pbl,Met] p_
   201 		                  then nxt_specify_ (pt,ip) else nxt_solve_ (pt,ip))
   202 		                  handle ERROR msg => (writeln ("*** " ^ msg);
   203 		                    ([],[],ptp))(*e.g. Add_Given "equality///"*) of
   204 		              cs as ([],_,_) => ("helpless", cs)
   205 		            | cs => ("ok", cs))
   206 	    | _ => (case pIopt of
   207 		            NONE => ("no-fmz-spec", ([], [], ptp))
   208 		          | SOME pI =>
   209 		            (case if member op = [Pbl,Met] p_
   210 			                   andalso is_none (get_obj g_env pt (fst p))
   211 			                        (*^^^^^^^^: Apply_Method without init_form*)
   212 			                 then nxt_specify_ (pt, ip) 
   213                        else (nxt_solve_ (pt,ip) )
   214 		                     handle ERROR msg => (writeln ("*** " ^ msg);
   215 		                     ([],[],ptp))(*e.g. Add_Given "equality///"*) of
   216 		               cs as ([],_,_) =>("helpless", cs)(*FIXXMEdel.handle*)
   217 			           | cs => ("ok", cs)))
   218   end;
   219 
   220 (*.does several steps within one calculation as given by "type auto";
   221    the steps may arbitrarily go into and leave different phases, 
   222    i.e. specify-phase and solve-phase.*)
   223 (*TODO.WN0512 ? redesign after the phases have been more separated
   224   at the fron-end in 05: 
   225   eg. CompleteCalcHead could be done by a separate fun !!!*)
   226 fun autocalc c ip (cs as (ptp as (_,p),tacis)) (Step s) =
   227     if s <= 1
   228     then let val (str, (_, c', ptp)) = step ip cs;(*1*)
   229 	 (*at least does 1 step, ev.1 too much*)
   230 	 in (str, c@c', ptp) end
   231     else let val (str, (_, c', ptp as (_, p))) = step ip cs;
   232 	 in if str = "ok" 
   233 	    then autocalc (c@c') p (ptp,[]) (Step (s-1))
   234 	    else (str, c@c', ptp) end
   235 (* handles autoord <= 3, autoord > 3 handled by all_/complete_solve *)
   236   | autocalc c (pos as (_,p_)) ((pt,_), _(*tacis would help 1x in solve*))auto =
   237      if autoord auto > 3 andalso just_created (pt, pos)
   238      then let val ptp = all_modspec (pt, pos);
   239 	  in all_solve auto c ptp end
   240      else
   241 	 if member op = [Pbl, Met] p_
   242  	 then if not (is_complete_mod (pt, pos))
   243 	      then let val ptp = complete_mod (pt, pos)
   244 		   in if autoord auto < 3 then ("ok", c, ptp)
   245 		      else 
   246 			  if not (is_complete_spec ptp)
   247 			  then let val ptp = complete_spec ptp
   248 			       in if autoord auto = 3 then ("ok", c, ptp)
   249 				  else all_solve auto c ptp
   250 			       end
   251 			  else if autoord auto = 3 then ("ok", c, ptp)
   252 			  else all_solve auto c ptp 
   253 		   end
   254 	      else 
   255 		  if not (is_complete_spec (pt,pos))
   256 		  then let val ptp = complete_spec (pt, pos)
   257 		       in if autoord auto = 3 then ("ok", c, ptp)
   258 			  else all_solve auto c ptp
   259 		       end
   260 		  else if autoord auto = 3 then ("ok", c, (pt, pos))
   261 		  else all_solve auto c (pt, pos)
   262 	 else complete_solve auto c (pt, pos);
   263 (* val pbl = get_obj g_pbl (fst ptp) [];
   264    val (oris,_,_) = get_obj g_origin (fst ptp) [];
   265 *)    
   266 
   267 
   268 
   269 
   270 
   271 (*.initialiye matching; before 'tryMatch' get the pblID to match with:
   272    if no pbl has been specified, take the init from origin.*)
   273 (*fun initmatch pt (pos as (p,_):pos') =
   274     let val PblObj {probl,origin=(os,(_,pI,_),_),spec=(dI',pI',mI'),...} = 
   275 	    get_obj I pt p
   276 	val pblID = if pI' = e_pblID 
   277 		    then (*TODO.WN051125 (#init o get_pbt) pI          <<<*) 
   278 			takelast (2, pI) (*FIXME.WN051125 a hack, impl.^^^*)
   279 		    else pI'
   280 	val spec = (dI',pblID,mI')
   281 	val {ppc,where_,prls,...} = get_pbt pblID
   282 	val (model_ok, (pbl, pre)) = 
   283 	    match_itms_oris (assoc_thy "Isac") probl (ppc,where_,prls) os
   284     in ModSpec (ocalhd_complete pbl pre spec,
   285 		Pbl, e_term, pbl, pre, spec) end;*)
   286 fun initcontext_pbl pt (pos as (p,_):pos') =
   287     let val PblObj {probl,origin=(os,(_,pI,_),hdl),spec=(dI',pI',mI'),...} = 
   288 	    get_obj I pt p
   289 	val pblID = if pI' = e_pblID 
   290 		    then (*TODO.WN051125 (#init o get_pbt) pI          <<<*) 
   291 			takelast (2, pI) (*FIXME.WN051125 a hack, impl.^^^*)
   292 		    else pI'
   293 	val {ppc,where_,prls,...} = get_pbt pblID
   294 	val (model_ok, (pbl, pre)) = 
   295 	    match_itms_oris (assoc_thy "Isac") probl (ppc,where_,prls) os
   296     in (model_ok, pblID, hdl, pbl, pre) end;
   297 
   298 fun initcontext_met pt (pos as (p,_):pos') =
   299     let val PblObj {meth,origin=(os,(_,_,mI), _),spec=(_, _, mI'),...} = 
   300 	    get_obj I pt p
   301 	val metID = if mI' = e_metID 
   302 		    then (*TODO.WN051125 (#init o get_pbt) pI          <<<*) 
   303 			takelast (2, mI) (*FIXME.WN051125 a hack, impl.^^^*)
   304 		    else mI'
   305 	val {ppc,pre,prls,scr,...} = get_met metID
   306 	val (model_ok, (pbl, pre)) = 
   307 	    match_itms_oris (assoc_thy "Isac") meth (ppc,pre,prls) os
   308     in (model_ok, metID, scr, pbl, pre) end;
   309 
   310 (*.match the model of a problem at pos p 
   311    with the model-pattern of the problem with pblID*)
   312 fun context_pbl pI pt (p:pos) =
   313     let val PblObj {probl,origin=(os,_,hdl),...} = get_obj I pt p
   314 	val {ppc,where_,prls,...} = get_pbt pI
   315 	val (model_ok, (pbl, pre)) = 
   316 	    match_itms_oris (assoc_thy "Isac") probl (ppc,where_,prls) os
   317     in (model_ok, pI, hdl, pbl, pre) end;
   318 
   319 fun context_met mI pt (p:pos) =
   320     let val PblObj {meth,origin=(os,_,hdl),...} = get_obj I pt p
   321 	val {ppc,pre,prls,scr,...} = get_met mI
   322 	val (model_ok, (pbl, pre)) = 
   323 	    match_itms_oris (assoc_thy "Isac") meth (ppc,pre,prls) os
   324     in (model_ok, mI, scr, pbl, pre) end
   325 
   326 
   327 (* val (pI, pt, pos as (p,_)) = (pblID, pt, p);
   328    *)
   329 fun tryrefine pI pt (pos as (p,_):pos') =
   330     let val PblObj {probl,origin=(os,_,hdl),...} = get_obj I pt p
   331     in case refine_pbl (assoc_thy "Isac") pI probl of
   332 	   NONE => (*copy from context_pbl*)
   333 	   let val {ppc,where_,prls,...} = get_pbt pI
   334 	       val (_, (pbl, pre)) = match_itms_oris (assoc_thy "Isac") 
   335 						     probl (ppc,where_,prls) os
   336 	   in (false, pI, hdl, pbl, pre) end
   337 	 | SOME (pI, (pbl, pre)) => 
   338 	   (true, pI, hdl, pbl, pre) 
   339     end;
   340 
   341 fun detailstep pt (pos as (p,p_):pos') = 
   342   let 
   343     val nd = get_nd pt p
   344     val cn = children nd
   345   in 
   346     if null cn 
   347     then if (is_rewset o (get_obj g_tac nd)) [(*root of nd*)]
   348       then detailrls pt pos
   349       else ("no-Rewrite_Set...", EmptyPtree, e_pos')
   350     else ("donesteps", pt,
   351     (p @ [length (children (get_nd pt p))], Res) ) 
   352   end;
   353 
   354 
   355 (***. for mathematics authoring on sml-toplevel; no XML .***)
   356 
   357 type NEW = int list;
   358 (* val sp = (dI',pI',mI');
   359    *)
   360 
   361 (*15.8.03 for me with loc_specify/solve, nxt_specify/solve
   362  delete as soon as TESTg_form -> _mout_ dropped*)
   363 fun TESTg_form ptp =
   364 (* val ptp = (pt,p);
   365    *) 
   366     let val (form,_,_) = pt_extract ptp
   367     in case form of
   368 	   Form t => Form' (FormKF (~1,EdUndef,0,Nundef,term2str t))
   369 	 | ModSpec (_,p_, head, gfr, pre, _) => 
   370 	   Form' (PpcKF (0,EdUndef,0,Nundef,
   371 			 (case p_ of Pbl => Problem[] | Met => Method[],
   372 			  itms2itemppc (assoc_thy"Isac") gfr pre)))
   373     end;
   374 
   375 (*.create a calc-tree; for use within sml: thus ^^^ NOT decoded to ^;
   376    compare "fun CalcTree" which DOES decode.*)
   377 fun CalcTreeTEST [(fmz, sp):fmz] = 
   378   let
   379     val cs as ((pt,p), tacis) = nxt_specify_init_calc (fmz, sp)
   380 	  val tac = case tacis of [] => Empty_Tac | _ => (#1 o hd) tacis
   381 	  val f = TESTg_form (pt,p)
   382   in (p, []:NEW, f, (tac2IDstr tac, tac), Sundef, pt) end; 
   383        
   384 (*for tests > 15.8.03 after separation setnexttactic / nextTac:
   385   external view: me should be used by math-authors as done so far
   386   internal view: loc_specify/solve, nxt_specify/solve used
   387                  i.e. same as in setnexttactic / nextTac*)
   388 (*ENDE TESTPHASE 08/10.03:
   389   NEW loeschen, eigene Version von locatetac, step
   390   meNEW, CalcTreeTEST: tac'_ -replace-> tac, remove [](cid) *)
   391 
   392 fun me ((_,tac):tac'_) (p:pos') (_:NEW(*remove*)) (pt:ptree) =
   393   let 
   394     val (pt, p) = 
   395 	    (*locatetac is here for testing by me; step would suffice in me*)
   396 	    case locatetac tac (pt,p) of
   397 		    ("ok", (_, _, ptp)) => ptp
   398 	    | ("unsafe-ok", (_, _, ptp)) => ptp
   399 	    | ("not-applicable",_) => (pt, p)
   400 	    | ("end-of-calculation", (_, _, ptp)) => ptp
   401 	    | ("failure",_) => error "sys-error";
   402 	  val (_, ts) =
   403 	    (case step p ((pt, e_pos'),[]) of
   404 		    ("ok", (ts as (tac,_,_)::_, _, _)) => ("",ts)
   405 	    | ("helpless",_) => ("helpless: cannot propose tac", [])
   406 	    | ("no-fmz-spec",_) => error "no-fmz-spec"
   407 	    | ("end-of-calculation", (ts, _, _)) => ("",ts))
   408 	    handle ERROR msg => raise ERROR msg
   409 	  val tac = 
   410       case ts of 
   411         tacis as (_::_) => let val (tac,_,_) = last_elem tacis in tac end 
   412 		  | _ => if p = ([],Res) then End_Proof' else Empty_Tac;
   413   in (p:pos', []:NEW, TESTg_form (pt, p) (*form output comes from locatetac*), 
   414 	   (tac2IDstr tac, tac):tac'_, Sundef, pt) end;
   415 
   416 (*for quick test-print-out, until 'type inout' is removed*)
   417 fun f2str (Form' (FormKF (_, _, _, _, cterm'))) = cterm';
   418 
   419 
   420 
   421 (*------------------------------------------------------------------(**)
   422 end
   423 open MathEngine;
   424 (**)------------------------------------------------------------------*)
   425