src/Tools/isac/Knowledge/Atools.ML
author Walther Neuper <neuper@ist.tugraz.at>
Wed, 25 Aug 2010 16:20:07 +0200
branchisac-update-Isa09-2
changeset 37947 22235e4dbe5f
parent 37935 src/Tools/isac/IsacKnowledge/Atools.ML@27d365c3dd31
permissions -rw-r--r--
renamed isac's directories and Build_Isac.thy

Scripts --> ProgLang
ME --> Interpret
IsacKnowledge --> Knowledge
neuper@37906
     1
(* tools for arithmetic
neuper@37906
     2
   WN.8.3.01
neuper@37947
     3
   use"../Knowledge/Atools.ML";
neuper@37947
     4
   use"Knowledge/Atools.ML";
neuper@37906
     5
   use"Atools.ML";
neuper@37906
     6
   *)
neuper@37906
     7
neuper@37906
     8
(*
neuper@37906
     9
copy from doc/math-eng.tex WN.28.3.03
neuper@37906
    10
WN071228 extended
neuper@37906
    11
neuper@37906
    12
\section{Coding standards}
neuper@37906
    13
neuper@37906
    14
%WN071228 extended -----vvv
neuper@37906
    15
\subsection{Identifiers}
neuper@37906
    16
Naming is particularily crucial, because Isabelles name space is global, and isac does not yet use the novel locale features introduces by Isar. For instance, {\tt probe} sounds reasonable as (1) a description in the model of a problem-pattern, (2) as an element of the problem hierarchies key, (3) as a socalled CAS-command, (4) as the name of a related script etc. However, all the cases (1)..(4) require different typing for one and the same identifier {\tt probe} which is impossible, and actually leads to strange errors (for instance (1) is used as string, except in a script addressing a Subproblem).
neuper@37906
    17
neuper@37906
    18
This are the preliminary rules for naming identifiers>
neuper@37906
    19
\begin{description}
neuper@37906
    20
\item [elements of a key] into the hierarchy of problems or methods must not contain capital letters and may contain underscrores, e.g. {\tt probe, for_polynomials}.
neuper@37906
    21
\item [descriptions in problem-patterns] must contain at least 1 capital letter and must not contain underscores, e.g. {\tt Probe, forPolynomials}.
neuper@37906
    22
\item [CAS-commands] follow the same rules as descriptions in problem-patterns above, thus beware of conflicts~!
neuper@37906
    23
\item [script identifiers] always end with {\tt Script}, e.g. {\tt ProbeScript}.
neuper@37906
    24
\item [???] ???
neuper@37906
    25
\item [???] ???
neuper@37906
    26
\end{description}
neuper@37906
    27
%WN071228 extended -----^^^
neuper@37906
    28
neuper@37906
    29
neuper@37906
    30
\subsection{Rule sets}
neuper@37947
    31
The actual version of the coding standards for rulesets is in {\tt /Knowledge/Atools.ML where it can be viewed using the knowledge browsers.
neuper@37906
    32
neuper@37906
    33
There are rulesets visible to the student, and there are rulesets visible (in general) only for math authors. There are also rulesets which {\em must} exist for {\em each} theory; these contain the identifier of the respective theory (including all capital letters) as indicated by {\it Thy} below.
neuper@37906
    34
\begin{description}
neuper@37906
    35
neuper@37906
    36
\item [norm\_{\it Thy}] exists for each theory, and {\em efficiently} calculates a normalform for all terms which can be expressed by the definitions of the respective theory (and the respective parents).
neuper@37906
    37
neuper@37906
    38
\item [simplify\_{\it Thy}] exists for each theory, and calculates a normalform for all terms which can be expressed by the definitions of the respective theory (and the respective parents) such, that the rewrites can be presented to the student.
neuper@37906
    39
neuper@37906
    40
\item [calculate\_{\it Thy}] exists for each theory, and evaluates terms with numerical constants only (i.e. all terms which can be expressed by the definitions of the respective theory and the respective parent theories). In particular, this ruleset includes evaluating in/equalities with numerical constants only.
neuper@37906
    41
WN.3.7.03: may be dropped due to more generality: numericals and non-numericals are logically equivalent, where the latter often add to the assumptions (e.g. in Check_elementwise).
neuper@37906
    42
neuper@37906
    43
\end{description}
neuper@37906
    44
The above rulesets are all visible to the user, and also may be input; thus they must be contained in the global associationlist {\tt ruleset':= }~! All these rulesets must undergo a preparation using the function {\tt prep_rls}, which generates a script for stepwise rewriting etc.
neuper@37906
    45
The following rulesets are used for internal purposes and usually invisible to the (naive) user:
neuper@37906
    46
\begin{description}
neuper@37906
    47
neuper@37906
    48
\item [*\_erls] 
neuper@37906
    49
\item [*\_prls] 
neuper@37906
    50
\item [*\_srls] 
neuper@37906
    51
neuper@37906
    52
\end{description}
neuper@37906
    53
{\tt append_rls, merge_rls, remove_rls}
neuper@37906
    54
*)
neuper@37906
    55
neuper@37906
    56
"******* Atools.ML begin *******";
neuper@37906
    57
theory' := overwritel (!theory', [("Atools.thy",Atools.thy)]);
neuper@37906
    58
neuper@37906
    59
(** evaluation of numerals and special predicates on the meta-level **)
neuper@37906
    60
(*-------------------------functions---------------------*)
neuper@37906
    61
local (* rlang 09.02 *)
neuper@37906
    62
    (*.a 'c is coefficient of v' if v does occur in c.*)
neuper@37935
    63
    fun coeff_in v c = member op = (vars c) v;
neuper@37906
    64
in
neuper@37906
    65
    fun occurs_in v t = coeff_in v t;
neuper@37906
    66
end;
neuper@37906
    67
neuper@37906
    68
(*("occurs_in", ("Atools.occurs'_in", eval_occurs_in ""))*)
neuper@37906
    69
fun eval_occurs_in _ "Atools.occurs'_in"
neuper@37906
    70
	     (p as (Const ("Atools.occurs'_in",_) $ v $ t)) _ =
neuper@37906
    71
    ((*writeln("@@@ eval_occurs_in: v= "^(term2str v));
neuper@37906
    72
     writeln("@@@ eval_occurs_in: t= "^(term2str t));*)
neuper@37906
    73
     if occurs_in v t
neuper@37926
    74
    then SOME ((term2str p) ^ " = True",
neuper@37906
    75
	  Trueprop $ (mk_equality (p, HOLogic.true_const)))
neuper@37926
    76
    else SOME ((term2str p) ^ " = False",
neuper@37906
    77
	  Trueprop $ (mk_equality (p, HOLogic.false_const))))
neuper@37926
    78
  | eval_occurs_in _ _ _ _ = NONE;
neuper@37906
    79
neuper@37906
    80
(*some of the (bound) variables (eg. in an eqsys) "vs" occur in term "t"*)   
neuper@37906
    81
fun some_occur_in vs t = 
neuper@37906
    82
    let fun occurs_in' a b = occurs_in b a
neuper@37906
    83
    in foldl or_ (false, map (occurs_in' t) vs) end;
neuper@37906
    84
neuper@37906
    85
(*("some_occur_in", ("Atools.some'_occur'_in", 
neuper@37906
    86
			eval_some_occur_in "#eval_some_occur_in_"))*)
neuper@37906
    87
fun eval_some_occur_in _ "Atools.some'_occur'_in"
neuper@37906
    88
			  (p as (Const ("Atools.some'_occur'_in",_) 
neuper@37906
    89
				       $ vs $ t)) _ =
neuper@37906
    90
    if some_occur_in (isalist2list vs) t
neuper@37926
    91
    then SOME ((term2str p) ^ " = True",
neuper@37906
    92
	       Trueprop $ (mk_equality (p, HOLogic.true_const)))
neuper@37926
    93
    else SOME ((term2str p) ^ " = False",
neuper@37906
    94
	       Trueprop $ (mk_equality (p, HOLogic.false_const)))
neuper@37926
    95
  | eval_some_occur_in _ _ _ _ = NONE;
neuper@37906
    96
neuper@37906
    97
neuper@37906
    98
neuper@37906
    99
neuper@37906
   100
(*evaluate 'is_atom'*)
neuper@37906
   101
(*("is_atom",("Atools.is'_atom",eval_is_atom "#is_atom_"))*)
neuper@37906
   102
fun eval_is_atom (thmid:string) "Atools.is'_atom"
neuper@37906
   103
		 (t as (Const(op0,_) $ arg)) thy = 
neuper@37906
   104
    (case arg of 
neuper@37926
   105
	 Free (n,_) => SOME (mk_thmid thmid op0 n "", 
neuper@37906
   106
			      Trueprop $ (mk_equality (t, true_as_term)))
neuper@37926
   107
       | _ => SOME (mk_thmid thmid op0 "" "", 
neuper@37906
   108
		    Trueprop $ (mk_equality (t, false_as_term))))
neuper@37926
   109
  | eval_is_atom _ _ _ _ = NONE;
neuper@37906
   110
neuper@37906
   111
(*evaluate 'is_even'*)
neuper@37906
   112
fun even i = (i div 2) * 2 = i;
neuper@37906
   113
(*("is_even",("Atools.is'_even",eval_is_even "#is_even_"))*)
neuper@37906
   114
fun eval_is_even (thmid:string) "Atools.is'_even"
neuper@37906
   115
		 (t as (Const(op0,_) $ arg)) thy = 
neuper@37906
   116
    (case arg of 
neuper@37906
   117
	Free (n,_) =>
neuper@37906
   118
	 (case int_of_str n of
neuper@37926
   119
	      SOME i =>
neuper@37926
   120
	      if even i then SOME (mk_thmid thmid op0 n "", 
neuper@37906
   121
				   Trueprop $ (mk_equality (t, true_as_term)))
neuper@37926
   122
	      else SOME (mk_thmid thmid op0 "" "", 
neuper@37906
   123
			 Trueprop $ (mk_equality (t, false_as_term)))
neuper@37926
   124
	    | _ => NONE)
neuper@37926
   125
       | _ => NONE)
neuper@37926
   126
  | eval_is_even _ _ _ _ = NONE; 
neuper@37906
   127
neuper@37906
   128
(*evaluate 'is_const'*)
neuper@37906
   129
(*("is_const",("Atools.is'_const",eval_const "#is_const_"))*)
neuper@37906
   130
fun eval_const (thmid:string) _(*"Atools.is'_const" WN050820 diff.beh. rooteq*)
neuper@37906
   131
	       (t as (Const(op0,t0) $ arg)) (thy:theory) = 
neuper@37906
   132
    (*eval_const FIXXXXXME.WN.16.5.03 still forgets ComplexI*)
neuper@37906
   133
    (case arg of 
neuper@37906
   134
       Const (n1,_) =>
neuper@37926
   135
	 SOME (mk_thmid thmid op0 n1 "", 
neuper@37906
   136
	       Trueprop $ (mk_equality (t, false_as_term)))
neuper@37906
   137
     | Free (n1,_) =>
neuper@37906
   138
	 if is_numeral n1
neuper@37926
   139
	   then SOME (mk_thmid thmid op0 n1 "", 
neuper@37906
   140
		      Trueprop $ (mk_equality (t, true_as_term)))
neuper@37926
   141
	 else SOME (mk_thmid thmid op0 n1 "", 
neuper@37906
   142
		    Trueprop $ (mk_equality (t, false_as_term)))
neuper@37906
   143
     | Const ("Float.Float",_) =>
neuper@37926
   144
       SOME (mk_thmid thmid op0 (term2str arg) "", 
neuper@37906
   145
	     Trueprop $ (mk_equality (t, true_as_term)))
neuper@37926
   146
     | _ => (*NONE*)
neuper@37926
   147
       SOME (mk_thmid thmid op0 (term2str arg) "", 
neuper@37906
   148
		    Trueprop $ (mk_equality (t, false_as_term))))
neuper@37926
   149
  | eval_const _ _ _ _ = NONE; 
neuper@37906
   150
neuper@37906
   151
(*. evaluate binary, associative, commutative operators: *,+,^ .*)
neuper@37922
   152
(*("PLUS"    ,("op +"        ,eval_binop "#add_")),
neuper@37922
   153
  ("TIMES"   ,("op *"        ,eval_binop "#mult_")),
neuper@37922
   154
  ("POWER"  ,("Atools.pow"  ,eval_binop "#power_"))*)
neuper@37906
   155
neuper@37906
   156
(* val (thmid,op_,t as(Const (op0,t0) $ Free (n1,t1) $ Free(n2,t2)),thy) =
neuper@37906
   157
       ("xxxxxx",op_,t,thy);
neuper@37906
   158
   *)
neuper@37906
   159
fun mk_thmid_f thmid ((v11, v12), (p11, p12)) ((v21, v22), (p21, p22))  = 
neuper@37906
   160
    thmid ^ "Float ((" ^ 
neuper@37906
   161
    (string_of_int v11)^","^(string_of_int v12)^"), ("^
neuper@37906
   162
    (string_of_int p11)^","^(string_of_int p12)^")) __ (("^
neuper@37906
   163
    (string_of_int v21)^","^(string_of_int v22)^"), ("^
neuper@37906
   164
    (string_of_int p21)^","^(string_of_int p22)^"))";
neuper@37906
   165
neuper@37906
   166
(*.convert int and float to internal floatingpoint prepresentation.*)
neuper@37906
   167
fun numeral (Free (str, T)) = 
neuper@37906
   168
    (case int_of_str str of
neuper@37926
   169
	 SOME i => SOME ((i, 0), (0, 0))
neuper@37926
   170
       | NONE => NONE)
neuper@37906
   171
  | numeral (Const ("Float.Float", _) $
neuper@37906
   172
		   (Const ("Pair", _) $
neuper@37906
   173
			  (Const ("Pair", T) $ Free (v1, _) $ Free (v2,_)) $
neuper@37906
   174
			  (Const ("Pair", _) $ Free (p1, _) $ Free (p2,_))))=
neuper@37906
   175
    (case (int_of_str v1, int_of_str v2, int_of_str p1, int_of_str p2) of
neuper@37926
   176
	(SOME v1', SOME v2', SOME p1', SOME p2') =>
neuper@37926
   177
	SOME ((v1', v2'), (p1', p2'))
neuper@37926
   178
      | _ => NONE)
neuper@37926
   179
  | numeral _ = NONE;
neuper@37906
   180
neuper@37906
   181
(*.evaluate binary associative operations.*)
neuper@37906
   182
fun eval_binop (thmid:string) (op_:string) 
neuper@37906
   183
	       (t as ( Const(op0,t0) $ 
neuper@37906
   184
			    (Const(op0',t0') $ v $ t1) $ t2)) 
neuper@37906
   185
	       thy =                                     (*binary . (v.n1).n2*)
neuper@37906
   186
    if op0 = op0' then
neuper@37906
   187
	case (numeral t1, numeral t2) of
neuper@37926
   188
	    (SOME n1, SOME n2) =>
neuper@37906
   189
	    let val (T1,T2,Trange) = dest_binop_typ t0
neuper@37906
   190
		val res = calc (if op0 = "op -" then "op +" else op0) n1 n2
neuper@37906
   191
		(*WN071229 "HOL.divide" never tried*)
neuper@37906
   192
		val rhs = var_op_float v op_ t0 T1 res
neuper@37906
   193
		val prop = Trueprop $ (mk_equality (t, rhs))
neuper@37926
   194
	    in SOME (mk_thmid_f thmid n1 n2, prop) end
neuper@37926
   195
	  | _ => NONE
neuper@37926
   196
    else NONE
neuper@37906
   197
  | eval_binop (thmid:string) (op_:string) 
neuper@37906
   198
	       (t as 
neuper@37906
   199
		  (Const (op0, t0) $ t1 $ 
neuper@37906
   200
			 (Const (op0', t0') $ t2 $ v))) 
neuper@37906
   201
	       thy =                                     (*binary . n1.(n2.v)*)
neuper@37906
   202
  if op0 = op0' then
neuper@37906
   203
	case (numeral t1, numeral t2) of
neuper@37926
   204
	    (SOME n1, SOME n2) =>
neuper@37926
   205
	    if op0 = "op -" then NONE else
neuper@37906
   206
	    let val (T1,T2,Trange) = dest_binop_typ t0
neuper@37906
   207
		val res = calc op0 n1 n2
neuper@37906
   208
		val rhs = float_op_var v op_ t0 T1 res
neuper@37906
   209
		val prop = Trueprop $ (mk_equality (t, rhs))
neuper@37926
   210
	    in SOME (mk_thmid_f thmid n1 n2, prop) end
neuper@37926
   211
	  | _ => NONE
neuper@37926
   212
  else NONE
neuper@37906
   213
    
neuper@37906
   214
  | eval_binop (thmid:string) (op_:string)
neuper@37906
   215
	       (t as (Const (op0,t0) $ t1 $ t2)) thy =       (*binary . n1.n2*)
neuper@37906
   216
    (case (numeral t1, numeral t2) of
neuper@37926
   217
	 (SOME n1, SOME n2) =>
neuper@37906
   218
	 let val (T1,T2,Trange) = dest_binop_typ t0;
neuper@37906
   219
	     val res = calc op0 n1 n2;
neuper@37906
   220
	     val rhs = term_of_float Trange res;
neuper@37906
   221
	     val prop = Trueprop $ (mk_equality (t, rhs));
neuper@37926
   222
	 in SOME (mk_thmid_f thmid n1 n2, prop) end
neuper@37926
   223
       | _ => NONE)
neuper@37926
   224
  | eval_binop _ _ _ _ = NONE; 
neuper@37906
   225
(*
neuper@37926
   226
> val SOME (thmid, t) = eval_binop "#add_" "op +" (str2term "-1 + 2") thy;
neuper@37906
   227
> term2str t;
neuper@37906
   228
val it = "-1 + 2 = 1"
neuper@37906
   229
> val t = str2term "-1 * (-1 * a)";
neuper@37926
   230
> val SOME (thmid, t) = eval_binop "#mult_" "op *" t thy;
neuper@37906
   231
> term2str t;
neuper@37906
   232
val it = "-1 * (-1 * a) = 1 * a"*)
neuper@37906
   233
neuper@37906
   234
neuper@37906
   235
neuper@37906
   236
(*.evaluate < and <= for numerals.*)
neuper@37906
   237
(*("le"      ,("op <"        ,eval_equ "#less_")),
neuper@37906
   238
  ("leq"     ,("op <="       ,eval_equ "#less_equal_"))*)
neuper@37906
   239
fun eval_equ (thmid:string) (op_:string) (t as 
neuper@37906
   240
	       (Const (op0,t0) $ Free (n1,t1) $ Free(n2,t2))) thy = 
neuper@37906
   241
    (case (int_of_str n1, int_of_str n2) of
neuper@37926
   242
	 (SOME n1', SOME n2') =>
neuper@37906
   243
  if calc_equ (strip_thy op0) (n1', n2')
neuper@37926
   244
    then SOME (mk_thmid thmid op0 n1 n2, 
neuper@37906
   245
	  Trueprop $ (mk_equality (t, true_as_term)))
neuper@37926
   246
  else SOME (mk_thmid thmid op0 n1 n2,  
neuper@37906
   247
	  Trueprop $ (mk_equality (t, false_as_term)))
neuper@37926
   248
       | _ => NONE)
neuper@37906
   249
    
neuper@37926
   250
  | eval_equ _ _ _ _ = NONE;
neuper@37906
   251
neuper@37906
   252
neuper@37906
   253
(*evaluate identity
neuper@37906
   254
> reflI;
neuper@37906
   255
val it = "(?t = ?t) = True"
neuper@37906
   256
> val t = str2term "x = 0";
neuper@37926
   257
> val NONE = rewrite_ thy dummy_ord e_rls false reflI t;
neuper@37906
   258
neuper@37906
   259
> val t = str2term "1 = 0";
neuper@37926
   260
> val NONE = rewrite_ thy dummy_ord e_rls false reflI t;
neuper@37906
   261
----------- thus needs Calc !
neuper@37906
   262
> val t = str2term "0 = 0";
neuper@37926
   263
> val SOME (t',_) = rewrite_ thy dummy_ord e_rls false reflI t;
neuper@37906
   264
> term2str t';
neuper@37906
   265
val it = "True"
neuper@37906
   266
neuper@37906
   267
val t = str2term "Not (x = 0)";
neuper@37906
   268
atomt t; term2str t;
neuper@37906
   269
*** -------------
neuper@37906
   270
*** Const ( Not)
neuper@37906
   271
*** . Const ( op =)
neuper@37906
   272
*** . . Free ( x, )
neuper@37906
   273
*** . . Free ( 0, )
neuper@37906
   274
val it = "x ~= 0" : string*)
neuper@37906
   275
neuper@37906
   276
(*.evaluate identity on the term-level, =!= ,i.e. without evaluation of 
neuper@37906
   277
  the arguments: thus special handling by 'fun eval_binop'*)
neuper@37906
   278
(*("ident"   ,("Atools.ident",eval_ident "#ident_")):calc*)
neuper@37906
   279
fun eval_ident (thmid:string) "Atools.ident" (t as 
neuper@37906
   280
	       (Const (op0,t0) $ t1 $ t2 )) thy = 
neuper@37906
   281
  if t1 = t2
neuper@37926
   282
    then SOME (mk_thmid thmid op0 
neuper@37933
   283
	       ("("^(Syntax.string_of_term (thy2ctxt thy) t1)^")")
neuper@37933
   284
	       ("("^(Syntax.string_of_term (thy2ctxt thy) t2)^")"), 
neuper@37906
   285
	  Trueprop $ (mk_equality (t, true_as_term)))
neuper@37926
   286
  else SOME (mk_thmid thmid op0  
neuper@37933
   287
	       ("("^(Syntax.string_of_term (thy2ctxt thy) t1)^")")
neuper@37933
   288
	       ("("^(Syntax.string_of_term (thy2ctxt thy) t2)^")"),  
neuper@37906
   289
	  Trueprop $ (mk_equality (t, false_as_term)))
neuper@37926
   290
  | eval_ident _ _ _ _ = NONE;
neuper@37906
   291
(* TODO
neuper@37906
   292
> val t = str2term "x =!= 0";
neuper@37926
   293
> val SOME (str, t') = eval_ident "ident_" "b" t thy;
neuper@37906
   294
> term2str t';
neuper@37906
   295
val str = "ident_(x)_(0)" : string
neuper@37906
   296
val it = "(x =!= 0) = False" : string                                
neuper@37906
   297
> val t = str2term "1 =!= 0";
neuper@37926
   298
> val SOME (str, t') = eval_ident "ident_" "b" t thy;
neuper@37906
   299
> term2str t';
neuper@37906
   300
val str = "ident_(1)_(0)" : string 
neuper@37906
   301
val it = "(1 =!= 0) = False" : string                                       
neuper@37906
   302
> val t = str2term "0 =!= 0";
neuper@37926
   303
> val SOME (str, t') = eval_ident "ident_" "b" t thy;
neuper@37906
   304
> term2str t';
neuper@37906
   305
val str = "ident_(0)_(0)" : string
neuper@37906
   306
val it = "(0 =!= 0) = True" : string
neuper@37906
   307
*)
neuper@37906
   308
neuper@37906
   309
(*.evaluate identity of terms, which stay ready for evaluation in turn;
neuper@37906
   310
  thus returns False only for atoms.*)
neuper@37906
   311
(*("equal"   ,("op =",eval_equal "#equal_")):calc*)
neuper@37906
   312
fun eval_equal (thmid:string) "op =" (t as 
neuper@37906
   313
	       (Const (op0,t0) $ t1 $ t2 )) thy = 
neuper@37906
   314
  if t1 = t2
neuper@37906
   315
    then ((*writeln"... eval_equal: t1 = t2  --> True";*)
neuper@37926
   316
	  SOME (mk_thmid thmid op0 
neuper@37933
   317
	       ("("^(Syntax.string_of_term (thy2ctxt thy) t1)^")")
neuper@37933
   318
	       ("("^(Syntax.string_of_term (thy2ctxt thy) t2)^")"), 
neuper@37906
   319
	  Trueprop $ (mk_equality (t, true_as_term)))
neuper@37906
   320
	  )
neuper@37906
   321
  else (case (is_atom t1, is_atom t2) of
neuper@37906
   322
	    (true, true) => 
neuper@37906
   323
	    ((*writeln"... eval_equal: t1<>t2, is_atom t1,t2 --> False";*)
neuper@37926
   324
	     SOME (mk_thmid thmid op0  
neuper@37906
   325
			   ("("^(term2str t1)^")") ("("^(term2str t2)^")"),
neuper@37906
   326
		  Trueprop $ (mk_equality (t, false_as_term)))
neuper@37906
   327
	     )
neuper@37906
   328
	  | _ => ((*writeln"... eval_equal: t1<>t2, NOT is_atom t1,t2 --> go-on";*)
neuper@37926
   329
		  NONE))
neuper@37906
   330
  | eval_equal _ _ _ _ = (writeln"... eval_equal: error-exit";
neuper@37926
   331
			  NONE);
neuper@37906
   332
(*
neuper@37906
   333
val t = str2term "x ~= 0";
neuper@37926
   334
val NONE = eval_equal "equal_" "b" t thy;
neuper@37906
   335
neuper@37906
   336
neuper@37906
   337
> val t = str2term "(x + 1) = (x + 1)";
neuper@37926
   338
> val SOME (str, t') = eval_equal "equal_" "b" t thy;
neuper@37906
   339
> term2str t';
neuper@37906
   340
val str = "equal_(x + 1)_(x + 1)" : string
neuper@37906
   341
val it = "(x + 1 = x + 1) = True" : string
neuper@37906
   342
> val t = str2term "x = 0";
neuper@37926
   343
> val NONE = eval_equal "equal_" "b" t thy;
neuper@37906
   344
neuper@37906
   345
> val t = str2term "1 = 0";
neuper@37926
   346
> val SOME (str, t') = eval_equal "equal_" "b" t thy;
neuper@37906
   347
> term2str t';
neuper@37906
   348
val str = "equal_(1)_(0)" : string 
neuper@37906
   349
val it = "(1 = 0) = False" : string
neuper@37906
   350
> val t = str2term "0 = 0";
neuper@37926
   351
> val SOME (str, t') = eval_equal "equal_" "b" t thy;
neuper@37906
   352
> term2str t';
neuper@37906
   353
val str = "equal_(0)_(0)" : string
neuper@37906
   354
val it = "(0 = 0) = True" : string
neuper@37906
   355
*)
neuper@37906
   356
neuper@37906
   357
neuper@37906
   358
(** evaluation on the metalevel **)
neuper@37906
   359
neuper@37906
   360
(*. evaluate HOL.divide .*)
neuper@37922
   361
(*("DIVIDE" ,("HOL.divide"  ,eval_cancel "#divide_"))*)
neuper@37906
   362
fun eval_cancel (thmid:string) "HOL.divide" (t as 
neuper@37906
   363
	       (Const (op0,t0) $ Free (n1,t1) $ Free(n2,t2))) thy = 
neuper@37906
   364
    (case (int_of_str n1, int_of_str n2) of
neuper@37926
   365
	 (SOME n1', SOME n2') =>
neuper@37906
   366
  let 
neuper@37906
   367
    val sg = sign2 n1' n2';
neuper@37906
   368
    val (T1,T2,Trange) = dest_binop_typ t0;
neuper@37906
   369
    val gcd' = gcd (abs n1') (abs n2');
neuper@37906
   370
  in if gcd' = abs n2' 
neuper@37906
   371
     then let val rhs = term_of_num Trange (sg * (abs n1') div gcd')
neuper@37906
   372
	      val prop = Trueprop $ (mk_equality (t, rhs))
neuper@37926
   373
	  in SOME (mk_thmid thmid op0 n1 n2, prop) end     
neuper@37926
   374
     else if 0 < n2' andalso gcd' = 1 then NONE
neuper@37906
   375
     else let val rhs = num_op_num T1 T2 (op0,t0) (sg * (abs n1') div gcd')
neuper@37906
   376
				   ((abs n2') div gcd')
neuper@37906
   377
	      val prop = Trueprop $ (mk_equality (t, rhs))
neuper@37926
   378
	  in SOME (mk_thmid thmid op0 n1 n2, prop) end
neuper@37906
   379
  end
neuper@37926
   380
       | _ => ((*writeln"@@@ eval_cancel NONE";*)NONE))
neuper@37906
   381
neuper@37926
   382
  | eval_cancel _ _ _ _ = NONE;
neuper@37906
   383
neuper@37906
   384
(*. get the argument from a function-definition.*)
neuper@37906
   385
(*("argument_in" ,("Atools.argument'_in",
neuper@37906
   386
		   eval_argument_in "Atools.argument'_in"))*)
neuper@37906
   387
fun eval_argument_in _ "Atools.argument'_in" 
neuper@37906
   388
		     (t as (Const ("Atools.argument'_in", _) $ (f $ arg))) _ =
neuper@37906
   389
    if is_Free arg (*could be something to be simplified before*)
neuper@37926
   390
    then SOME (term2str t ^ " = " ^ term2str arg,
neuper@37906
   391
	       Trueprop $ (mk_equality (t, arg)))
neuper@37926
   392
    else NONE
neuper@37926
   393
  | eval_argument_in _ _ _ _ = NONE;
neuper@37906
   394
neuper@37906
   395
(*.check if the function-identifier of the first argument matches 
neuper@37906
   396
   the function-identifier of the lhs of the second argument.*)
neuper@37906
   397
(*("sameFunId" ,("Atools.sameFunId",
neuper@37906
   398
		   eval_same_funid "Atools.sameFunId"))*)
neuper@37906
   399
fun eval_sameFunId _ "Atools.sameFunId" 
neuper@37906
   400
		     (p as Const ("Atools.sameFunId",_) $ 
neuper@37906
   401
			(f1 $ _) $ 
neuper@37906
   402
			(Const ("op =", _) $ (f2 $ _) $ _)) _ =
neuper@37906
   403
    if f1 = f2 
neuper@37926
   404
    then SOME ((term2str p) ^ " = True",
neuper@37906
   405
	       Trueprop $ (mk_equality (p, HOLogic.true_const)))
neuper@37926
   406
    else SOME ((term2str p) ^ " = False",
neuper@37906
   407
	       Trueprop $ (mk_equality (p, HOLogic.false_const)))
neuper@37926
   408
| eval_sameFunId _ _ _ _ = NONE;
neuper@37906
   409
neuper@37906
   410
neuper@37906
   411
(*.from a list of fun-definitions "f x = ..." as 2nd argument
neuper@37906
   412
   filter the elements with the same fun-identfier in "f y"
neuper@37906
   413
   as the fst argument;
neuper@37906
   414
   this is, because Isabelles filter takes more than 1 sec.*)
neuper@37906
   415
fun same_funid f1 (Const ("op =", _) $ (f2 $ _) $ _) = f1 = f2
neuper@37906
   416
  | same_funid f1 t = raise error ("same_funid called with t = ("
neuper@37906
   417
				   ^term2str f1^") ("^term2str t^")");
neuper@37906
   418
(*("filter_sameFunId" ,("Atools.filter'_sameFunId",
neuper@37906
   419
		   eval_filter_sameFunId "Atools.filter'_sameFunId"))*)
neuper@37906
   420
fun eval_filter_sameFunId _ "Atools.filter'_sameFunId" 
neuper@37906
   421
		     (p as Const ("Atools.filter'_sameFunId",_) $ 
neuper@37906
   422
			(fid $ _) $ fs) _ =
neuper@37906
   423
    let val fs' = ((list2isalist HOLogic.boolT) o 
neuper@37906
   424
		   (filter (same_funid fid))) (isalist2list fs)
neuper@37926
   425
    in SOME (term2str (mk_equality (p, fs')),
neuper@37906
   426
	       Trueprop $ (mk_equality (p, fs'))) end
neuper@37926
   427
| eval_filter_sameFunId _ _ _ _ = NONE;
neuper@37906
   428
neuper@37906
   429
neuper@37906
   430
(*make a list of terms to a sum*)
neuper@37906
   431
fun list2sum [] = error ("list2sum called with []")
neuper@37906
   432
  | list2sum [s] = s
neuper@37906
   433
  | list2sum (s::ss) = 
neuper@37906
   434
    let fun sum su [s'] = 
neuper@37906
   435
	    Const ("op +", [HOLogic.realT,HOLogic.realT]--->HOLogic.realT)
neuper@37906
   436
		  $ su $ s'
neuper@37906
   437
	  | sum su (s'::ss') = 
neuper@37906
   438
	    sum (Const ("op +", [HOLogic.realT,HOLogic.realT]--->HOLogic.realT)
neuper@37906
   439
		  $ su $ s') ss'
neuper@37906
   440
    in sum s ss end;
neuper@37906
   441
neuper@37906
   442
(*make a list of equalities to the sum of the lhs*)
neuper@37906
   443
(*("boollist2sum"    ,("Atools.boollist2sum"    ,eval_boollist2sum "")):calc*)
neuper@37906
   444
fun eval_boollist2sum _ "Atools.boollist2sum" 
neuper@37906
   445
		      (p as Const ("Atools.boollist2sum", _) $ 
neuper@37906
   446
			 (l as Const ("List.list.Cons", _) $ _ $ _)) _ =
neuper@37906
   447
    let val isal = isalist2list l
neuper@37906
   448
	val lhss = map lhs isal
neuper@37906
   449
	val sum = list2sum lhss
neuper@37926
   450
    in SOME ((term2str p) ^ " = " ^ (term2str sum),
neuper@37906
   451
	  Trueprop $ (mk_equality (p, sum)))
neuper@37906
   452
    end
neuper@37926
   453
| eval_boollist2sum _ _ _ _ = NONE;
neuper@37906
   454
neuper@37906
   455
neuper@37906
   456
neuper@37906
   457
local
neuper@37906
   458
neuper@37906
   459
open Term;
neuper@37906
   460
neuper@37906
   461
in
neuper@37906
   462
fun termlessI (_:subst) uv = termless uv;
neuper@37906
   463
fun term_ordI (_:subst) uv = term_ord uv;
neuper@37906
   464
end;
neuper@37906
   465
neuper@37906
   466
neuper@37906
   467
(** rule set, for evaluating list-expressions in scripts 8.01.02 **)
neuper@37906
   468
neuper@37906
   469
neuper@37906
   470
val list_rls = 
neuper@37906
   471
    append_rls "list_rls" list_rls
neuper@37906
   472
	       [Calc ("op *",eval_binop "#mult_"),
neuper@37906
   473
		Calc ("op +", eval_binop "#add_"), 
neuper@37906
   474
		Calc ("op <",eval_equ "#less_"),
neuper@37906
   475
		Calc ("op <=",eval_equ "#less_equal_"),
neuper@37906
   476
		Calc ("Atools.ident",eval_ident "#ident_"),
neuper@37906
   477
		Calc ("op =",eval_equal "#equal_"),(*atom <> atom -> False*)
neuper@37906
   478
       
neuper@37906
   479
		Calc ("Tools.Vars",eval_var "#Vars_"),
neuper@37906
   480
		
neuper@37906
   481
		Thm ("if_True",num_str if_True),
neuper@37906
   482
		Thm ("if_False",num_str if_False)
neuper@37906
   483
		];
neuper@37906
   484
neuper@37906
   485
ruleset' := overwritelthy thy (!ruleset',
neuper@37906
   486
  [("list_rls",list_rls)
neuper@37906
   487
   ]);
neuper@37906
   488
neuper@37906
   489
(*TODO.WN0509 reduce ids: tless_true = e_rew_ord' = e_rew_ord = dummy_ord*)
neuper@37906
   490
val tless_true = dummy_ord;
neuper@37906
   491
rew_ord' := overwritel (!rew_ord',
neuper@37906
   492
			[("tless_true", tless_true),
neuper@37906
   493
			 ("e_rew_ord'", tless_true),
neuper@37906
   494
			 ("dummy_ord", dummy_ord)]);
neuper@37906
   495
neuper@37906
   496
val calculate_Atools = 
neuper@37906
   497
    append_rls "calculate_Atools" e_rls
neuper@37906
   498
               [Calc ("op <",eval_equ "#less_"),
neuper@37906
   499
		Calc ("op <=",eval_equ "#less_equal_"),
neuper@37906
   500
		Calc ("op =",eval_equal "#equal_"),
neuper@37906
   501
neuper@37906
   502
		Thm  ("real_unari_minus",num_str real_unari_minus),
neuper@37906
   503
		Calc ("op +",eval_binop "#add_"),
neuper@37906
   504
		Calc ("op -",eval_binop "#sub_"),
neuper@37906
   505
		Calc ("op *",eval_binop "#mult_")
neuper@37906
   506
		];
neuper@37906
   507
neuper@37906
   508
val Atools_erls = 
neuper@37906
   509
    append_rls "Atools_erls" e_rls
neuper@37906
   510
               [Calc ("op =",eval_equal "#equal_"),
neuper@37906
   511
                Thm ("not_true",num_str not_true),
neuper@37906
   512
		(*"(~ True) = False"*)
neuper@37906
   513
		Thm ("not_false",num_str not_false),
neuper@37906
   514
		(*"(~ False) = True"*)
neuper@37906
   515
		Thm ("and_true",and_true),
neuper@37906
   516
		(*"(?a & True) = ?a"*)
neuper@37906
   517
		Thm ("and_false",and_false),
neuper@37906
   518
		(*"(?a & False) = False"*)
neuper@37906
   519
		Thm ("or_true",or_true),
neuper@37906
   520
		(*"(?a | True) = True"*)
neuper@37906
   521
		Thm ("or_false",or_false),
neuper@37906
   522
		(*"(?a | False) = ?a"*)
neuper@37906
   523
               
neuper@37906
   524
		Thm ("rat_leq1",rat_leq1),
neuper@37906
   525
		Thm ("rat_leq2",rat_leq2),
neuper@37906
   526
		Thm ("rat_leq3",rat_leq3),
neuper@37906
   527
                Thm ("refl",num_str refl),
neuper@37906
   528
		Thm ("le_refl",num_str le_refl),
neuper@37906
   529
		Thm ("radd_left_cancel_le",num_str radd_left_cancel_le),
neuper@37906
   530
		
neuper@37906
   531
		Calc ("op <",eval_equ "#less_"),
neuper@37906
   532
		Calc ("op <=",eval_equ "#less_equal_"),
neuper@37906
   533
		
neuper@37906
   534
		Calc ("Atools.ident",eval_ident "#ident_"),    
neuper@37906
   535
		Calc ("Atools.is'_const",eval_const "#is_const_"),
neuper@37906
   536
		Calc ("Atools.occurs'_in",eval_occurs_in ""),    
neuper@37906
   537
		Calc ("Tools.matches",eval_matches "")
neuper@37906
   538
		];
neuper@37906
   539
neuper@37906
   540
val Atools_crls = 
neuper@37906
   541
    append_rls "Atools_crls" e_rls
neuper@37906
   542
               [Calc ("op =",eval_equal "#equal_"),
neuper@37906
   543
                Thm ("not_true",num_str not_true),
neuper@37906
   544
		Thm ("not_false",num_str not_false),
neuper@37906
   545
		Thm ("and_true",and_true),
neuper@37906
   546
		Thm ("and_false",and_false),
neuper@37906
   547
		Thm ("or_true",or_true),
neuper@37906
   548
		Thm ("or_false",or_false),
neuper@37906
   549
               
neuper@37906
   550
		Thm ("rat_leq1",rat_leq1),
neuper@37906
   551
		Thm ("rat_leq2",rat_leq2),
neuper@37906
   552
		Thm ("rat_leq3",rat_leq3),
neuper@37906
   553
                Thm ("refl",num_str refl),
neuper@37906
   554
		Thm ("le_refl",num_str le_refl),
neuper@37906
   555
		Thm ("radd_left_cancel_le",num_str radd_left_cancel_le),
neuper@37906
   556
		
neuper@37906
   557
		Calc ("op <",eval_equ "#less_"),
neuper@37906
   558
		Calc ("op <=",eval_equ "#less_equal_"),
neuper@37906
   559
		
neuper@37906
   560
		Calc ("Atools.ident",eval_ident "#ident_"),    
neuper@37906
   561
		Calc ("Atools.is'_const",eval_const "#is_const_"),
neuper@37906
   562
		Calc ("Atools.occurs'_in",eval_occurs_in ""),    
neuper@37906
   563
		Calc ("Tools.matches",eval_matches "")
neuper@37906
   564
		];
neuper@37906
   565
neuper@37906
   566
(*val atools_erls = ... waere zu testen ...
neuper@37906
   567
    merge_rls calculate_Atools
neuper@37906
   568
	      (append_rls Atools_erls (*i.A. zu viele rules*)
neuper@37906
   569
			  [Calc ("Atools.ident",eval_ident "#ident_"),    
neuper@37906
   570
			   Calc ("Atools.is'_const",eval_const "#is_const_"),
neuper@37906
   571
			   Calc ("Atools.occurs'_in",
neuper@37906
   572
				 eval_occurs_in "#occurs_in"),    
neuper@37906
   573
			   Calc ("Tools.matches",eval_matches "#matches")
neuper@37906
   574
			   ] (*i.A. zu viele rules*)
neuper@37906
   575
			  );*)
neuper@37906
   576
(* val atools_erls = prep_rls(
neuper@37906
   577
  Rls {id="atools_erls",preconds = [], rew_ord = ("termlessI",termlessI), 
neuper@37906
   578
      erls = e_rls, srls = Erls, calc = [], (*asm_thm = [],*)
neuper@37906
   579
      rules = [Thm ("refl",num_str refl),
neuper@37906
   580
		Thm ("le_refl",num_str le_refl),
neuper@37906
   581
		Thm ("radd_left_cancel_le",num_str radd_left_cancel_le),
neuper@37906
   582
		Thm ("not_true",num_str not_true),
neuper@37906
   583
		Thm ("not_false",num_str not_false),
neuper@37906
   584
		Thm ("and_true",and_true),
neuper@37906
   585
		Thm ("and_false",and_false),
neuper@37906
   586
		Thm ("or_true",or_true),
neuper@37906
   587
		Thm ("or_false",or_false),
neuper@37906
   588
		Thm ("and_commute",num_str and_commute),
neuper@37906
   589
		Thm ("or_commute",num_str or_commute),
neuper@37906
   590
		
neuper@37906
   591
		Calc ("op <",eval_equ "#less_"),
neuper@37906
   592
		Calc ("op <=",eval_equ "#less_equal_"),
neuper@37906
   593
		
neuper@37906
   594
		Calc ("Atools.ident",eval_ident "#ident_"),    
neuper@37906
   595
		Calc ("Atools.is'_const",eval_const "#is_const_"),
neuper@37906
   596
		Calc ("Atools.occurs'_in",eval_occurs_in ""),    
neuper@37906
   597
		Calc ("Tools.matches",eval_matches "")
neuper@37906
   598
	       ],
neuper@37906
   599
      scr = Script ((term_of o the o (parse thy)) 
neuper@37906
   600
      "empty_script")
neuper@37906
   601
      }:rls);
neuper@37906
   602
ruleset' := overwritelth thy 
neuper@37906
   603
		(!ruleset',
neuper@37906
   604
		 [("atools_erls",atools_erls)(*FIXXXME:del with rls.rls'*)
neuper@37906
   605
		  ]);
neuper@37906
   606
*)
neuper@37906
   607
"******* Atools.ML end *******";
neuper@37906
   608
neuper@37906
   609
calclist':= overwritel (!calclist', 
neuper@37906
   610
   [("occurs_in",("Atools.occurs'_in", eval_occurs_in "#occurs_in_")),
neuper@37906
   611
    ("some_occur_in",
neuper@37906
   612
     ("Atools.some'_occur'_in", eval_some_occur_in "#some_occur_in_")),
neuper@37906
   613
    ("is_atom"  ,("Atools.is'_atom",eval_is_atom "#is_atom_")),
neuper@37906
   614
    ("is_even"  ,("Atools.is'_even",eval_is_even "#is_even_")),
neuper@37906
   615
    ("is_const" ,("Atools.is'_const",eval_const "#is_const_")),
neuper@37906
   616
    ("le"       ,("op <"        ,eval_equ "#less_")),
neuper@37906
   617
    ("leq"      ,("op <="       ,eval_equ "#less_equal_")),
neuper@37906
   618
    ("ident"    ,("Atools.ident",eval_ident "#ident_")),
neuper@37906
   619
    ("equal"    ,("op =",eval_equal "#equal_")),
neuper@37922
   620
    ("PLUS"     ,("op +"        ,eval_binop "#add_")),
neuper@37906
   621
    ("minus"    ,("op -",eval_binop "#sub_")), (*040207 only for prep_rls
neuper@37906
   622
	        			      no script with "minus"*)
neuper@37922
   623
    ("TIMES"    ,("op *"        ,eval_binop "#mult_")),
neuper@37922
   624
    ("DIVIDE"  ,("HOL.divide"  ,eval_cancel "#divide_")),
neuper@37922
   625
    ("POWER"   ,("Atools.pow"  ,eval_binop "#power_")),
neuper@37906
   626
    ("boollist2sum",("Atools.boollist2sum",eval_boollist2sum ""))
neuper@37906
   627
    ]);
neuper@37906
   628
neuper@37906
   629
val list_rls = prep_rls(
neuper@37906
   630
    merge_rls "list_erls"
neuper@37906
   631
	      (Rls {id="replaced",preconds = [], 
neuper@37906
   632
		    rew_ord = ("termlessI", termlessI),
neuper@37906
   633
		    erls = Rls {id="list_elrs", preconds = [], 
neuper@37906
   634
				rew_ord = ("termlessI",termlessI), 
neuper@37906
   635
				erls = e_rls, 
neuper@37906
   636
				srls = Erls, calc = [], (*asm_thm = [],*)
neuper@37906
   637
				rules = [Calc ("op +", eval_binop "#add_"),
neuper@37906
   638
					 Calc ("op <",eval_equ "#less_")
neuper@37906
   639
					 (*    ~~~~~~ for nth_Cons_*)
neuper@37906
   640
					 ],
neuper@37906
   641
				scr = EmptyScr},
neuper@37906
   642
		    srls = Erls, calc = [], (*asm_thm = [], *)
neuper@37906
   643
		    rules = [], scr = EmptyScr})
neuper@37906
   644
	      list_rls);
neuper@37906
   645
ruleset' := overwritelthy thy (!ruleset', [("list_rls", list_rls)]);