src/sml/IsacKnowledge/Integrate.ML
author wneuper
Fri, 28 Oct 2005 18:25:12 +0200
branchstart_Take
changeset 454 d38ad8b7d642
parent 453 6fe0f3a4b9ab
child 457 4872ccfdf758
permissions -rw-r--r--
working on simplify_System
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@453
     7
wneuper@453
     8
remove_thy"Integrate";
wneuper@453
     9
use_thy"IsacKnowledge/Isac";
wneuper@339
    10
*)
wneuper@339
    11
wneuper@339
    12
(** interface isabelle -- isac **)
wneuper@339
    13
wneuper@339
    14
theory' := overwritel (!theory', [("Integrate.thy",Integrate.thy)]);
wneuper@339
    15
wneuper@339
    16
theorem' := overwritel (!theorem',
wneuper@339
    17
[("integral_const",num_str integral_const),
wneuper@339
    18
 ("integral_var",num_str integral_var),
wneuper@339
    19
 ("integral_add",num_str integral_add),
wneuper@339
    20
 ("integral_mult",num_str integral_mult),
wneuper@339
    21
 ("call_for_new_c",num_str call_for_new_c),
wneuper@339
    22
 ("integral_pow",num_str integral_pow)
wneuper@339
    23
]);
wneuper@339
    24
wneuper@339
    25
(** eval functions **)
wneuper@339
    26
wneuper@339
    27
val c = Free ("c", HOLogic.realT);
wneuper@417
    28
(*.create a new unique variable 'c..' in a term; for use by Calc in a rls;
wneuper@417
    29
   an alternative to do this would be '(Try (Calculate new_c_) (new_c es__))'
wneuper@417
    30
   in the script; this will be possible if currying doesnt take the value
wneuper@417
    31
   from a variable, but the value '(new_c es__)' itself.*)
wneuper@339
    32
fun new_c term = 
wneuper@339
    33
    let fun selc var = 
wneuper@339
    34
	    case (explode o id_of) var of
wneuper@339
    35
		"c"::[] => true
wneuper@339
    36
	      |	"c"::"_"::is => (case (int_of_str o implode) is of
wneuper@339
    37
				     Some _ => true
wneuper@339
    38
				   | None => false)
wneuper@339
    39
              | _ => false;
wneuper@339
    40
	fun get_coeff c = case (explode o id_of) c of
wneuper@339
    41
	      		      "c"::"_"::is => (the o int_of_str o implode) is
wneuper@339
    42
			    | _ => 0;
wneuper@339
    43
        val cs = filter selc (vars term);
wneuper@339
    44
    in 
wneuper@339
    45
	case cs of
wneuper@339
    46
	    [] => c
wneuper@339
    47
	  | [c] => Free ("c_2", HOLogic.realT)
wneuper@339
    48
	  | cs => 
wneuper@339
    49
	    let val max_coeff = maxl (map get_coeff cs)
wneuper@339
    50
	    in Free ("c_"^string_of_int (max_coeff + 1), HOLogic.realT) end
wneuper@339
    51
    end;
wneuper@339
    52
wneuper@414
    53
(*("new_c", ("Integrate.new'_c", eval_new_c "#new_c_"))*)
wneuper@339
    54
fun eval_new_c _ _ (p as (Const ("Integrate.new'_c",_) $ t)) _ =
wneuper@339
    55
     Some ((term2str p) ^ " = " ^ term2str (new_c p),
wneuper@339
    56
	  Trueprop $ (mk_equality (p, new_c p)))
wneuper@339
    57
  | eval_new_c _ _ _ _ = None;
wneuper@339
    58
wneuper@346
    59
(*("is_f_x", ("Integrate.is'_f'_x", eval_is_f_x "is_f_x_"))*)
wneuper@346
    60
fun eval_is_f_x _ _(p as (Const ("Integrate.is'_f'_x", _)
wneuper@346
    61
					   $ arg)) _ =
