src/sml/IsacKnowledge/Integrate.ML
author wneuper
Wed, 26 Oct 2005 15:48:11 +0200
branchstart_Take
changeset 447 f2a7e2138a41
parent 417 3e98e2608940
child 451 e9ce58de3818
permissions -rw-r--r--
finished EqSystem 'top_down_substitution', 'normalize' #1 for Biegelinie
wneuper@339
     1
(* tools for integration over the reals
wneuper@375
     2
   author: Walther Neuper 050905, 08:51
wneuper@339
     3
   (c) due to copyright terms
wneuper@339
     4
wneuper@375
     5
use"IsacKnowledge/Integrate.ML";
wneuper@376
     6
use"Integrate.ML";
wneuper@339
     7
*)
wneuper@339
     8
wneuper@339
     9
(** interface isabelle -- isac **)
wneuper@339
    10
wneuper@339
    11
theory' := overwritel (!theory', [("Integrate.thy",Integrate.thy)]);
wneuper@339
    12
wneuper@339
    13
theorem' := overwritel (!theorem',
wneuper@339
    14
[("integral_const",num_str integral_const),
wneuper@339
    15
 ("integral_var",num_str integral_var),
wneuper@339
    16
 ("integral_add",num_str integral_add),
wneuper@339
    17
 ("integral_mult",num_str integral_mult),
wneuper@339
    18
 ("call_for_new_c",num_str call_for_new_c),
wneuper@339
    19
 ("integral_pow",num_str integral_pow)
wneuper@339
    20
]);
wneuper@339
    21
wneuper@339
    22
(** eval functions **)
wneuper@339
    23
wneuper@339
    24
val c = Free ("c", HOLogic.realT);
wneuper@417
    25
(*.create a new unique variable 'c..' in a term; for use by Calc in a rls;
wneuper@417
    26
   an alternative to do this would be '(Try (Calculate new_c_) (new_c es__))'
wneuper@417
    27
   in the script; this will be possible if currying doesnt take the value
wneuper@417
    28
   from a variable, but the value '(new_c es__)' itself.*)
wneuper@339
    29
fun new_c term = 
wneuper@339
    30
    let fun selc var = 
wneuper@339
    31
	    case (explode o id_of) var of
wneuper@339
    32
		"c"::[] => true
wneuper@339
    33
	      |	"c"::"_"::is => (case (int_of_str o implode) is of
wneuper@339
    34
				     Some _ => true
wneuper@339
    35
				   | None => false)
wneuper@339
    36
              | _ => false;
wneuper@339
    37
	fun get_coeff c = case (explode o id_of) c of
wneuper@339
    38
	      		      "c"::"_"::is => (the o int_of_str o implode) is
wneuper@339
    39
			    | _ => 0;
wneuper@339
    40
        val cs = filter selc (vars term);
wneuper@339
    41
    in 
wneuper@339
    42
	case cs of
wneuper@339
    43
	    [] => c
wneuper@339
    44
	  | [c] => Free ("c_2", HOLogic.realT)
wneuper@339
    45
	  | cs => 
wneuper@339
    46
	    let val max_coeff = maxl (map get_coeff cs)
wneuper@339
    47
	    in Free ("c_"^string_of_int (max_coeff + 1), HOLogic.realT) end
wneuper@339
    48
    end;
wneuper@339
    49
wneuper@414
    50
(*("new_c", ("Integrate.new'_c", eval_new_c "#new_c_"))*)
wneuper@339
    51
fun eval_new_c _ _ (p as (Const ("Integrate.new'_c",_) $ t)) _ =
wneuper@339
    52
     Some ((term2str p) ^ " = " ^ term2str (new_c p),
wneuper@339
    53
	  Trueprop $ (mk_equality (p, new_c p)))
wneuper@339
    54
  | eval_new_c _ _ _ _ = None;
wneuper@339
    55
wneuper@346
    56
(*("is_f_x", ("Integrate.is'_f'_x", eval_is_f_x "is_f_x_"))*)
wneuper@346
    57
fun eval_is_f_x _ _(p as (Const ("Integrate.is'_f'_x", _)
wneuper@346
    58
					   $ arg)) _ =
