src/Tools/isac/ProgLang/rewrite.sml
author Walther Neuper <wneuper@ist.tugraz.at>
Fri, 23 Feb 2018 07:29:36 +0100
changeset 59380 8b08d9296654
parent 59352 172b53399454
child 59381 cb7e75507c05
permissions -rw-r--r--
separate structure Rewrite : REWRITE
     1 (* isac's rewriter
     2    (c) Walther Neuper 2000
     3 *)
     4 
     5 signature REWRITE =
     6   sig
     7     val assoc_thm': theory -> thm' -> thm
     8     val assoc_thm'': theory -> thmID -> thm
     9     val calculate_: theory -> string * eval_fn -> term -> (term * (string * thm)) option
    10     val eval__true: theory -> int -> term list -> (term * term) list -> rls -> term list * bool
    11     val eval_listexpr_: theory -> rls -> term -> term
    12     val eval_true: theory -> term list -> rls -> bool
    13     val eval_true_: theory' -> rls -> term -> bool
    14     val rew_sub: theory -> int -> (term * term) list -> ((term * term) list -> term * term -> bool) -> rls -> bool -> lrd list -> term -> term -> term * term list * lrd list * bool
    15     val rewrite_: theory -> ((term * term) list -> term * term -> bool) -> rls -> bool -> thm -> term -> (term * term list) option
    16     val rewrite_inst_: theory -> ((term * term) list -> term * term -> bool) -> rls -> bool -> (term * term) list -> thm -> term -> (term * term list) option
    17     val rewrite_set_: theory -> bool -> rls -> term -> (term * term list) option
    18     val rewrite_set_inst_: theory -> bool -> (term * term) list -> rls -> term -> (term * term list) option
    19     val rewrite_terms_: theory -> ((term * term) list -> term * term -> bool) -> rls -> term list -> term -> (term * term list) option
    20 (* ---- for tests only: shifted from below to remove the Warning "unused" at fun.def. --------- *)
    21   (* NONE *)
    22 (*/-------------------------------------------------------- ! aktivate for Test_Isac BEGIN ---\* )
    23   (* NONE *)
    24 (* probably shift up ---------------
    25     exception NO_REWRITE
    26     exception STOP_REW_SUB
    27     val adhoc_thm': theory' -> string * eval_fn -> cterm' -> thm' option
    28     val app_rev: theory -> int -> rls -> term -> term * term list * bool
    29     val app_sub: theory -> int -> rls -> term -> term * term list * bool
    30     val calculate: theory' -> string * eval_fn -> cterm' -> (string * thm') option
    31     val convert: 'a -> string -> string
    32     val convert_metaview_to_thmid: theory -> string -> thm
    33     val eval_true': theory' -> rls' -> term -> bool
    34     val get_rls_scr: rls' -> scr
    35     val mk_thm: theory -> string -> thm
    36     val mk_thm'': theory -> term -> thm
    37     val parse': theory' -> cterm' -> cterm' option
    38     val rewrite: theory' -> rew_ord' -> rls' -> bool -> thm' -> cterm' -> (string * string) option
    39     val rewrite__: theory -> int -> (term * term) list -> ((term * term) list -> term * term -> bool) -> rls -> bool -> thm -> term -> (term * term list) option
    40     val rewrite__set_: theory -> int -> bool -> (term * term) list -> rls -> term -> (term * term list) option
    41     val rewrite_inst: theory' -> rew_ord' -> rls' -> bool -> 'a -> thm' -> cterm' -> (cterm' * cterm' list) option
    42     val rewrite_set: theory' -> bool -> rls' -> cterm' -> (string * string) option
    43     val rewrite_set_inst: theory' -> bool -> subs' -> rls' -> cterm' -> (string * string) option
    44     val subs'2subst: theory -> subs' -> subst
    45     val trace: int -> string -> unit
    46     val trace1: int -> string -> unit
    47 --------------------------------------*)
    48 ( *\--- ! aktivate for Test_Isac END ----------------------------------------------------------/*)
    49   end
    50 
    51 (**)
    52 structure Rewrite(**): REWRITE(**) =
    53 struct
    54 (**)
    55 
    56 exception NO_REWRITE;
    57 exception STOP_REW_SUB; (*WN050820 quick and dirty*)
    58 
    59 fun trace i str = 
    60   if ! trace_rewrite andalso i < ! depth then tracing (idt "#" i ^ str) else ()
    61 fun trace1 i str = 
    62   if ! trace_rewrite andalso i < ! depth then tracing (idt "#" (i + 1) ^ str) else ()
    63 
    64 (* 
    65 Synopsis rewriting (prep for reference manual):
    66 ----------------------------------------------
    67 Rewriting uses theorems for transforming terms. However, not all kinds
    68 of such transformations can be done by rewriting. Examples are
    69 calculation with numerals or cancellation of fractions. 
    70 
    71 Isac tries to present transformations like calculations or cancellation 
    72 as simple rewrite steps for the naive user. However, some of such
    73 transformations should be transparent to the user by single-stepping.
    74 For instance, cancellation involves interesting CA algorithms like 
    75 GCD of multivariate polynomials.
    76 
    77 Thus Isac has two mechanisms for including SML code, "thm Calc" and "Rrls",
    78 the former for steps which are not meant to be inspected by single-stepping
    79 the latter meant for single-stepping and providing respective mechanisms.
    80 
    81 (1) Inclusion by "thm Calc" for 1-step execution
    82 TODO
    83 
    84 (2) Inclusion by "Rrls" for multi-step execution
    85 TODO
    86 In multi-step execution "reverse rewriting" worked only as passive presentation
    87 without any interaction. So the functions init_state, locate_rule etc are just dummies.
    88 TODO
    89 ? multi-step execution did never work.
    90 what worked is "reverse rewriting", 
    91 i.e. presentation of intermediate steps *without* interaction
    92 TODO
    93 # type rule and scr | Rfuns
    94 # type rrlsstate = (*state for reverse rewriting*) 
    95 # type and rls | Rrls
    96 all in calcelems.sml
    97 TODO
    98 *)
    99 fun rewrite__ thy i bdv tless rls put_asm thm ct =
   100   (let
   101     val (t',asms,lrd,rew) = 
   102 	rew_sub thy i bdv tless rls put_asm [(*root of the term*)]
   103 		(((inst_bdv bdv) o norm o #prop o Thm.rep_thm) thm) ct;
   104   in if rew then SOME (t', distinct asms)
   105      else NONE end)
   106 (* one rewrite (possibly conditional, ordered) EXOR exn EXOR go into subterms *)
   107 and rew_sub thy i bdv tless rls put_asm lrd r t = 
   108   ((*tracing ("@@@ rew_sub begin: t = "^(term2str t));
   109    tracing ("@@@ rew_sub begin: bdv = "^(@{make_string} bdv));
   110    tracing ("@@@ rew_sub begin: r = "^(term2str r));*)
   111     let                  (* copy from Pure/thm.ML: fun rewritec *)
   112      val (lhs, rhs) = (HOLogic.dest_eq o HOLogic.dest_Trueprop
   113                        o Logic.strip_imp_concl) r;
   114      (*?alternative Unify.matchers:
   115        http://isabelle.in.tum.de/repos/isabelle/file/Isabelle2017/src/Pure/more_unify.ML*)
   116      val r' = Envir.subst_term (Pattern.match thy (lhs, t) 
   117 					      (Vartab.empty, Vartab.empty)) r;
   118      val p' = map HOLogic.dest_Trueprop ((fst o Logic.strip_prems) 
   119                                              (Logic.count_prems r', [], r'));
   120      val t' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop 
   121                o Logic.strip_imp_concl) r';
   122      (*val _= tracing("@@@ rew_sub match: t'= "^(term2str t'));*)
   123      val _= if ! trace_rewrite andalso i < ! depth andalso p' <> []
   124 	    then tracing((idt"#"(i+1))^" eval asms: "^(term2str r')) else();
   125      val (t'',p'') =                                   (*conditional rewriting*)
   126 	 let val (simpl_p', nofalse) = eval__true thy (i+1) p' bdv rls 	     
   127 	 in if nofalse
   128 	    then (if ! trace_rewrite andalso i < ! depth andalso p' <> []
   129 		  then tracing((idt"#"(i+1))^" asms accepted: "^(terms2str p')^
   130 			       "   stored: "^(terms2str simpl_p'))
   131 		  else(); (t',simpl_p'))             (* uncond.rew. from above*)
   132 	    else 
   133 		(if ! trace_rewrite andalso i < ! depth 
   134 		 then tracing((idt"#"(i+1))^" asms false: "^(terms2str p')) 
   135 		 else(); raise STOP_REW_SUB (*dont go into subterms of cond*))
   136 	 end
   137    in if perm lhs rhs andalso not (tless bdv (t',t))       (*ordered rewriting*)
   138 	then (if ! trace_rewrite andalso i < ! depth 
   139 	      then tracing((idt"#"i)^" not: \""^
   140 	      (term2str t)^"\" > \""^
   141 	      (term2str t')^"\"") else (); 
   142 	      raise NO_REWRITE )
   143 	else ((*tracing("##@ rew_sub: (t''= "^(term2str t'')^
   144 		      ", p'' ="^(terms2str p'')^", true)");*)
   145 	      (t'',p'',[],true))
   146    end
   147    ) handle _ (*NO_REWRITE WN050820 causes diff.behav. in tests + MATCH!*) => 
   148      ((*tracing ("@@@ rew_sub gosub: t = "^(term2str t));*)
   149       case t of
   150 	Const(s,T) => (Const(s,T),[],lrd,false)
   151       | Free(s,T) => (Free(s,T),[],lrd,false)
   152       | Var(n,T) => (Var(n,T),[],lrd,false)
   153       | Bound i => (Bound i,[],lrd,false)
   154       | Abs(s,T,body) => 
   155 	  let val (t', asms, lrd, rew) = 
   156 		  rew_sub thy i bdv tless rls put_asm (lrd@[D]) r body
   157 	  in (Abs(s,T,t'), asms, [], rew) end
   158       | t1 $ t2 => 
   159 	  let val (t2', asm2, lrd, rew2) = 
   160 		  rew_sub thy i bdv tless rls put_asm (lrd@[R]) r t2
   161 	  in if rew2 then (t1 $ t2', asm2, lrd, true)
   162 	     else let val (t1', asm1, lrd, rew1) = 
   163 	       rew_sub thy i bdv tless rls put_asm (lrd@[L]) r t1
   164 		  in if rew1 then (t1' $ t2, asm1, lrd, true)
   165 		     else (t1 $ t2,[], lrd, false) end
   166 	  end)
   167 (* simplify asumptions until one evaluates to false, store intermined's (x~=0)*)
   168 and eval__true thy i asms bdv rls =
   169   if asms = [@{term True}] orelse asms = [] then ([], true)
   170   (* this allows to check Rrls with prepat = ([@{term True}], pat) *)
   171   else if asms = [@{term False}] then ([], false) else
   172     let                            
   173       fun chk indets [] = (indets, true)(*return asms<>True until false*)
   174         | chk indets (a::asms) =
   175           (case rewrite__set_ thy (i + 1) false bdv rls a of
   176             NONE => (chk (indets @ [a]) asms)
   177           | SOME (t, a') =>
   178             if t = @{term True} then (chk (indets @ a') asms) 
   179             else if t = @{term False} then ([], false)
   180           (*asm false .. thm not applied ^^^; continue until False vvv*)
   181           else chk (indets @ [t] @ a') asms);
   182     in chk [] asms end
   183 (* rewrite with a rule set, which must not be the empty Erls *)
   184 and rewrite__set_ _ _ __ Erls t = 
   185     error ("rewrite__set_ called with 'Erls' for '" ^ term2str t ^ "'")
   186   (* rewrite with a 'reverse rule set' implemented by ML code *)
   187   | rewrite__set_ thy i _ _ (rrls as Rrls _) t =
   188     let
   189       val _= trace i (" rls: " ^ id_rls rrls ^ " on: " ^ term2str t)
   190 	    val (t', asm, rew) = app_rev thy (i + 1) rrls t
   191     in if rew then SOME (t', distinct asm) else NONE end
   192   (* rewrite with a rule set containing Thms or Calculations *)
   193   | rewrite__set_ thy i put_asm bdv rls ct =
   194     let
   195       datatype switch = Appl | Noap;
   196       fun rew_once ruls asm ct Noap [] = (ct, asm) (* unify with version in rewtools.sml *)
   197         | rew_once ruls asm ct Appl [] = 
   198           (case rls of Rls _ => rew_once ruls asm ct Noap ruls
   199           | Seq _ => (ct, asm))
   200         | rew_once ruls asm ct apno (rul::thms) =
   201           case rul of
   202             Thm (thmid, thm) =>
   203               (trace1 i (" try thm: " ^ thmid);
   204               case rewrite__ thy (i + 1) bdv ((snd o #rew_ord o rep_rls) rls)
   205                   ((#erls o rep_rls) rls) put_asm thm ct of
   206                 NONE => rew_once ruls asm ct apno thms
   207               | SOME (ct',asm') => 
   208                 (trace1 i (" rewrites to: " ^ term2str ct');
   209                 rew_once ruls (union (op =) asm asm') ct' Appl (rul::thms)))
   210           | Calc (cc as (op_, _)) => 
   211             let val _= trace1 i (" try calc: " ^ op_ ^ "'")
   212               val ct = uminus_to_string ct
   213             in case adhoc_thm thy cc ct of
   214                 NONE => rew_once ruls asm ct apno thms
   215               | SOME (thmid, thm') => 
   216                 let 
   217                   val pairopt = rewrite__ thy (i + 1) bdv ((snd o #rew_ord o rep_rls) rls)
   218                     ((#erls o rep_rls) rls) put_asm thm' ct;
   219                   val _ = if pairopt <> NONE then () else error ("rewrite_set_, rewrite_ \"" ^ 
   220                     string_of_thmI thm' ^ "\" " ^ term2str ct ^ " = NONE")
   221                   val _ = trace1 i (" calc. to: " ^ term2str ((fst o the) pairopt))
   222                 in rew_once ruls asm ((fst o the) pairopt) Appl (rul :: thms) end
   223             end
   224           | Cal1 (cc as (op_, _)) => 
   225             let val _= trace1 i (" try cal1: " ^ op_ ^ "'");
   226               val ct = uminus_to_string ct
   227             in case adhoc_thm1_ thy cc ct of
   228                 NONE => (ct, asm)
   229               | SOME (thmid, thm') =>
   230                 let 
   231                   val pairopt = rewrite__ thy (i + 1) bdv ((snd o #rew_ord o rep_rls) rls)
   232                     ((#erls o rep_rls) rls) put_asm thm' ct;
   233                   val _ = if pairopt <> NONE then () else error ("rewrite_set_, rewrite_ \"" ^
   234                      string_of_thmI thm' ^ "\" " ^ term2str ct ^ " = NONE")
   235                   val _ = trace1 i (" cal1. to: " ^ term2str ((fst o the) pairopt))
   236                 in the pairopt end
   237             end
   238           | Rls_ rls' => 
   239             (case rewrite__set_ thy (i + 1) put_asm bdv rls' ct of
   240               SOME (t', asm') => rew_once ruls (union (op =) asm asm') t' Appl thms
   241             | NONE => rew_once ruls asm ct apno thms);
   242       val ruls = (#rules o rep_rls) rls;
   243       val _= trace i (" rls: " ^ id_rls rls ^ " on: " ^ term2str ct)
   244       val (ct', asm') = rew_once ruls [] ct Noap ruls;
   245 	  in if ct = ct' then NONE else SOME (ct', distinct asm') end
   246 
   247 (* apply an Rrls; if not applicable proceed with subterms *)
   248 and app_rev thy i rrls t = 
   249   let (* check a (precond, pattern) of a rev-set; stops with 1st true *)
   250     fun chk_prepat thy erls [] t = true
   251       | chk_prepat thy erls prepat t =
   252         let
   253           fun chk (pres, pat) =
   254             (let 
   255               val subst: Type.tyenv * Envir.tenv =
   256                 Pattern.match thy (pat, t) (Vartab.empty, Vartab.empty)
   257              in
   258               snd (eval__true thy (i + 1) (map (Envir.subst_term subst) pres) [] erls)
   259              end) handle _ => false
   260            fun scan_ f [] = false (*scan_ NEVER called by []*)
   261              | scan_ f (pp::pps) =
   262                if f pp then true else scan_ f pps;
   263         in scan_ chk prepat end;
   264     (* apply the normal_form of a rev-set *)
   265     fun app_rev' thy (Rrls {erls, prepat, scr = Rfuns {normal_form, ...}, ...}) t =
   266       if chk_prepat thy erls prepat t then normal_form t else NONE;
   267     val opt = app_rev' thy rrls t
   268   in
   269     case opt of
   270       SOME (t', asm) => (t', asm, true)
   271     | NONE => app_sub thy i rrls t
   272   end
   273 
   274 (* apply an Rrls to subterms *)
   275 and app_sub thy i rrls t =
   276   ((*tracing("### app_sub: subterm = "^(term2str t));*)
   277   case t of
   278     Const (s, T) => (Const(s, T), [], false)
   279   | Free (s, T) => (Free(s, T), [], false)
   280   | Var (n, T) => (Var(n, T), [], false)
   281   | Bound i => (Bound i, [], false)
   282   | Abs (s, T, body) => 
   283 	  let val (t', asm, rew) = app_rev thy i rrls body
   284 	  in (Abs(s, T, t'), asm, rew) end
   285   | t1 $ t2 => 
   286     let val (t2', asm2, rew2) = app_rev thy i rrls t2
   287     in
   288       if rew2 then (t1 $ t2', asm2, true)
   289       else
   290         let val (t1', asm1, rew1) = app_rev thy i rrls t1
   291         in if rew1 then (t1' $ t2, asm1, true)
   292            else (t1 $ t2, [], false)
   293         end
   294     end);
   295 
   296 
   297 
   298 (*.rewriting without argument [] for rew_ord.*)
   299 (*WN.11.6.03: shouldnt asm<>[] lead to false ????*)
   300 fun eval_true thy terms rls = (snd o (eval__true thy 1 terms [])) rls;
   301 
   302 (* rewriting without internal argument [] *)
   303 fun rewrite_ thy rew_ord erls bool thm term = rewrite__ thy 1 [] rew_ord erls bool thm term;
   304 fun rewrite_set_ thy bool rls term = rewrite__set_ thy 1 bool [] rls term;
   305 
   306 fun subs'2subst thy (s:subs') = 
   307     (((map (apfst (Thm.term_of o the o (parse thy)))) 
   308      o (map (apsnd (Thm.term_of o the o (parse thy))))) s):subst;
   309 
   310 (*.variants of rewrite.*)
   311 (*FIXME 12.8.02: put_asm = true <==> rewrite_inst,
   312   thus the argument put_asm  IS NOT NECESSARY -- FIXME*)
   313 (* val (rew_ord,rls,put_asm,thm,ct)=
   314        (e_rew_ord,poly_erls,false,num_str d1_isolate_add2,t);
   315    *)
   316 fun rewrite_inst_ (thy:theory) rew_ord (rls:rls) (put_asm:bool) 
   317 		  (subst:(term * term) list) (thm:thm) (ct:term) =
   318     rewrite__ thy 1 subst rew_ord rls put_asm thm ct;
   319 
   320 fun rewrite_set_inst_ (thy:theory) 
   321   (put_asm:bool) (subst:(term * term) list) (rls:rls) (ct:term) =
   322   (*let 
   323     val subst = subs'2subst thy subs';
   324     val subrls = instantiate_rls subs' rls
   325   in*) rewrite__set_ thy 1 put_asm subst (*sub*)rls ct
   326   (*end*);
   327 
   328 (* given a list of equalities (lhs = rhs) and a term, 
   329    replace all occurrences of lhs in the term with rhs;
   330    thus the order or equalities matters: put variables in lhs first. *)
   331 fun rewrite_terms_ thy ord erls equs t =
   332   let
   333 	  fun rew_ (t', asm') [] _ = (t', asm')
   334 	    | rew_ (t', asm') (rules as r::rs) t =
   335 	        let
   336 	          val (t'', asm'', lrd, rew) = rew_sub thy 1 [] ord erls false [] (Trueprop $ r) t
   337 	        in 
   338 	          if rew 
   339 	          then rew_ (t'', asm' @ asm'') rules t''
   340 	          else rew_ (t', asm') rs t'
   341 	        end
   342 	  val (t'', asm'') = rew_ (e_term, []) equs t
   343     in if t'' = e_term then NONE else SOME (t'', asm'')
   344     end;
   345 
   346 (*. search ct for adjacent numerals and calculate them by operator isa_fn .*)
   347 fun calculate_ thy isa_fn ct =
   348   let val ct = uminus_to_string ct
   349     in case adhoc_thm thy isa_fn ct of
   350 	   NONE => NONE
   351 	 | SOME (thmID, thm) => 
   352 	   (let val SOME (rew,_) = rewrite_ thy dummy_ord e_rls false thm ct
   353     in SOME (rew,(thmID, thm)) end)
   354 	   handle _ => error ("calculate_: "^thmID^" does not rewrite")
   355   end;
   356 (*
   357 > val thy = InsSort.thy;
   358 > val op_ = "le";      (* < *)
   359 > val ct = (the o (parse thy)) 
   360    "foldr ins [#2] (if #1 < #3 then #1 # ins [] #3 else [#3, #1])";
   361 > calculate_ thy op_ ct;
   362   SOME
   363     ("foldr ins [#2] (if True then #1 # ins [] #3 else [#3, #1])",
   364      "(#1 < #3) = True") : (cterm * thm) option  *)
   365 
   366 fun get_rls_scr rls' = ((#scr o rep_rls o assoc_rls) rls')
   367   handle _ => error ("get_rls_scr: no script for " ^ rls');
   368 
   369 (*Thm.make_thm added to Pure/thm.ML*)
   370 fun mk_thm'' thy t = 
   371     let val t' = case t of
   372 		     Const ("==>",_) $ _ $ _ => t
   373 		   | _ => Trueprop $ t
   374     in Thm.make_thm (Thm.global_cterm_of thy t') end;
   375 fun mk_thm thy str = 
   376     let val t = (Thm.term_of o the o (parse thy)) str
   377 	val t' = case t of
   378 		     Const ("==>",_) $ _ $ _ => t
   379 		   | _ => Trueprop $ t
   380     in Thm.make_thm (Thm.global_cterm_of thy t') end;
   381 (*
   382   val str = "?r ^^^ 2 = ?r * ?r";
   383   val thm = realpow_twoI;
   384 
   385   val t1 = (#prop o rep_thm) (num_str thm);
   386   val t2 = Trueprop $ ((Thm.term_of o the o (parse thy)) str);
   387   t1 = t2;
   388 val it = true : bool      ... !!!
   389   val th1 = (num_str thm);
   390   val th2 = ((*num_str*) (mk_thm thy str)) handle e => print_exn e;
   391   th1 = th2;
   392 ML> val it = false : bool ... HIDDEN DIFFERENCES IRRELEVANT FOR ISAC ?!
   393 
   394 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   395   val str = "k ~= 0 ==> m * k / (n * k) = m / n";
   396   val thm = real_mult_div_cancel2;
   397 
   398   val t1 = (#prop o rep_thm) (num_str thm);
   399   val t2 = ((Thm.term_of o the o (parse thy)) str);
   400   t1 = t2;
   401 val it = false : bool     ... Var .. Free
   402   val th1 = (num_str thm);
   403   val th2 = ((*num_str*) (mk_thm thy str)) handle e => print_exn e;
   404   th1 = th2;
   405 ML> val it = false : bool ... PLUS HIDDEN DIFFERENCES IRRELEVANT FOR ISAC ?!
   406 *)
   407 
   408 
   409 (*prints subgoal etc. 
   410 ((goal thy);(topthm()) o ) str;                      *)
   411 (*assume rejects scheme variables 
   412   assume ((Thm.global_cterm_of thy) (Trueprop $ 
   413 		(Thm.term_of o the o (parse thy)) str)); *)
   414 
   415 
   416 (* outcommented 18.11.xx, xx < 02 -------
   417 fun rul2rul' (Thm (thmid, thm)) = Thm'(thmid, string_of_thmI thm)
   418   | rul2rul' (Calc op_)         = Calc' op_;
   419 fun rul'2rul thy (Thm'(thmid, ct')) = 
   420        Thm (thmid, mk_thm thy ct')
   421   | rul'2rul thy' (Calc' op_)        = Calc op_;
   422 
   423 
   424 fun rls2rls' (Rls{preconds=preconds,rew_ord=rew_ord,rules=rules}:rls) =
   425   Rls'{preconds'= map string_of_cterm preconds,
   426        rew_ord' = fst rew_ord,
   427        rules'   = map rul2rul' rules}:rlsdat';
   428 
   429 fun rls'2rls thy' (Rls'{preconds'=preconds,rew_ord'=rew_ord,
   430 		   rules'=rules}:rlsdat') =
   431   let val thy = assoc_thy thy';
   432   in Rls{preconds = map (the o (parse thy)) preconds,
   433 	 rew_ord  = (rew_ord, the (assoc'(rew_ord',rew_ord))),
   434 	 rules    = map (rul'2rul thy) rules}:rls end;
   435 ------- *)
   436 
   437 (* "metaview" as seen from programs and from user input (both are parsed like terms presently) *)
   438 fun convert_metaview_to_thmid thy thmid =
   439   let val thmid' = case thmid of
   440       "add_commute" => "add.commute"
   441     | "mult_commute" => "mult.commute"
   442     | "add_left_commute" => "add.left_commute"
   443     | "mult_left_commute" => "mult.left_commute"
   444     | "add_assoc" => "add.assoc"
   445     | "mult_assoc" => "mult.assoc"
   446     | _ => thmid
   447   in (Global_Theory.get_thm thy) thmid' end;
   448 
   449 (* FIXME: the other direction below is probably concerned with this fun:
   450 thmID_of_derivation_name' @{thm add.assoc} = "assoc"    TODO: repair this fun *);
   451 
   452 fun convert thmid_to_metaview thmid =
   453   case thmid of
   454       "add.commute" => "add_commute"
   455     | "mult.commute" => "mult_commute"
   456     | "add.left_commute" => "add_left_commute"
   457     | "mult.left_commute" => "mult_left_commute"
   458     | "add.assoc" => "add_assoc"
   459     | "mult.assoc" => "mult_assoc"
   460     | _ => thmid;
   461 
   462 (*.get the theorem associated with the xstring-identifier;
   463    if the identifier starts with "sym_" then swap lhs = rhs around =
   464    (ATTENTION: "RS sym" attaches a [.] -- remove it with string_of_thmI);
   465    identifiers starting with "#" come from Calc and
   466    get a hand-made theorem (containing numerals only).*)
   467 fun assoc_thm'' (thy : theory) (thmid : thmID) =
   468   case Symbol.explode thmid of
   469     "s"::"y"::"m"::"_"::"#"::_ => error ("assoc_thm'' not impl.for " ^ thmid)
   470   | "s"::"y"::"m"::"_"::id => ((num_str o (Global_Theory.get_thm thy)) (implode id)) RS sym
   471   | "#"::_ => error ("assoc_thm'' not impl.for " ^ thmid)
   472   | _ => thmid |> convert_metaview_to_thmid thy |> num_str
   473 fun assoc_thm' (thy:theory) ((thmid, ct'):thm') =
   474   (case Symbol.explode thmid of
   475     "s"::"y"::"m"::"_"::id => 
   476       if hd id = "#" 
   477       then mk_thm thy ct'
   478       else ((num_str o (Global_Theory.get_thm thy)) (implode id)) RS sym
   479   | id =>
   480     if hd id = "#" 
   481     then mk_thm thy ct'
   482     else thmid |> convert_metaview_to_thmid thy |> num_str
   483   ) handle _ (*TODO: fin exn behind ERROR: Undefined fact: "add_commute"*) => 
   484     error ("assoc_thm': \"" ^ thmid ^ "\" not in \"" ^ theory2domID thy ^ "\" (and parents)")
   485 
   486 fun parse' (thy:theory') (ct:cterm') =
   487     case parse (assoc_thy thy) ct of
   488 	NONE => NONE
   489       | SOME ct => SOME ((term2str (Thm.term_of ct)):cterm');
   490 
   491 
   492 (*FIXME 12.8.02: put_asm = true <==> rewrite_inst, rewrite_set_inst
   493   thus the argument put_asm  IS NOT NECESSARY -- FIXME        ~~~~~*)
   494 fun rewrite (thy':theory') (rew_ord:rew_ord') (rls:rls') (put_asm:bool) (thm:thm') (ct:cterm') =
   495   let val thy = assoc_thy thy';
   496   in
   497     case rewrite_ thy ((the o assoc')(!rew_ord',rew_ord))(assoc_rls rls)
   498       put_asm ((assoc_thm' thy) thm) ((Thm.term_of o the o (parse thy)) ct) of
   499       NONE => NONE
   500     | SOME (t, ts) => SOME (term2str t, terms2str ts)
   501   end;
   502 
   503 (*FIXME 12.8.02: put_asm = true <==> rewrite_inst, rewrite_set_inst
   504   thus the argument put_asm  IS NOT NECESSARY -- FIXME        ~~~~~*)
   505 fun rewrite_set (thy':theory') (put_asm:bool) (rls:rls') (ct:cterm') =
   506   let val thy = (assoc_thy thy');
   507   in
   508     case rewrite_set_ thy put_asm (assoc_rls rls) ((Thm.term_of o the o (parse thy)) ct) of
   509       NONE => NONE
   510     | SOME (t, ts) => SOME (term2str t, terms2str ts)
   511   end;
   512 
   513 fun eval_listexpr_ thy srls t =
   514   let val rew = rewrite_set_ thy false srls t;
   515   in case rew of SOME (res,_) => res | NONE => t end;
   516 
   517 fun adhoc_thm' (thy:theory') op_ (ct:cterm') =
   518    case adhoc_thm (assoc_thy thy) op_
   519     ((uminus_to_string o Thm.term_of o the o 
   520       (parse (assoc_thy thy))) ct) of
   521 	NONE => NONE
   522       | SOME (thmid, thm) => 
   523 	    SOME ((thmid, string_of_thmI thm):thm');
   524 
   525 fun calculate (thy':theory') op_ (ct:cterm') =
   526     let val thy = (assoc_thy thy');
   527     in
   528 	case calculate_ thy op_
   529 			((Thm.term_of o the o (parse thy)) ct) of
   530 	    NONE => NONE
   531 	  | SOME (ct,(thmID,thm)) => 
   532 	    SOME (term2str ct, 
   533 		  (thmID, string_of_thmI thm):thm')
   534     end;
   535 
   536 (*FIXME 12.8.02: put_asm = true <==> rewrite_inst, rewrite_set_inst
   537   thus the argument put_asm  IS NOT NECESSARY -- FIXME        ~~~~~*)
   538 fun rewrite_inst (thy':theory') (rew_ord:rew_ord') (rls:rls') 
   539   (put_asm:bool) subs (thm:thm') (ct:cterm') =
   540   let
   541     val thy = assoc_thy thy';
   542     val thm = assoc_thm' thy thm; (*28.10.02*)
   543     (*val subthm = read_instantiate subs ((assoc_thm' thy) thm)*)
   544   in
   545     case rewrite_ thy
   546       ((the o assoc')(!rew_ord',rew_ord)) (assoc_rls rls)
   547       put_asm (*sub*)thm ((Thm.term_of o the o (parse thy)) ct) of
   548       NONE => NONE
   549     | SOME (ctm, ctms) => 
   550       SOME ((term2str ctm):cterm', (map term2str ctms):cterm' list)
   551   end;
   552 
   553 (*FIXME 12.8.02: put_asm = true <==> rewrite_inst, rewrite_set_inst
   554   thus the argument put_asm  IS NOT NECESSARY -- FIXME        ~~~~~*)
   555 fun rewrite_set_inst (thy':theory') (put_asm:bool)
   556   subs' (rls:rls') (ct:cterm') =
   557   let
   558     val thy = assoc_thy thy';
   559     val rls = assoc_rls rls
   560     val subst = subs'2subst thy subs'
   561   in case rewrite_set_inst_ thy put_asm subst (*sub*)rls
   562 			    ((Thm.term_of o the o (parse thy)) ct) of
   563 	 NONE => NONE
   564        | SOME (t, ts) => SOME (term2str t, terms2str ts)
   565   end;
   566 
   567 
   568 (*vor check_elementwise: SqRoot_eval_rls .. wie *_simplify ?! TODO *)
   569 fun eval_true' (thy':theory') (rls':rls') (Const ("HOL.True",_)) = true
   570 
   571   | eval_true' (thy':theory') (rls':rls') (t:term) =
   572 (* val thy'="Isac"; val rls'="eval_rls"; val t=hd pres';
   573    *)
   574     let val ct' = term2str t;
   575     in case rewrite_set thy' false rls' ct' of
   576 	   SOME ("HOL.True",_) => true
   577 	 | _ => false 
   578     end;
   579 fun eval_true_ _ _ (Const ("HOL.True",_)) = true
   580   | eval_true_ (thy':theory') rls t =
   581     case rewrite_set_ (assoc_thy thy') false rls t of
   582 	   SOME (Const ("HOL.True",_),_) => true
   583 	 | _ => false;
   584 
   585 (*
   586 val test_rls = 
   587   Rls{preconds = [], rew_ord = ("sqrt_right",sqrt_right), 
   588       rules = [Calc ("matches",eval_matches "")
   589 	       ],
   590       scr = Prog ((Thm.term_of o the o (parse thy)) 
   591       "empty_script")
   592       }:rls;      
   593 
   594 
   595 
   596   rewrite_set_ (Thy_Info_get_theory "Isac") eval_rls false test_rls 
   597         ((the o (parse thy)) "matches (?a = ?b) (x = #0)");
   598   val xxx = (Thm.term_of o the o (parse thy)) 
   599 	       "matches (?a = ?b) (x = #0)";
   600   eval_matches """" xxx thy;
   601 SOME ("matches (?a = ?b) (x + #1 + #-1 * #2 = #0) = True",
   602      Const ("HOL.Trueprop","bool => prop") $ (Const # $ (# $ #) $ Const (#,#)))
   603 
   604 
   605 
   606   rewrite_set_ (Thy_Info_get_theory "Isac") eval_rls false eval_rls 
   607         ((the o (parse thy)) "contains_root (sqrt #0)");
   608 val it = SOME ("HOL.True",[]) : (cterm * cterm list) option
   609     
   610 *)
   611 
   612 
   613 (*----------WN:16.5.03 stuff below considered illdesigned, thus coded from scratch in appl.sml fun check_elementwise
   614 datatype det = TRUE  | FALSE | INDET;(*FIXXME.WN:16.5.03
   615 				     introduced with quick-and-dirty code*)
   616 fun determine dts =
   617     let val false_indet = 
   618 	    filter_out ((curry op= TRUE) o (#1:det * term -> det)) dts
   619         val ts = map (#2: det * term -> term) dts
   620     in if nil = false_indet then (TRUE, ts)
   621        else if nil = filter ((curry op= FALSE) o (#1:det * term -> det))
   622 			    false_indet
   623        then (INDET, ts)
   624        else (FALSE, ts) end;
   625 (* val dts = [(INDET,e_term), (FALSE,@{term False}), 
   626 	      (INDET,e_term), (TRUE,@{term True})];
   627   determine dts;
   628 val it =
   629   (FALSE,
   630    [Const ("empty","'a"),Const ("HOL.False","bool"),Const ("empty","'a"),
   631     Const ("HOL.True","bool")]) : det * term list*)
   632 
   633 fun eval__indet_ thy cs rls = (*FIXXME.WN:16.5.03 pull into eval__true_, update check (check_elementwise), and regard eval_true_ + eval_true*)
   634 if cs = [@{term True}] orelse cs = [] then (TRUE, [])
   635     else if cs = [@{term False}] then (FALSE, cs)
   636     else
   637 	let fun eval t = 
   638 		let val taopt = rewrite__set_ thy 1 false [] rls t
   639 		in case taopt of
   640 		       SOME (t,_) =>
   641 		       if t = @{term True} then (TRUE, t)
   642 		       else if t = @{term False} then (FALSE, t)
   643 		       else (INDET, t)
   644 		     | NONE => (INDET, t) end
   645 	in (determine o (map eval)) cs end;
   646 WN.16.5.0-------------------------------------------------------------*)
   647 
   648 end