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