wneuper@346
    59
    if is_f_x arg
wneuper@346
    60
    then Some ((term2str p) ^ " = True",
wneuper@346
    61
	       Trueprop $ (mk_equality (p, HOLogic.true_const)))
wneuper@346
    62
    else Some ((term2str p) ^ " = False",
wneuper@346
    63
	       Trueprop $ (mk_equality (p, HOLogic.false_const)))
wneuper@346
    64
  | eval_is_f_x _ _ _ _ = None;
wneuper@346
    65
wneuper@339
    66
calclist':= overwritel (!calclist', 
wneuper@346
    67
   [("new_c", ("Integrate.new'_c", eval_new_c "new_c_")),
wneuper@346
    68
    ("is_f_x", ("Integrate.is'_f'_x", eval_is_f_x "is_f_idextifier_"))
wneuper@339
    69
    ]);
wneuper@339
    70
wneuper@376
    71
(** rewrite order 'ord_simplify_Integral' **)
wneuper@376
    72
wneuper@376
    73
(* order wrt. several linear (i.e. without exponents) variables "c","c_2",..
wneuper@376
    74
   which leaves the monomials containing c, c_2,... at the end of an Integral
wneuper@376
    75
   and puts the c, c_2,... rightmost within a monomial.
wneuper@376
    76
wneuper@376
    77
   WN050906 this is a quick and dirty adaption of ord_make_polynomial_in,
wneuper@376
    78
   which was most adequate, because it uses size_of_term*)
wneuper@376
    79
(**)
wneuper@376
    80
local (*. for simplify_Integral .*)
wneuper@376
    81
(**)
wneuper@376
    82
open Term;  (* for type order = EQUAL | LESS | GREATER *)
wneuper@376
    83
wneuper@376
    84
fun pr_ord EQUAL = "EQUAL"
wneuper@376
    85
  | pr_ord LESS  = "LESS"
wneuper@376
    86
  | pr_ord GREATER = "GREATER";
wneuper@376
    87
wneuper@376
    88
fun dest_hd' (Const (a, T)) = (((a, 0), T), 0)
wneuper@376
    89
  | dest_hd' (Free (ccc, T)) =
wneuper@376
    90
    (case explode ccc of
wneuper@376
    91
	"c"::[] => ((("|||||||||||||||||||||", 0), T), 1)(*greatest string WN*)
wneuper@376
    92
      | "c"::"_"::_ => ((("|||||||||||||||||||||", 0), T), 1)
wneuper@376
    93
      | _ => (((ccc, 0), T), 1))
wneuper@376
    94
  | dest_hd' (Var v) = (v, 2)
wneuper@376
    95
  | dest_hd' (Bound i) = ((("", i), dummyT), 3)
wneuper@376
    96
  | dest_hd' (Abs (_, T, _)) = ((("", 0), T), 4);
wneuper@376
    97
wneuper@376
    98
fun size_of_term' (Free (ccc, _)) =
wneuper@376
    99
    (case explode ccc of
wneuper@376
   100
	"c"::[] => 1000
wneuper@376
   101
      | "c"::"_"::is => 1000 * ((str2int o implode) is)
wneuper@376
   102
      | _ => 1)
wneuper@376
   103
  | size_of_term' (Abs (_,_,body)) = 1 + size_of_term' body
wneuper@376
   104
  | size_of_term' (f$t) = size_of_term' f  +  size_of_term' t
wneuper@376
   105
  | size_of_term' _ = 1;
wneuper@376
   106
wneuper@376
   107