wneuper@346
    62
    if is_f_x arg
wneuper@346
    63
    then Some ((term2str p) ^ " = True",
wneuper@346
    64
	       Trueprop $ (mk_equality (p, HOLogic.true_const)))
wneuper@346
    65
    else Some ((term2str p) ^ " = False",
wneuper@346
    66
	       Trueprop $ (mk_equality (p, HOLogic.false_const)))
wneuper@346
    67
  | eval_is_f_x _ _ _ _ = None;
wneuper@346
    68
wneuper@339
    69
calclist':= overwritel (!calclist', 
wneuper@346
    70
   [("new_c", ("Integrate.new'_c", eval_new_c "new_c_")),
wneuper@346
    71
    ("is_f_x", ("Integrate.is'_f'_x", eval_is_f_x "is_f_idextifier_"))
wneuper@339
    72
    ]);
wneuper@339
    73
wneuper@376
    74
wneuper@339
    75
(** rulesets **)
wneuper@339
    76
wneuper@376
    77
(*.rulesets for integration.*)
wneuper@339
    78
val integration_rules = 
wneuper@339
    79
    prep_rls (Rls {id="integration_rules", preconds = [], 
wneuper@339
    80
		   rew_ord = ("termlessI",termlessI), 
wneuper@339
    81
		   erls = Rls {id="conditions_in_integration_rules", 
wneuper@339
    82
			       preconds = [], 
wneuper@339
    83
			       rew_ord = ("termlessI",termlessI), 
wneuper@339
    84
			       erls = Erls, 
wneuper@339
    85
			       srls = Erls, calc = [],
wneuper@339
    86
			       rules = [(*for rewriting conditions in Thm's*)
wneuper@339
    87
					Calc ("Atools.occurs'_in", 
wneuper@339
    88
					      eval_occurs_in "#occurs_in_"),
wneuper@339
    89
					Thm ("not_true",num_str not_true),
wneuper@339
    90
					Thm ("not_false",not_false)
wneuper@339
    91
					],
wneuper@339
    92
			       scr = EmptyScr}, 
wneuper@339
    93
		   srls = Erls, calc = [],
wneuper@339
    94
		   rules = [
wneuper@339
    95
			    Thm ("integral_const",num_str integral_const),
wneuper@339
    96
			    Thm ("integral_var",num_str integral_var),
wneuper@339
    97
			    Thm ("integral_add",num_str integral_add),
wneuper@339
    98
			    Thm ("integral_mult",num_str integral_mult),
wneuper@339
    99
			    Thm ("integral_pow",num_str integral_pow),
wneuper@339
   100
			    Calc ("op +", eval_binop "#add_")(*for n+1*)
wneuper@339
   101
			    ],
wneuper@339
   102
		   scr = EmptyScr});
wneuper@339
   103
val add_new_c = 
wneuper@339
   104
    prep_rls (Seq {id="add_new_c", preconds = [], 
wneuper@339
   105
		   rew_ord = ("termlessI",termlessI), 
wneuper@339
   106
		   erls = Rls {id="conditions_in_add_new_c", 
wneuper@339
   107
			       preconds = [], 
wneuper@339
   108
			       rew_ord = ("termlessI",termlessI), 
wneuper@339
   109
			       erls = Erls, 
wneuper@339
   110
			       srls = Erls, calc = [],
wneuper@339
   111
			       rules = [Calc ("Tools.matches", eval_matches""),
wneuper@347
   112
					Calc ("Integrate.is'_f'_x", 
wneuper@347
   113
					 eval_is_f_x "is_f_x_"),
wneuper@339
   114
					Thm ("not_true",num_str not_true),
wneuper@339
   115
					Thm ("not_false",num_str not_false)
wneuper@339
   116
					],
wneuper@339
   117
			       scr = EmptyScr}, 
wneuper@339
   118
		   srls = Erls, calc = [],
wneuper@339
   119
		   rules = [ Thm ("call_for_new_c", num_str call_for_new_c),
wneuper@339
   120
			     Calc("Integrate.new'_c", eval_new_c "new_c_")
wneuper@339
   121
			    ],
wneuper@339
   122
		   scr = EmptyScr});
wneuper@376
   123
wneuper@376
   124
(*.rulesets for simplifying Integrals.*)
wneuper@376
   125
wneuper@451
   126
(*.for simplify_Integral adapted from 'norm_Rational_rls'.*)
wneuper@451
   127
val norm_Rational_rls_noadd_fractions = prep_rls(
wneuper@453
   128
Rls {id = "norm_Rational_rls_noadd_fractions", preconds = [], 
wneuper@453
   129
     rew_ord = ("dummy_ord",dummy_ord), 
wneuper@453
   130
     erls = norm_rat_erls, srls = Erls, calc = [],
wneuper@453
   131
     rules = [(*Rls_ common_nominator_p_rls,!!!*)
wneuper@453
   132
	      Rls_ (*rat_mult_div_pow original corrected WN051028*)
wneuper@453
   133
		  (Rls {id = "rat_mult_div_pow", preconds = [], 
wneuper@453
   134
		       rew_ord = ("dummy_ord",dummy_ord), 
wneuper@453
   135
		       erls = (*FIXME.WN051028 e_rls,*)
wneuper@453
   136
		       append_rls "e_rls-is_polyexp" e_rls
wneuper@453
   137
				  [Calc ("Poly.is'_polyexp", 
wneuper@453
   138
					 eval_is_polyexp "")],
wneuper@453
   139
				  srls = Erls, calc = [],
wneuper@453
   140
				  rules = [Thm ("rat_mult",num_str rat_mult),
wneuper@453
   141
	       (*"?a / ?b * (?c / ?d) = ?a * ?c / (?b * ?d)"*)
wneuper@453
   142
	       Thm ("rat_mult_poly_l",num_str rat_mult_poly_l),
wneuper@453
   143
	       (*"?c is_polyexp ==> ?c * (?a / ?b) = ?c * ?a / ?b"*)
wneuper@453
   144
	       Thm ("rat_mult_poly_r",num_str rat_mult_poly_r),
wneuper@453
   145
	       (*"?c is_polyexp ==> ?a / ?b * ?c = ?a * ?c / ?b"*)
wneuper@453
   146
wneuper@453
   147
	       Thm ("real_divide_divide1_mg", real_divide_divide1_mg),
wneuper@453
   148
	       (*"y ~= 0 ==> (u / v) / (y / z) = (u * z) / (y * v)"*)
wneuper@453
   149
	       Thm ("real_divide_divide1_eq", real_divide_divide1_eq),
wneuper@453
   150
	       (*"?x / (?y / ?z) = ?x * ?z / ?y"*)
wneuper@453
   151
	       Thm ("real_divide_divide2_eq", real_divide_divide2_eq),
wneuper@453
   152
	       (*"?x / ?y / ?z = ?x / (?y * ?z)"*)
wneuper@453
   153
	       Calc ("HOL.divide"  ,eval_cancel "#divide_"),
wneuper@453
   154
	      
wneuper@453
   155
	       Thm ("rat_power", num_str rat_power)
wneuper@453
   156
		(*"(?a / ?b) ^^^ ?n = ?a ^^^ ?n / ?b ^^^ ?n"*)
wneuper@453
   157
	       ],
wneuper@453
   158
      scr = Script ((term_of o the o (parse thy)) "empty_script")
wneuper@453
   159
      }),
wneuper@451
   160
		Rls_ make_rat_poly_with_parentheses,
wneuper@451
   161
		Rls_ cancel_p_rls,(*FIXME:cancel_p does NOT order sometimes*)
wneuper@451
   162
		Rls_ rat_reduce_1
wneuper@376
   163
		],
wneuper@451
   164
       scr = Script ((term_of o the o (parse thy)) "empty_script")
wneuper@376
   165
       }:rls);
wneuper@376
   166
wneuper@451
   167
(*.for simplify_Integral adapted from 'norm_Rational'.*)
wneuper@451
   168
val norm_Rational_noadd_fractions = prep_rls(
wneuper@451
   169
   Seq {id = "norm_Rational_noadd_fractions", preconds = [], 
wneuper@451
   170
       rew_ord = ("dummy_ord",dummy_ord), 
wneuper@451
   171
       erls = norm_rat_erls, srls = Erls, calc = [],
wneuper@451
   172
       rules = [Rls_ discard_minus_,
wneuper@451
   173
		Rls_ rat_mult_poly,(* removes double fractions like a/b/c    *)
wneuper@451
   174
		Rls_ make_rat_poly_with_parentheses, (*WN0510 also in(#)below*)
wneuper@451
   175
		Rls_ cancel_p_rls, (*FIXME.MG:cancel_p does NOT order sometim*)
wneuper@451
   176
		Rls_ norm_Rational_rls_noadd_fractions,(* the main rls (#)   *)
wneuper@451
   177
		Rls_ discard_parentheses_ (* mult only                       *)
wneuper@451
   178
		],
wneuper@451
   179
       scr = Script ((term_of o the o (parse thy)) "empty_script")
wneuper@451
   180
       }:rls);
wneuper@451
   181
wneuper@451
   182
(*.simplify terms before and after Integration such that  
wneuper@451
   183
   ..a.x^2/2 + b.x^3/3.. is made to ..a/2.x^2 + b/3.x^3.. (and NO
wneuper@451
   184
   common denominator as done by norm_Rational or make_ratpoly_in.
wneuper@451
   185
   This is a copy from 'make_ratpoly_in' with respective reduction of rules.*)
wneuper@376
   186
val simplify_Integral = prep_rls(
wneuper@376
   187
  Seq {id = "simplify_Integral", preconds = []:term list, 
wneuper@376
   188
       rew_ord = ("dummy_ord", dummy_ord),
wneuper@451
   189
      erls = Atools_erls, srls = Erls,
wneuper@451
   190
      calc = [], (*asm_thm = [],*)
wneuper@451
   191
      rules = [Rls_ norm_Rational_noadd_fractions,
wneuper@451
   192
	       Rls_ order_add_mult_in,
wneuper@451
   193
	       Rls_ discard_parentheses,
wneuper@451
   194
	       (*Rls_ collect_bdv, from make_polynomial_in*)
wneuper@451
   195
	       Rls_ (append_rls "separate_bdv"
wneuper@451
   196
			 collect_bdv
wneuper@451
   197
			 [Thm ("separate_bdv", num_str separate_bdv),
wneuper@451
   198
			  (*"?a * ?bdv / ?b = ?a / ?b * ?bdv"*)
wneuper@451
   199
			  Thm ("separate_bdv_n", num_str separate_bdv_n),
wneuper@451
   200
			  Thm ("separate_1_bdv", num_str separate_1_bdv),
wneuper@451
   201
			  (*"?bdv / ?b = (1 / ?b) * ?bdv"*)
wneuper@451
   202
			  Thm ("separate_1_bdv_n", num_str separate_1_bdv_n)(*,
wneuper@451
   203
			  (*"?bdv ^^^ ?n / ?b = 1 / ?b * ?bdv ^^^ ?n"*)
wneuper@451
   204
			  Thm ("real_add_divide_distrib", 
wneuper@451
   205
			       num_str real_add_divide_distrib)
wneuper@451
   206
			  (*"(?x + ?y) / ?z = ?x / ?z + ?y / ?z"*)----------*)
wneuper@451
   207
			  ]),
wneuper@451
   208
	       Calc ("HOL.divide"  ,eval_cancel "#divide_")
wneuper@451
   209
	       ],
wneuper@451
   210
      scr = EmptyScr}:rls);      
wneuper@451
   211
wneuper@451
   212
wneuper@453
   213
(*simplify terms before and after Integration such that  
wneuper@451
   214
   ..a.x^2/2 + b.x^3/3.. is made to ..a/2.x^2 + b/3.x^3.. (and NO
wneuper@451
   215
   common denominator as done by norm_Rational or make_ratpoly_in.
wneuper@451
   216
   This is a copy from 'make_polynomial_in' with insertions from 
wneuper@453
   217
   'make_ratpoly_in' 
wneuper@453
   218
THIS IS KEPT FOR COMPARISON ............................................   
wneuper@451
   219
val simplify_Integral = prep_rls(
wneuper@451
   220
  Seq {id = "", preconds = []:term list, 
wneuper@451
   221
       rew_ord = ("dummy_ord", dummy_ord),
wneuper@451
   222
      erls = Atools_erls, srls = Erls,
wneuper@451
   223
      calc = [], (*asm_thm = [],*)
wneuper@451
   224
      rules = [Rls_ expand_poly,
wneuper@451
   225
	       Rls_ order_add_mult_in,
wneuper@451
   226
	       Rls_ simplify_power,
wneuper@451
   227
	       Rls_ collect_numerals,
wneuper@451
   228
	       Rls_ reduce_012,
wneuper@451
   229
	       Thm ("realpow_oneI",num_str realpow_oneI),
wneuper@451
   230
	       Rls_ discard_parentheses,
wneuper@451
   231
	       Rls_ collect_bdv,
wneuper@451
   232
	       (*below inserted from 'make_ratpoly_in'*)
wneuper@451
   233
	       Rls_ (append_rls "separate_bdv"
wneuper@451
   234
			 collect_bdv
wneuper@451
   235
			 [Thm ("separate_bdv", num_str separate_bdv),
wneuper@451
   236
			  (*"?a * ?bdv / ?b = ?a / ?b * ?bdv"*)
wneuper@451
   237
			  Thm ("separate_bdv_n", num_str separate_bdv_n),
wneuper@451
   238
			  Thm ("separate_1_bdv", num_str separate_1_bdv),
wneuper@451
   239
			  (*"?bdv / ?b = (1 / ?b) * ?bdv"*)
wneuper@451
   240
			  Thm ("separate_1_bdv_n", num_str separate_1_bdv_n)(*,
wneuper@451
   241
			  (*"?bdv ^^^ ?n / ?b = 1 / ?b * ?bdv ^^^ ?n"*)
wneuper@451
   242
			  Thm ("real_add_divide_distrib", 
wneuper@451
   243
				 num_str real_add_divide_distrib)
wneuper@451
   244
			   (*"(?x + ?y) / ?z = ?x / ?z + ?y / ?z"*)*)
wneuper@451
   245
			  ]),
wneuper@451
   246
	       Calc ("HOL.divide"  ,eval_cancel "#divide_")
wneuper@376
   247
	       ],
wneuper@376
   248
      scr = EmptyScr
wneuper@453
   249
      }:rls); 
wneuper@453
   250
.......................................................................*)     
wneuper@408
   251
wneuper@339
   252
val integration = 
wneuper@339
   253
    prep_rls (Seq {id="integration", preconds = [], 
wneuper@339
   254
		   rew_ord = ("termlessI",termlessI), 
wneuper@339
   255
		   erls = Rls {id="conditions_in_integration", 
wneuper@339
   256
			       preconds = [], 
wneuper@339
   257
			       rew_ord = ("termlessI",termlessI), 
wneuper@339
   258
			       erls = Erls, 
wneuper@339
   259
			       srls = Erls, calc = [],
wneuper@339
   260
			       rules = [],
wneuper@339
   261
			       scr = EmptyScr}, 
wneuper@339
   262
		   srls = Erls, calc = [],
wneuper@339
   263
		   rules = [ Rls_ integration_rules,
wneuper@339
   264
			     Rls_ add_new_c,
wneuper@376
   265
			     Rls_ simplify_Integral
wneuper@339
   266
			    ],
wneuper@339
   267
		   scr = EmptyScr});
wneuper@376
   268
ruleset' := 
wneuper@376
   269
overwritel (!ruleset', 
wneuper@376
   270
	    [("integration_rules", integration_rules),
wneuper@376
   271
	     ("add_new_c", add_new_c),
wneuper@376
   272
	     ("simplify_Integral", simplify_Integral),
wneuper@376
   273
	     ("integration", integration)]);
wneuper@339
   274
wneuper@339
   275
(** problems **)
wneuper@339
   276
wneuper@339
   277
store_pbt
wneuper@339
   278
 (prep_pbt Integrate.thy
wneuper@339
   279
 (["integrate","function"],
wneuper@339
   280
  [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@339
   281
   ("#Find"  ,["antiDerivative F_"])
wneuper@339
   282
  ],
wneuper@339
   283
  append_rls "e_rls" e_rls [(*for preds in where_*)], 
wneuper@339
   284
  Some "Integrate (f_, v_)", 
wneuper@339
   285
  [["Diff","integration"]]));
wneuper@339
   286
 
wneuper@339
   287
store_pbt
wneuper@339
   288
 (prep_pbt Integrate.thy
wneuper@339
   289
 (["named","integrate","function"],
wneuper@339
   290
  [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@347
   291
   ("#Find"  ,["antiDerivativeName F_"])
wneuper@339
   292
  ],
wneuper@339
   293
  append_rls "e_rls" e_rls [(*for preds in where_*)], 
wneuper@339
   294
  Some "Integrate (f_, v_)", 
wneuper@339
   295
  [["Diff","integration","named"]]));
wneuper@339
   296
 
wneuper@339
   297
(** methods **)
wneuper@339
   298
wneuper@339
   299
store_met
wneuper@339
   300
    (prep_met Integrate.thy
wneuper@339
   301
	      (["Diff","integration"],
wneuper@339
   302
	       [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@339
   303
		("#Find"  ,["antiDerivative F_"])
wneuper@339
   304
		],
wneuper@339
   305
	       {rew_ord'="tless_true", rls'=Atools_erls, calc = [], 
wneuper@339
   306
		srls = e_rls, 
wneuper@339
   307
		prls=e_rls,
wneuper@339
   308
	     crls = Atools_erls, nrls = e_rls},
wneuper@339
   309
"Script IntegrationScript (f_::real) (v_::real) =                \
wneuper@339
   310
\  (let t_ = Take (Integral f_ D v_)                             \
wneuper@339
   311
\   in (Rewrite_Set_Inst [(bdv,v_)] integration False) (t_::real))"
wneuper@339
   312
));
wneuper@339
   313
    
wneuper@339
   314
store_met
wneuper@339
   315
    (prep_met Integrate.thy
wneuper@339
   316
	      (["Diff","integration","named"],
wneuper@339
   317
	       [("#Given" ,["functionTerm f_", "integrateBy v_"]),
wneuper@347
   318
		("#Find"  ,["antiDerivativeName F_"])
wneuper@339
   319
		],
wneuper@339
   320
	       {rew_ord'="tless_true", rls'=Atools_erls, calc = [], 
wneuper@339
   321
		srls = e_rls, 
wneuper@339
   322
		prls=e_rls,
wneuper@339
   323
		crls = Atools_erls, nrls = e_rls},
wneuper@347
   324
"Script NamedIntegrationScript (f_::real) (v_::real) (F_::real=>real) = \
wneuper@347
   325
\  (let t_ = Take (F_ v_ = Integral f_ D v_)                         \
wneuper@339
   326
\   in (Rewrite_Set_Inst [(bdv,v_)] integration False) t_)"
wneuper@339
   327
 ));
wneuper@339
   328