fun term_ord' pr thy (Abs (_, T, t), Abs(_, U, u)) =       (* ~ term.ML *)
wneuper@376
   108
      (case term_ord' pr thy (t, u) of EQUAL => typ_ord (T, U) | ord => ord)
wneuper@376
   109
  | term_ord' pr thy (t, u) =
wneuper@376
   110
      (if pr then 
wneuper@376
   111
	 let
wneuper@376
   112
	   val (f, ts) = strip_comb t and (g, us) = strip_comb u;
wneuper@376
   113
	   val _=writeln("t= f@ts= \""^
wneuper@376
   114
	      ((string_of_cterm o cterm_of (sign_of thy)) f)^"\" @ \"["^
wneuper@376
   115
	      (commas(map(string_of_cterm o cterm_of(sign_of thy)) ts))^"]\"");
wneuper@376
   116
	   val _=writeln("u= g@us= \""^
wneuper@376
   117
	      ((string_of_cterm o cterm_of (sign_of thy)) g)^"\" @ \"["^
wneuper@376
   118
	      (commas(map(string_of_cterm o cterm_of(sign_of thy)) us))^"]\"");
wneuper@376
   119
	   val _=writeln("size_of_term(t,u)= ("^
wneuper@376
   120
	      (string_of_int(size_of_term' t))^", "^
wneuper@376
   121
	      (string_of_int(size_of_term' u))^")");
wneuper@376
   122
	   val _=writeln("hd_ord(f,g)      = "^((pr_ord o hd_ord)(f,g)));
wneuper@376
   123
	   val _=writeln("terms_ord(ts,us) = "^
wneuper@376
   124
			   ((pr_ord o terms_ord str false)(ts,us)));
wneuper@376
   125
	   val _=writeln("-------");
wneuper@376
   126
	 in () end
wneuper@376
   127
       else ();
wneuper@376
   128
	 case int_ord (size_of_term' t, size_of_term' u) of
wneuper@376
   129
	   EQUAL =>
wneuper@376
   130
	     let val (f, ts) = strip_comb t and (g, us) = strip_comb u in
wneuper@376
   131
	       (case hd_ord (f, g) of EQUAL => (terms_ord str pr) (ts, us) 
wneuper@376
   132
	     | ord => ord)
wneuper@376
   133
	     end
wneuper@376
   134
	 | ord => ord)
wneuper@376
   135
and hd_ord (f, g) =                                        (* ~ term.ML *)
wneuper@376
   136
  prod_ord (prod_ord indexname_ord typ_ord) int_ord (dest_hd' f, 
wneuper@376
   137
						     dest_hd' g)
wneuper@376
   138
and terms_ord str pr (ts, us) = 
wneuper@376
   139
    list_ord (term_ord' pr (assoc_thy "Isac.thy"))(ts, us);
wneuper@376
   140
(**)
wneuper@376
   141
in
wneuper@376
   142
(**)
wneuper@447
   143
(*WN0510 for preliminary use in eval_order_system, see case-study mat-eng.tex
wneuper@447
   144
fun ord_simplify_Integral_rev (pr:bool) thy subst tu = 
wneuper@447
   145
    (term_ord' pr thy (Library.swap tu) = LESS);*)
wneuper@447
   146
wneuper@414
   147
(*for the rls's*)
wneuper@376
   148
fun ord_simplify_Integral (pr:bool) thy subst tu = 
wneuper@376
   149
    (term_ord' pr thy tu = LESS);
wneuper@376
   150
(**)
wneuper@376
   151
end;
wneuper@376
   152
(**)
wneuper@447
   153
rew_ord' := overwritel (!rew_ord',
wneuper@447
   154
[("ord_simplify_Integral", ord_simplify_Integral false thy)
wneuper@447
   155
 ]);
wneuper@376
   156
wneuper@376
   157
wneuper@339
   158
(** rulesets **)
wneuper@339
   159
wneuper@376
   160
(*.rulesets for integration.*)
wneuper@339
   161
val integration_rules = 
wneuper@339
   162
    prep_rls (Rls {id="integration_rules", preconds = [], 
wneuper@339
   163
		   rew_ord = ("termlessI",termlessI), 
wneuper@339
   164
		   erls = Rls {id="conditions_in_integration_rules", 
wneuper@339
   165
			       preconds = [], 
wneuper@339
   166
			       rew_ord = ("termlessI",termlessI), 
wneuper@339
   167
			       erls = Erls, 
wneuper@339
   168
			       srls = Erls, calc = [],
wneuper@339
   169
			       rules = [(*for rewriting conditions in Thm's*)
wneuper@339
   170
					Calc ("Atools.occurs'_in", 
wneuper@339
   171
					      eval_occurs_in "#occurs_in_"),
wneuper@339
   172
					Thm ("not_true",num_str not_true),
wneuper@339
   173
					Thm ("not_false",not_false)
wneuper@339
   174
					],
wneuper@339
   175
			       scr = EmptyScr}, 
wneuper@339
   176
		   srls = Erls, calc = [],
wneuper@339
   177
		   rules = [
wneuper@339
   178
			    Thm ("integral_const",num_str integral_const),
wneuper@339
   179
			    Thm ("integral_var",num_str integral_var),
wneuper@339
   180
			    Thm ("integral_add",num_str integral_add),
wneuper@339
   181
			    Thm ("integral_mult",num_str integral_mult),
wneuper@339
   182
			    Thm ("integral_pow",num_str integral_pow),
wneuper@339
   183
			    Calc ("op +", eval_binop "#add_")(*for n+1*)
wneuper@339
   184
			    ],
wneuper@339
   185
		   scr = EmptyScr});
wneuper@339
   186
val add_new_c = 
wneuper@339
   187
    prep_rls (Seq {id="add_new_c", preconds = [], 
wneuper@339
   188
		   rew_ord = ("termlessI",termlessI), 
wneuper@339
   189
		   erls = Rls {id="conditions_in_add_new_c", 
wneuper@339
   190
			       preconds = [], 
wneuper@339
   191
			       rew_ord = ("termlessI",termlessI), 
wneuper@339
   192
			       erls = Erls, 
wneuper@339
   193
			       srls = Erls, calc = [],
wneuper@339
   194
			       rules = [Calc ("Tools.matches", eval_matches""),
wneuper@347
   195
					Calc ("Integrate.is'_f'_x", 
wneuper@347
   196
					 eval_is_f_x "is_f_x_"),
wneuper@339
   197
					Thm ("not_true",num_str not_true),
wneuper@339
   198
					Thm ("not_false",num_str not_false)
wneuper@339
   199
					],
wneuper@339
   200
			       scr = EmptyScr}, 
wneuper@339
   201
		   srls = Erls, calc = [],
wneuper@339
   202
		   rules = [ Thm ("call_for_new_c", num_str call_for_new_c),
wneuper@339
   203
			     Calc("Integrate.new'_c", eval_new_c "new_c_")
wneuper@339
   204
			    ],
wneuper@339
   205
		   scr = EmptyScr});
wneuper@376
   206
wneuper@376
   207
(*.rulesets for simplifying Integrals.*)
wneuper@376
   208
wneuper@376
   209
(*'' is adapted from '' by just replacing the rew_ord*)
wneuper@376
   210
val order_add_mult_Integral = 
wneuper@376
   211
  Rls{id = "order_add_mult_Integral", preconds = [], 
wneuper@376
   212
      rew_ord = ("ord_simplify_Integral",
wneuper@376
   213
		 ord_simplify_Integral false Integrate.thy),
wneuper@376
   214
      erls = e_rls,srls = Erls, calc = [],
wneuper@376
   215
      rules = [Thm ("real_mult_commute",num_str real_mult_commute),
wneuper@376
   216
	       (* z * w = w * z *)
wneuper@376
   217
	       Thm ("real_mult_left_commute",num_str real_mult_left_commute),
wneuper@376
   218
	       (*z1.0 * (z2.0 * z3.0) = z2.0 * (z1.0 * z3.0)*)
wneuper@376
   219
	       Thm ("real_mult_assoc",num_str real_mult_assoc),		
wneuper@376
   220
	       (*z1.0 * z2.0 * z3.0 = z1.0 * (z2.0 * z3.0)*)
wneuper@376
   221
	       Thm ("real_add_commute",num_str real_add_commute),	
wneuper@376
   222
	       (*z + w = w + z*)
wneuper@376
   223
	       Thm ("real_add_left_commute",num_str real_add_left_commute),
wneuper@376
   224
	       (*x + (y + z) = y + (x + z)*)
wneuper@376
   225
	       Thm ("real_add_assoc",num_str real_add_assoc)	               
wneuper@376
   226
	       (*z1.0 + z2.0 + z3.0 = z1.0 + (z2.0 + z3.0)*)
wneuper@376
   227
	       ], 
wneuper@376
   228
      scr = EmptyScr}:rls;
wneuper@376
   229
wneuper@377
   230
(*'norm_Rational_no_add_fractions' is adapted from 'norm_Rational' by
wneuper@376
   231
  #1 using 'ord_simplify_Integral' in 'order_add_mult_Integral'
wneuper@376
   232
  #2 NOT using common_nominator_p
wneuper@376
   233
  *)
wneuper@377
   234
val norm_Rational_no_add_fractions = prep_rls(
wneuper@377
   235
  Rls {id = "norm_Rational_no_add_fractions", preconds = [], 
wneuper@376
   236
       rew_ord = ("dummy_ord",dummy_ord), 
wneuper@376
   237
       erls = norm_rat_erls, srls = Erls, calc = [],
wneuper@376
   238
       rules = [(*sequence given by operator precedence*)
wneuper@376
   239
		Rls_ discard_minus,
wneuper@376
   240
		Rls_ powers,
wneuper@376
   241
		Rls_ rat_mult_divide,
wneuper@376
   242
		Rls_ expand,
wneuper@376
   243
		Rls_ reduce_0_1_2,
wneuper@376
   244
		Rls_ (*order_add_mult #1*) order_add_mult_Integral,
wneuper@376
   245
		Rls_ collect_numerals,
wneuper@377
   246
		(*Rls_ add_fractions_p, #2*)
wneuper@376
   247
		Rls_ cancel_p
wneuper@376
   248
		],
wneuper@376
   249
       scr = Script ((term_of o the o (parse thy)) 
wneuper@376
   250
			 "empty_script")
wneuper@376
   251
       }:rls);
wneuper@376
   252
wneuper@407
   253
(*'simplify_Integral' is adapted from 'norm_Rational_parenthesized'
wneuper@376
   254
  this simplifier orders 'c'..'c_123' right most and 
wneuper@376
   255
  does NOT 'common_nominator' for fractions*)
wneuper@376
   256
val simplify_Integral = prep_rls(
wneuper@376
   257
  Seq {id = "simplify_Integral", preconds = []:term list, 
wneuper@376
   258
       rew_ord = ("dummy_ord", dummy_ord),
wneuper@376
   259
      erls = Atools_erls, srls = Erls, calc = [],
wneuper@377
   260
      rules = [Rls_ norm_Rational_no_add_fractions,
wneuper@376
   261
	       Rls_ discard_parentheses
wneuper@376
   262
	       ],
wneuper@376
   263
      scr = EmptyScr
wneuper@376
   264
      }:rls);      
wneuper@376
   265
wneuper@408
   266
(*rls (ab-)used preliminarily for 'EqSystem's in 'Biegelininie'*)
wneuper@408
   267
val simplify_Integral_parenthesized = prep_rls(
wneuper@413
   268
  Seq {id = "simplify_Integral_parenthesized", preconds = []:term list, 
wneuper@408
   269
       rew_ord = ("dummy_ord", dummy_ord),
wneuper@408
   270
      erls = Atools_erls, srls = Erls, calc = [],
wneuper@408
   271
      rules = [Rls_ norm_Rational_no_add_fractions(*,
wneuper@408
   272
	       Rls_ discard_parentheses*)
wneuper@408
   273
	       ],
wneuper@408
   274
      scr = EmptyScr
wneuper@408
   275
      }:rls);      
wneuper@408
   276
wneuper@339
   277
val integration = 
wneuper@339
   278
    prep_rls (Seq {id="integration", preconds = [], 
wneuper@339
   279
		   rew_ord = ("termlessI",termlessI), 
wneuper@339
   280
		   erls = Rls {id="conditions_in_integration", 
wneuper@339
   281
			       preconds = [], 
wneuper@339
   282
			       rew_ord = ("termlessI",termlessI), 
wneuper@339
   283
			       erls = Erls, 
wneuper@339
   284
			       srls = Erls, calc = [],
wneuper@339
   285
			       rules = [],
wneuper@339
   286
			       scr = EmptyScr}, 
wneuper@339
   287
		   srls = Erls, calc = [],
wneuper@339
   288
		   rules = [ Rls_ integration_rules,
wneuper@339
   289
			     Rls_ add_new_c,
wneuper@376
   290
			     Rls_ simplify_Integral
wneuper@339
   291
			    ],
wneuper@339
   292
		   scr = EmptyScr});
wneuper@376
   293
ruleset' := 
wneuper@376
   294
overwritel (!ruleset', 
wneuper@376
   295
	    [("integration_rules", integration_rules),
wneuper@376
   296
	     ("add_new_c", add_new_c),
wneuper@376
   297
	     ("order_add_mult_Integral", order_add_mult_Integral),
wneuper@377
   298
	     ("norm_Rational_no_add_fractions", 
wneuper@377
   299
	      norm_Rational_no_add_fractions),
wneuper@376
   300
	     ("simplify_Integral", simplify_Integral),
wneuper@376
   301
	     ("integration", integration)]);
wneuper@339
   302
wneuper@339
   303
(** problems **)
wneuper@339
   304
wneuper@339
   305
store_pbt
wneuper@339
   306
 (prep_pbt Integrate.thy
wneuper@339
   307
 (["integrate","function"],
wneuper@339
   308
  [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@339
   309
   ("#Find"  ,["antiDerivative F_"])
wneuper@339
   310
  ],
wneuper@339
   311
  append_rls "e_rls" e_rls [(*for preds in where_*)], 
wneuper@339
   312
  Some "Integrate (f_, v_)", 
wneuper@339
   313
  [["Diff","integration"]]));
wneuper@339
   314
 
wneuper@339
   315
store_pbt
wneuper@339
   316
 (prep_pbt Integrate.thy
wneuper@339
   317
 (["named","integrate","function"],
wneuper@339
   318
  [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@347
   319
   ("#Find"  ,["antiDerivativeName F_"])
wneuper@339
   320
  ],
wneuper@339
   321
  append_rls "e_rls" e_rls [(*for preds in where_*)], 
wneuper@339
   322
  Some "Integrate (f_, v_)", 
wneuper@339
   323
  [["Diff","integration","named"]]));
wneuper@339
   324
 
wneuper@339
   325
(** methods **)
wneuper@339
   326
wneuper@339
   327
store_met
wneuper@339
   328
    (prep_met Integrate.thy
wneuper@339
   329
	      (["Diff","integration"],
wneuper@339
   330
	       [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@339
   331
		("#Find"  ,["antiDerivative F_"])
wneuper@339
   332
		],
wneuper@339
   333
	       {rew_ord'="tless_true", rls'=Atools_erls, calc = [], 
wneuper@339
   334
		srls = e_rls, 
wneuper@339
   335
		prls=e_rls,
wneuper@339
   336
	     crls = Atools_erls, nrls = e_rls},
wneuper@339
   337
"Script IntegrationScript (f_::real) (v_::real) =                \
wneuper@339
   338
\  (let t_ = Take (Integral f_ D v_)                             \
wneuper@339
   339
\   in (Rewrite_Set_Inst [(bdv,v_)] integration False) (t_::real))"
wneuper@339
   340
));
wneuper@339
   341
    
wneuper@339
   342
store_met
wneuper@339
   343
    (prep_met Integrate.thy
wneuper@339
   344
	      (["Diff","integration","named"],
wneuper@339
   345
	       [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@347
   346
		("#Find"  ,["antiDerivativeName F_"])
wneuper@339
   347
		],
wneuper@339
   348
	       {rew_ord'="tless_true", rls'=Atools_erls, calc = [], 
wneuper@339
   349
		srls = e_rls, 
wneuper@339
   350
		prls=e_rls,
wneuper@339
   351
		crls = Atools_erls, nrls = e_rls},
wneuper@347
   352
"Script NamedIntegrationScript (f_::real) (v_::real) (F_::real=>real) = \
wneuper@347
   353
\  (let t_ = Take (F_ v_ = Integral f_ D v_)                         \
wneuper@339
   354
\   in (Rewrite_Set_Inst [(bdv,v_)] integration False) t_)"
wneuper@339
   355
 ));
wneuper@339
   356