src/Tools/isac/Knowledge/Diff.thy
author wneuper <Walther.Neuper@jku.at>
Mon, 01 Jan 2024 11:31:16 +0100
changeset 60789 8fa678b678e8
parent 60675 d841c720d288
permissions -rw-r--r--
Doc/Specify_Phase 4: start use antiquotations from isar-ref
neuper@37906
     1
(* differentiation over the reals
neuper@37906
     2
   author: Walther Neuper
neuper@37906
     3
   000516   
neuper@37906
     4
 *)
neuper@37906
     5
wneuper@59424
     6
theory Diff imports Calculus Trig LogExp Rational Root Poly Base_Tools begin
neuper@37906
     7
wneuper@59472
     8
ML \<open>
neuper@37993
     9
@{term "sin x"}
wneuper@59472
    10
\<close>
neuper@37993
    11
neuper@37906
    12
consts
neuper@37906
    13
Walther@60574
    14
  d_d           :: "[real, real] => real"
wneuper@59551
    15
neuper@37906
    16
  (*descriptions in the related problems*)
neuper@37993
    17
  derivativeEq  :: "bool => una"
neuper@37906
    18
neuper@37906
    19
  (*predicates*)
neuper@37906
    20
  primed        :: "'a => 'a" (*"primed A" -> "A'"*)
neuper@37906
    21
walther@60242
    22
  (*the CAS-commands, eg. "Diff (2*x \<up> 3, x)", 
neuper@37906
    23
			  "Differentiate (A = s * (a - s), s)"*)
neuper@37906
    24
  Diff           :: "[real * real] => real"
neuper@37906
    25
  Differentiate  :: "[bool * real] => bool"
neuper@37906
    26
wneuper@59551
    27
  (*subproblem-name*)
wneuper@59484
    28
  differentiate  :: "[char list * char list list * char list, real, real] => real"
neuper@37906
    29
               	   ("(differentiate (_)/ (_ _ ))" 9)
neuper@37906
    30
wneuper@59472
    31
text \<open>a variant of the derivatives defintion:
neuper@37906
    32
neuper@37954
    33
  d_d            :: "(real => real) => (real => real)"
neuper@37954
    34
neuper@37954
    35
  advantages:
neuper@37954
    36
(1) no variable 'bdv' on the meta-level required
neuper@37954
    37
(2) chain_rule "d_d (%x. (u (v x))) = (%x. (d_d u)) (v x) * d_d v"
neuper@37954
    38
(3) and no specialized chain-rules required like
neuper@37954
    39
    diff_sin_chain "d_d bdv (sin u)    = cos u * d_d bdv u"
neuper@37954
    40
neuper@37954
    41
  disadvantage: d_d (%x. 1 + x^2) = ... differs from high-school notation
wneuper@59472
    42
\<close>
neuper@37954
    43
neuper@52148
    44
axiomatization where (*stated as axioms, todo: prove as theorems
neuper@37906
    45
        'bdv' is a constant on the meta-level  *)
neuper@52148
    46
  diff_const:     "[| Not (bdv occurs_in a) |] ==> d_d bdv a = 0" and
neuper@52148
    47
  diff_var:       "d_d bdv bdv = 1" and
neuper@37983
    48
  diff_prod_const:"[| Not (bdv occurs_in u) |] ==>  
neuper@52148
    49
					 d_d bdv (u * v) = u * d_d bdv v" and
neuper@37906
    50
neuper@52148
    51
  diff_sum:       "d_d bdv (u + v)     = d_d bdv u + d_d bdv v" and
neuper@52148
    52
  diff_dif:       "d_d bdv (u - v)     = d_d bdv u - d_d bdv v" and
neuper@52148
    53
  diff_prod:      "d_d bdv (u * v)     = d_d bdv u * v + u * d_d bdv v" and
neuper@37983
    54
  diff_quot:      "Not (v = 0) ==> (d_d bdv (u / v) =  
walther@60242
    55
	           (d_d bdv u * v - u * d_d bdv v) / v \<up> 2)" and
neuper@37906
    56
neuper@52148
    57
  diff_sin:       "d_d bdv (sin bdv)   = cos bdv" and
neuper@52148
    58
  diff_sin_chain: "d_d bdv (sin u)     = cos u * d_d bdv u" and
neuper@52148
    59
  diff_cos:       "d_d bdv (cos bdv)   = - sin bdv" and
neuper@52148
    60
  diff_cos_chain: "d_d bdv (cos u)     = - sin u * d_d bdv u" and
walther@60242
    61
  diff_pow:       "d_d bdv (bdv \<up> n) = n * (bdv \<up> (n - 1))" and
walther@60242
    62
  diff_pow_chain: "d_d bdv (u \<up> n)   = n * (u \<up> (n - 1)) * d_d bdv u" and
neuper@52148
    63
  diff_ln:        "d_d bdv (ln bdv)    = 1 / bdv" and
neuper@52148
    64
  diff_ln_chain:  "d_d bdv (ln u)      = d_d bdv u / u" and
neuper@52148
    65
  diff_exp:       "d_d bdv (exp bdv)   = exp bdv" and
neuper@52148
    66
  diff_exp_chain: "d_d bdv (exp u)     = exp u * d_d x u" and
neuper@37906
    67
(*
neuper@37906
    68
  diff_sqrt      "d_d bdv (sqrt bdv)  = 1 / (2 * sqrt bdv)"
neuper@37906
    69
  diff_sqrt_chain"d_d bdv (sqrt u)    = d_d bdv u / (2 * sqrt u)"
neuper@37906
    70
*)
neuper@37906
    71
  (*...*)
neuper@37906
    72
neuper@37983
    73
  frac_conv:       "[| bdv occurs_in b; 0 < n |] ==>  
walther@60242
    74
		    a / (b \<up> n) = a * b \<up> (-n)" and
walther@60242
    75
  frac_sym_conv:   "n < 0 ==> a * b \<up> n = a / b \<up> (-n)" and
neuper@37906
    76
walther@60242
    77
  sqrt_conv_bdv:   "sqrt bdv = bdv \<up> (1 / 2)" and
walther@60242
    78
  sqrt_conv_bdv_n: "sqrt (bdv \<up> n) = bdv \<up> (n / 2)" and
walther@60269
    79
(*Ambiguous input\<^here> produces 3 parse trees -----------------------------\\*)
walther@60242
    80
  sqrt_conv:       "bdv occurs_in u ==> sqrt u = u \<up> (1 / 2)" and
walther@60269
    81
(*Ambiguous input\<^here> produces 3 parse trees -----------------------------//*)
walther@60242
    82
  sqrt_sym_conv:   "u \<up> (a / 2) = sqrt (u \<up> a)" and
neuper@37906
    83
walther@60242
    84
  root_conv:       "bdv occurs_in u ==> nroot n u = u \<up> (1 / n)" and
walther@60242
    85
  root_sym_conv:   "u \<up> (a / b) = nroot b (u \<up> a)" and
neuper@37906
    86
walther@60242
    87
  realpow_pow_bdv: "(bdv \<up> b) \<up> c = bdv \<up> (b * c)"
neuper@37906
    88
wneuper@59472
    89
ML \<open>
neuper@37954
    90
(** eval functions **)
neuper@37954
    91
neuper@37954
    92
fun primed (Const (id, T)) = Const (id ^ "'", T)
neuper@37954
    93
  | primed (Free (id, T)) = Free (id ^ "'", T)
Walther@60675
    94
  | primed t = raise ERROR ("primed called with arg = '"^ UnparseC.term @{context} t ^"'");
neuper@37954
    95
neuper@37954
    96
(*("primed", ("Diff.primed", eval_primed "#primed"))*)
walther@60335
    97
fun eval_primed _ _ (p as (Const (\<^const_name>\<open>Diff.primed\<close>,_) $ t)) _ =
Walther@60675
    98
    SOME ((UnparseC.term @{context} p) ^ " = " ^ UnparseC.term @{context} (primed t),
wneuper@59390
    99
	  HOLogic.Trueprop $ (TermC.mk_equality (p, primed t)))
neuper@37954
   100
  | eval_primed _ _ _ _ = NONE;
wneuper@59472
   101
\<close>
wenzelm@60313
   102
wenzelm@60313
   103
calculation primed = \<open>eval_primed "#primed"\<close>
wenzelm@60313
   104
wneuper@59472
   105
ML \<open>
neuper@37954
   106
(** rulesets **)
neuper@37954
   107
neuper@37954
   108
(*.converts a term such that differentiation works optimally.*)
neuper@37954
   109
val diff_conv =   
walther@60358
   110
  Rule_Def.Repeat {id="diff_conv", preconds = [], rew_ord = ("termlessI",termlessI), 
Walther@60586
   111
  asm_rls = Rule_Set.append_rules "erls_diff_conv" Rule_Set.empty [
walther@60358
   112
    \<^rule_eval>\<open>Prog_Expr.occurs_in\<close> (Prog_Expr.eval_occurs_in ""),
walther@60358
   113
    \<^rule_thm>\<open>not_true\<close>,
walther@60358
   114
    \<^rule_thm>\<open>not_false\<close>,
walther@60358
   115
    \<^rule_eval>\<open>less\<close> (Prog_Expr.eval_equ "#less_"),
walther@60358
   116
    \<^rule_thm>\<open>and_true\<close>,
walther@60358
   117
    \<^rule_thm>\<open>and_false\<close>], 
Walther@60586
   118
  prog_rls = Rule_Set.Empty, calc = [], errpatts = [],
walther@60358
   119
  rules = [
walther@60358
   120
     \<^rule_thm>\<open>frac_conv\<close>, (*"?bdv occurs_in ?b \<Longrightarrow> 0 < ?n \<Longrightarrow> ?a / ?b \<up> ?n = ?a * ?b \<up> - ?n"*)
walther@60358
   121
 	   \<^rule_thm>\<open>sqrt_conv_bdv\<close>, (*"sqrt ?bdv = ?bdv \<up> (1 / 2)"*)
walther@60358
   122
 	   \<^rule_thm>\<open>sqrt_conv_bdv_n\<close>, (*"sqrt (?bdv \<up> ?n) = ?bdv \<up> (?n / 2)"*)
walther@60358
   123
 	   \<^rule_thm>\<open>sqrt_conv\<close>, (*"?bdv occurs_in ?u \<Longrightarrow> sqrt ?u = ?u \<up> (1 / 2)"*)
walther@60358
   124
 	   \<^rule_thm>\<open>root_conv\<close>, (*"?bdv occurs_in ?u \<Longrightarrow> nroot ?n ?u = ?u \<up> (1 / ?n)"*)
walther@60358
   125
 	   \<^rule_thm>\<open>realpow_pow_bdv\<close>, (* "(?bdv \<up> ?b) \<up> ?c = ?bdv \<up> (?b * ?c)"*)
Walther@60515
   126
 	   \<^rule_eval>\<open>times\<close> (**)(Calc_Binop.numeric "#mult_"),
walther@60358
   127
 	   \<^rule_thm>\<open>rat_mult\<close>, (*a / b * (c / d) = a * c / (b * d)*)
walther@60358
   128
 	   \<^rule_thm>\<open>times_divide_eq_right\<close>, (*?x * (?y / ?z) = ?x * ?y / ?z*)
walther@60358
   129
 	   \<^rule_thm>\<open>times_divide_eq_left\<close>], (*?y / ?z * ?x = ?y * ?x / ?z*)
Walther@60586
   130
  program = Rule.Empty_Prog};
wneuper@59472
   131
\<close>
wneuper@59472
   132
ML \<open>
neuper@37954
   133
(*.beautifies a term after differentiation.*)
neuper@37954
   134
val diff_sym_conv =   
walther@60358
   135
  Rule_Def.Repeat {id="diff_sym_conv", preconds = [], rew_ord = ("termlessI",termlessI), 
Walther@60586
   136
  asm_rls = Rule_Set.append_rules "erls_diff_sym_conv" Rule_Set.empty [
walther@60358
   137
    \<^rule_eval>\<open>less\<close> (Prog_Expr.eval_equ "#less_"), 
walther@60358
   138
    \<^rule_eval>\<open>matches\<close> (Prog_Expr.eval_matches "#matches_"),
walther@60385
   139
    \<^rule_eval>\<open>is_atom\<close> (Prog_Expr.eval_is_atom "#is_atom_"),
walther@60384
   140
    \<^rule_eval>\<open>is_num\<close> (Prog_Expr.eval_is_num "#is_num_"),
walther@60358
   141
    \<^rule_eval>\<open>less\<close> (Prog_Expr.eval_equ "#less_"),
walther@60358
   142
    \<^rule_thm>\<open>not_false\<close>,
walther@60358
   143
    \<^rule_thm>\<open>not_true\<close>], 
Walther@60586
   144
  prog_rls = Rule_Set.Empty, calc = [], errpatts = [],
walther@60358
   145
  rules = [
walther@60358
   146
    \<^rule_thm>\<open>frac_sym_conv\<close>,
walther@60358
   147
    \<^rule_thm>\<open>sqrt_sym_conv\<close>,
walther@60358
   148
    \<^rule_thm>\<open>root_sym_conv\<close>,
walther@60385
   149
    \<^rule_thm>\<open>real_mult_minus1_sym\<close> (*"\<not>(z is_atom) ==> - (z::real) = -1 * z"*),
walther@60384
   150
    \<^rule_thm>\<open>minus_minus\<close> (*"- (- ?a) = ?a"*),
walther@60358
   151
    \<^rule_thm>\<open>rat_mult\<close> (*a / b * (c / d) = a * c / (b * d)*),
walther@60358
   152
    \<^rule_thm>\<open>times_divide_eq_right\<close> (*?x * (?y / ?z) = ?x * ?y / ?z*),
walther@60358
   153
    \<^rule_thm>\<open>times_divide_eq_left\<close> (*?y / ?z * ?x = ?y * ?x / ?z*),
Walther@60515
   154
    \<^rule_eval>\<open>times\<close> (**)(Calc_Binop.numeric "#mult_")],
Walther@60586
   155
  program = Rule.Empty_Prog};
neuper@37954
   156
neuper@37954
   157
(*..*)
neuper@37954
   158
val srls_diff = 
walther@60358
   159
  Rule_Def.Repeat {id="srls_differentiate..", preconds = [], rew_ord = ("termlessI",termlessI), 
Walther@60586
   160
  asm_rls = Rule_Set.empty, prog_rls = Rule_Set.Empty, calc = [], errpatts = [],
walther@60358
   161
  rules = [
walther@60358
   162
    \<^rule_eval>\<open>Prog_Expr.lhs\<close> (Prog_Expr.eval_lhs "eval_lhs_"),
walther@60358
   163
    \<^rule_eval>\<open>Prog_Expr.rhs\<close> (Prog_Expr.eval_rhs "eval_rhs_"),
walther@60358
   164
    \<^rule_eval>\<open>Diff.primed\<close> (eval_primed "Diff.primed")],
Walther@60586
   165
  program = Rule.Empty_Prog};
wneuper@59472
   166
\<close>
wneuper@59472
   167
ML \<open>
neuper@37954
   168
(*..*)
neuper@37954
   169
val erls_diff = 
walther@60358
   170
  Rule_Set.append_rules "erls_differentiate.." Rule_Set.empty [
walther@60358
   171
    \<^rule_thm>\<open>not_true\<close>,
wenzelm@60297
   172
		\<^rule_thm>\<open>not_false\<close>,
neuper@37954
   173
		
wenzelm@60294
   174
		\<^rule_eval>\<open>Prog_Expr.ident\<close> (Prog_Expr.eval_ident "#ident_"),
wenzelm@60294
   175
		\<^rule_eval>\<open>Prog_Expr.is_atom\<close> (Prog_Expr.eval_is_atom "#is_atom_"),
wenzelm@60294
   176
		\<^rule_eval>\<open>Prog_Expr.occurs_in\<close> (Prog_Expr.eval_occurs_in ""),
walther@60385
   177
  	\<^rule_eval>\<open>Prog_Expr.is_num\<close> (Prog_Expr.eval_is_num "#is_num_")];
neuper@37954
   178
neuper@37954
   179
(*.rules for differentiation, _no_ simplification.*)
neuper@37954
   180
val diff_rules =
walther@60358
   181
   Rule_Def.Repeat {id="diff_rules", preconds = [], rew_ord = ("termlessI",termlessI), 
Walther@60586
   182
	 asm_rls = erls_diff, prog_rls = Rule_Set.Empty, calc = [], errpatts = [],
walther@60358
   183
	 rules = [
walther@60358
   184
      \<^rule_thm>\<open>diff_sum\<close>,
wenzelm@60297
   185
		  \<^rule_thm>\<open>diff_dif\<close>,
wenzelm@60297
   186
		  \<^rule_thm>\<open>diff_prod_const\<close>,
wenzelm@60297
   187
		  \<^rule_thm>\<open>diff_prod\<close>,
wenzelm@60297
   188
		  \<^rule_thm>\<open>diff_quot\<close>,
wenzelm@60297
   189
		  \<^rule_thm>\<open>diff_sin\<close>,
wenzelm@60297
   190
		  \<^rule_thm>\<open>diff_sin_chain\<close>,
wenzelm@60297
   191
		  \<^rule_thm>\<open>diff_cos\<close>,
wenzelm@60297
   192
		  \<^rule_thm>\<open>diff_cos_chain\<close>,
wenzelm@60297
   193
		  \<^rule_thm>\<open>diff_pow\<close>,
wenzelm@60297
   194
		  \<^rule_thm>\<open>diff_pow_chain\<close>,
wenzelm@60297
   195
		  \<^rule_thm>\<open>diff_ln\<close>,
wenzelm@60297
   196
		  \<^rule_thm>\<open>diff_ln_chain\<close>,
wenzelm@60297
   197
		  \<^rule_thm>\<open>diff_exp\<close>,
wenzelm@60297
   198
		  \<^rule_thm>\<open>diff_exp_chain\<close>,
walther@60358
   199
      (*
wenzelm@60297
   200
		  \<^rule_thm>\<open>diff_sqrt\<close>,
wenzelm@60297
   201
		  \<^rule_thm>\<open>diff_sqrt_chain\<close>,
walther@60358
   202
      *)
wenzelm@60297
   203
		  \<^rule_thm>\<open>diff_const\<close>,
walther@60358
   204
		  \<^rule_thm>\<open>diff_var\<close>],
Walther@60586
   205
	 program = Rule.Empty_Prog};
wneuper@59472
   206
\<close>
wneuper@59472
   207
ML \<open>
neuper@37954
   208
(*.normalisation for checking user-input.*)
neuper@37954
   209
val norm_diff = 
walther@59851
   210
  Rule_Def.Repeat
neuper@42458
   211
    {id="norm_diff", preconds = [], rew_ord = ("termlessI",termlessI), 
Walther@60586
   212
     asm_rls = Rule_Set.Empty, prog_rls = Rule_Set.Empty, calc = [], errpatts = [],
wneuper@59416
   213
     rules = [Rule.Rls_ diff_rules, Rule.Rls_ norm_Poly ],
Walther@60586
   214
     program = Rule.Empty_Prog};
wneuper@59472
   215
\<close>
wenzelm@60289
   216
rule_set_knowledge
wenzelm@60286
   217
  erls_diff = \<open>prep_rls' erls_diff\<close> and
wenzelm@60286
   218
  diff_rules = \<open>prep_rls' diff_rules\<close> and
wenzelm@60286
   219
  norm_diff = \<open>prep_rls' norm_diff\<close> and
wenzelm@60286
   220
  diff_conv = \<open>prep_rls' diff_conv\<close> and
wenzelm@60286
   221
  diff_sym_conv = \<open>prep_rls' diff_sym_conv\<close>
s1210629013@55363
   222
wenzelm@60306
   223
wenzelm@60306
   224
(** problems **)
wenzelm@60306
   225
wenzelm@60306
   226
problem pbl_fun : "function" = \<open>Rule_Set.empty\<close>
wenzelm@60306
   227
wenzelm@60306
   228
problem pbl_fun_deriv : "derivative_of/function" =
wenzelm@60306
   229
  \<open>Rule_Set.append_rules "empty" Rule_Set.empty []\<close>
Walther@60449
   230
  Method_Ref: "diff/differentiate_on_R" "diff/after_simplification"
wenzelm@60306
   231
  CAS: "Diff (f_f, v_v)"
wenzelm@60306
   232
  Given: "functionTerm f_f" "differentiateFor v_v"
wenzelm@60306
   233
  Find: "derivative f_f'"
wenzelm@60306
   234
wenzelm@60306
   235
problem pbl_fun_deriv_nam :
wenzelm@60306
   236
  "named/derivative_of/function" (*here "named" is used differently from Integration"*) =
wenzelm@60306
   237
  \<open>Rule_Set.append_rules "empty" Rule_Set.empty []\<close>
Walther@60449
   238
  Method_Ref: "diff/differentiate_equality"
wenzelm@60306
   239
  CAS: "Differentiate (f_f, v_v)"
wenzelm@60306
   240
  Given: "functionEq f_f" "differentiateFor v_v"
wenzelm@60306
   241
  Find: "derivativeEq f_f'"
s1210629013@55380
   242
wneuper@59472
   243
ML \<open>
neuper@37954
   244
(** CAS-commands **)
neuper@37954
   245
neuper@37954
   246
(*.handle cas-input like "Diff (a * x^3 + b, x)".*)
Walther@60567
   247
(* val (t, pairl) = strip_comb (TermC.parse_test @{context} "Diff (a * x^3 + b, x)");
wenzelm@60309
   248
   val [Const (\<^const_name>\<open>Pair\<close>, _) $ t $ bdv] = pairl;
neuper@37954
   249
   *)
wenzelm@60309
   250
fun argl2dtss [Const (\<^const_name>\<open>Pair\<close>, _) $ t $ bdv] =
Walther@60664
   251
    [(Syntax.read_term (Proof_Context.init_global \<^theory>) "functionTerm", [t]),
Walther@60664
   252
     (Syntax.read_term (Proof_Context.init_global \<^theory>) "differentiateFor", [bdv]),
Walther@60664
   253
     (Syntax.read_term (Proof_Context.init_global \<^theory>) "derivative", 
Walther@60664
   254
       [Syntax.read_term (Proof_Context.init_global \<^theory>) "f_f'"])]
walther@59962
   255
  | argl2dtss _ = raise ERROR "Diff.ML: wrong argument for argl2dtss";
wneuper@59472
   256
\<close>
wenzelm@60303
   257
wenzelm@60303
   258
method met_diff : "diff" =
Walther@60586
   259
  \<open>{rew_ord="tless_true",rls'=Atools_erls,calc = [], prog_rls = Rule_Set.empty, where_rls=Rule_Set.empty,
Walther@60587
   260
    errpats = [], rew_rls = norm_diff}\<close>
wneuper@59545
   261
wneuper@59504
   262
partial_function (tailrec) differentiate_on_R :: "real \<Rightarrow> real \<Rightarrow> real"
wneuper@59504
   263
  where
walther@59635
   264
"differentiate_on_R f_f v_v = (
walther@59635
   265
  let
walther@59635
   266
    f_f' = Take (d_d v_v f_f)
walther@59635
   267
  in (
walther@59637
   268
    (Try (Rewrite_Set_Inst [(''bdv'',v_v)] ''diff_conv'')) #> (
walther@59635
   269
    Repeat (
walther@59635
   270
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_sum'')) Or
walther@59635
   271
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_prod_const'')) Or
walther@59635
   272
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_prod'')) Or
walther@59635
   273
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_quot'')) Or
walther@59635
   274
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_sin'')) Or
walther@59635
   275
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_sin_chain'')) Or
walther@59635
   276
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_cos'')) Or
walther@59635
   277
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_cos_chain'')) Or
walther@59635
   278
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_pow'')) Or
walther@59635
   279
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_pow_chain'')) Or
walther@59635
   280
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_ln'')) Or
walther@59635
   281
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_ln_chain'')) Or
walther@59635
   282
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_exp'')) Or
walther@59635
   283
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_exp_chain'')) Or
walther@59635
   284
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_const'')) Or
walther@59635
   285
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_var'')) Or
walther@59637
   286
      (Repeat (Rewrite_Set ''make_polynomial'')))) #> (
walther@59635
   287
    Try (Rewrite_Set_Inst [(''bdv'',v_v)] ''diff_sym_conv''))
walther@59635
   288
    ) f_f')"
wenzelm@60303
   289
wenzelm@60303
   290
method met_diff_onR : "diff/differentiate_on_R" =
Walther@60586
   291
  \<open>{rew_ord="tless_true", rls' = erls_diff, calc = [], prog_rls = Rule_Set.empty, where_rls=Rule_Set.empty,
Walther@60587
   292
    errpats = [], rew_rls = norm_diff}\<close>
wenzelm@60303
   293
  Program: differentiate_on_R.simps
wenzelm@60303
   294
  Given: "functionTerm f_f" "differentiateFor v_v"
wenzelm@60303
   295
  Find: "derivative f_f'"
wneuper@59545
   296
wneuper@59504
   297
partial_function (tailrec) differentiateX :: "real \<Rightarrow> real \<Rightarrow> real"
wneuper@59504
   298
  where
walther@59635
   299
"differentiateX f_f v_v = (
walther@59635
   300
  let
walther@59635
   301
    f_f' = Take (d_d v_v f_f)
walther@59635
   302
  in (
walther@59635
   303
    Repeat (
walther@59635
   304
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_sum'')) Or
walther@59635
   305
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_prod_const'' )) Or
walther@59635
   306
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_prod'')) Or
walther@59635
   307
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_quot'')) Or
walther@59635
   308
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_sin'')) Or
walther@59635
   309
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_sin_chain'')) Or
walther@59635
   310
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_cos'')) Or
walther@59635
   311
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_cos_chain'')) Or
walther@59635
   312
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_pow'')) Or
walther@59635
   313
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_pow_chain'')) Or
walther@59635
   314
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_ln'')) Or
walther@59635
   315
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_ln_chain'')) Or
walther@59635
   316
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_exp'')) Or
walther@59635
   317
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_exp_chain'')) Or
walther@59635
   318
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_const'')) Or
walther@59635
   319
      (Repeat (Rewrite_Inst [(''bdv'',v_v)] ''diff_var'')) Or
walther@59635
   320
      (Repeat (Rewrite_Set ''make_polynomial'')))
walther@59635
   321
    ) f_f')"
wenzelm@60303
   322
wenzelm@60303
   323
method met_diff_simpl : "diff/diff_simpl" =
Walther@60586
   324
  \<open>{rew_ord="tless_true", rls' = erls_diff, calc = [], prog_rls = Rule_Set.empty, where_rls=Rule_Set.empty,
Walther@60587
   325
    errpats = [], rew_rls = norm_diff}\<close>
wenzelm@60303
   326
  Program: differentiateX.simps
wenzelm@60303
   327
  Given: "functionTerm f_f" " differentiateFor v_v"
wenzelm@60303
   328
  Find: "derivative f_f'"
wneuper@59545
   329
wneuper@59504
   330
partial_function (tailrec) differentiate_equality :: "bool \<Rightarrow> real \<Rightarrow> bool"
wneuper@59504
   331
  where
walther@59635
   332
"differentiate_equality f_f v_v = (
walther@59635
   333
  let
walther@59635
   334
    f_f' = Take ((primed (lhs f_f)) = d_d v_v (rhs f_f))
walther@59635
   335
  in (
walther@59637
   336
    (Try (Rewrite_Set_Inst [(''bdv'',v_v)] ''diff_conv'' )) #> (
walther@59635
   337
    Repeat (
walther@59635
   338
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_sum'')) Or
walther@59635
   339
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_dif''        )) Or
walther@59635
   340
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_prod_const'')) Or
walther@59635
   341
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_prod'')) Or
walther@59635
   342
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_quot'')) Or
walther@59635
   343
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_sin'')) Or
walther@59635
   344
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_sin_chain'')) Or
walther@59635
   345
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_cos'')) Or
walther@59635
   346
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_cos_chain'')) Or
walther@59635
   347
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_pow'')) Or
walther@59635
   348
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_pow_chain'')) Or
walther@59635
   349
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_ln'')) Or
walther@59635
   350
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_ln_chain'')) Or
walther@59635
   351
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_exp'')) Or
walther@59635
   352
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_exp_chain'')) Or
walther@59635
   353
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_const'')) Or
walther@59635
   354
      (Repeat (Rewrite_Inst [(''bdv'', v_v)] ''diff_var'')) Or
walther@59637
   355
      (Repeat (Rewrite_Set ''make_polynomial'')))) #> (
walther@59635
   356
    Try (Rewrite_Set_Inst [(''bdv'', v_v)] ''diff_sym_conv'' ))
walther@59635
   357
    ) f_f')"
wenzelm@60303
   358
wenzelm@60303
   359
method met_diff_equ : "diff/differentiate_equality" =
Walther@60586
   360
  \<open>{rew_ord="tless_true", rls' = erls_diff, calc = [], prog_rls = srls_diff, where_rls=Rule_Set.empty,
Walther@60587
   361
    errpats = [], rew_rls = norm_diff}\<close>
wenzelm@60303
   362
  Program: differentiate_equality.simps
wenzelm@60303
   363
  Given: "functionEq f_f" "differentiateFor v_v"
wenzelm@60303
   364
  Find: "derivativeEq f_f'"
wneuper@59545
   365
wneuper@59504
   366
partial_function (tailrec) simplify_derivative :: "real \<Rightarrow> real \<Rightarrow> real"
wneuper@59504
   367
  where
walther@59635
   368
"simplify_derivative term bound_variable = (
walther@59635
   369
  let
walther@59634
   370
   term' = Take (d_d bound_variable term)
walther@59635
   371
  in (
walther@59637
   372
    (Try (Rewrite_Set ''norm_Rational'')) #>
walther@59637
   373
    (Try (Rewrite_Set_Inst [(''bdv'', bound_variable)] ''diff_conv'')) #>
walther@59637
   374
    (Try (Rewrite_Set_Inst [(''bdv'', bound_variable)] ''norm_diff'')) #>
walther@59637
   375
    (Try (Rewrite_Set_Inst [(''bdv'', bound_variable)] ''diff_sym_conv'')) #>
walther@59635
   376
    (Try (Rewrite_Set ''norm_Rational''))
walther@59635
   377
    ) term')"
walther@59634
   378
wenzelm@60303
   379
method met_diff_after_simp : "diff/after_simplification" =
Walther@60586
   380
  \<open>{rew_ord="tless_true", rls' = Rule_Set.empty, calc = [], prog_rls = Rule_Set.empty, where_rls=Rule_Set.empty,
Walther@60587
   381
    errpats = [], rew_rls = norm_Rational}\<close>
wenzelm@60303
   382
  Program: simplify_derivative.simps
wenzelm@60303
   383
  Given: "functionTerm term" "differentiateFor bound_variable"
wenzelm@60303
   384
  Find: "derivative term'"
wenzelm@60303
   385
wenzelm@60314
   386
cas Diff = \<open>argl2dtss\<close>
Walther@60449
   387
  Problem_Ref: "derivative_of/function"
wenzelm@60314
   388
wneuper@59472
   389
ML \<open>
neuper@37954
   390
neuper@37954
   391
(*.handle cas-input like "Differentiate (A = s * (a - s), s)".*)
Walther@60567
   392
(* val (t, pairl) = strip_comb (TermC.parse_test @{context} "Differentiate (A = s * (a - s), s)");
wenzelm@60309
   393
   val [Const (\<^const_name>\<open>Pair\<close>, _) $ t $ bdv] = pairl;
neuper@37954
   394
   *)
wenzelm@60309
   395
fun argl2dtss [Const (\<^const_name>\<open>Pair\<close>, _) $ t $ bdv] =
Walther@60664
   396
    [(Syntax.read_term (Proof_Context.init_global \<^theory>) "functionEq", [t]),
Walther@60664
   397
     (Syntax.read_term (Proof_Context.init_global \<^theory>) "differentiateFor", [bdv]),
Walther@60664
   398
     (Syntax.read_term (Proof_Context.init_global \<^theory>) "derivativeEq", 
Walther@60664
   399
       [Syntax.read_term (Proof_Context.init_global \<^theory>) "f_f'::bool"])]
walther@59962
   400
  | argl2dtss _ = raise ERROR "Diff.ML: wrong argument for argl2dtss";
wneuper@59472
   401
\<close>
wenzelm@60314
   402
cas Differentiate = \<open>argl2dtss\<close>
Walther@60449
   403
  Problem_Ref: "named/derivative_of/function"
Walther@60631
   404
Walther@60631
   405
Walther@60633
   406
section \<open>Error_Patterns\<close>
Walther@60633
   407
Walther@60633
   408
declare [[check_unique = false]]
Walther@60633
   409
setup \<open>Know_Store.add_mets @{context}
Walther@60633
   410
  [Pbl_Met_Hierarchy.add_errpats @{theory} ["diff", "differentiate_on_R"]
Walther@60633
   411
    [("chain-rule-diff-both",
Walther@60662
   412
      [ParseC.patt_opt @{theory} "d_d ?bdv (sin ?u) = cos (d_d ?bdv ?u)" |> the,
Walther@60662
   413
       ParseC.patt_opt @{theory} "d_d ?bdv (cos ?u) = - sin (d_d ?bdv ?u)" |> the,
Walther@60662
   414
       ParseC.patt_opt @{theory} "d_d ?bdv (?u \<up> ?n) = ?n * ?u \<up> (?n - 1)" |> the(*,
Walther@60662
   415
       ParseC.patt_opt @{theory} "d_d ?bdv (LogExp.ln ?u) = 1 / ?u" |> the,
Walther@60662
   416
       ParseC.patt_opt @{theory} "d_d ?bdv (LogExp.ln ?u) = 1 / d_d ?bdv ?u" |> the*)],
Walther@60633
   417
      [@{thm diff_sin_chain}, @{thm diff_cos_chain}, @{thm diff_pow_chain}(*, @{thm diff_ln_chain},
Walther@60633
   418
        @{thm  diff_exp_chain}*)])]
Walther@60633
   419
  ]\<close>
Walther@60633
   420
declare [[check_unique = true]]
Walther@60633
   421
Walther@60631
   422
(*WN230105 ? do fill_ins really work wrt. substitutions ?*)
Walther@60631
   423
setup \<open>Error_Pattern.store_fill_ins
Walther@60631
   424
  [("diff_sin_chain",
Walther@60631
   425
    ([("fill-d_d-arg",
Walther@60662
   426
      ParseC.patt_opt @{theory} "d_d ?bdv (sin ?u) = cos ?u * d_d ?bdv _" |> the, "chain-rule-diff-both"),
Walther@60631
   427
    ("fill-both-args",
Walther@60662
   428
      ParseC.patt_opt @{theory} "d_d ?bdv (sin _) = cos ?u * d_d ?bdv _" |> the, "chain-rule-diff-both"),
Walther@60631
   429
    ("fill-d_d",
Walther@60662
   430
      ParseC.patt_opt @{theory} "d_d ?bdv (sin ?u) = cos ?u * _ ?bdv ?u" |> the, "chain-rule-diff-both"),
Walther@60631
   431
    ("fill-inner-deriv",
Walther@60662
   432
      ParseC.patt_opt @{theory} "d_d ?bdv (sin ?u) = cos ?u * _" |> the, "chain-rule-diff-both"),
Walther@60631
   433
    ("fill-all",
Walther@60662
   434
      ParseC.patt_opt @{theory} "d_d ?bdv (sin ?u) = _" |> the, "chain-rule-diff-both")])),
Walther@60631
   435
  ("diff_cos_chain",
Walther@60631
   436
    ([("fill-d_d-arg",
Walther@60662
   437
      ParseC.patt_opt @{theory} "d_d ?bdv (cos ?u) = cos ?u * d_d ?bdv _" |> the, "chain-rule-diff-both"),
Walther@60631
   438
    ("fill-both-args",
Walther@60662
   439
      ParseC.patt_opt @{theory} "d_d ?bdv (cos _) = cos ?u * d_d ?bdv _" |> the, "chain-rule-diff-both"),
Walther@60631
   440
    ("fill-d_d",
Walther@60662
   441
      ParseC.patt_opt @{theory} "d_d ?bdv (cos ?u) = cos ?u * _ ?bdv ?u" |> the, "chain-rule-diff-both"),
Walther@60631
   442
    ("fill-inner-deriv",
Walther@60662
   443
      ParseC.patt_opt @{theory} "d_d ?bdv (cos ?u) = cos ?u * _" |> the, "chain-rule-diff-both"),
Walther@60631
   444
    ("fill-all",
Walther@60662
   445
      ParseC.patt_opt @{theory} "d_d ?bdv (cos ?u) = _" |> the, "chain-rule-diff-both")])),
Walther@60631
   446
  ("diff_pow_chain",
Walther@60631
   447
    ([("fill-d_d-arg",
Walther@60662
   448
      ParseC.patt_opt @{theory} "d_d ?bdv (?u \<up> ?n) = _" |> the, "chain-rule-diff-both")]))
Walther@60631
   449
  ]
Walther@60631
   450
\<close>
Walther@60631
   451
(** )
Walther@60631
   452
ML \<open>
Walther@60631
   453
    val fill_ins = get_fill_ins @{theory Diff} "chain-rule-diff-both"
Walther@60631
   454
ERROR: (*Unfinished theory "Diff"\<^here>*)
Walther@60631
   455
+ see success at end of Isac_Knowledge.thy 
Walther@60631
   456
\<close>
Walther@60631
   457
( **)
Walther@60631
   458
Walther@60631
   459
Walther@60631
   460
(* still ununsed; planned for stepToErrorpattern: this is just a reminder... 
Walther@60631
   461
Walther@60631
   462
insert_errpatIDs @{theory} ["IsacKnowledge", "Diff", "Rulesets", "norm_diff"]
Walther@60631
   463
  (["chain-rule-diff-both", "cancel"]: errpatID list);
Walther@60631
   464
[[[ERROR *** app_py: not found: ["IsacKnowledge", "Diff", "Rulesets", "norm_diff"]
Walther@60631
   465
  since Know_Store.set_ref_last_thy has been shifted below;
Walther@60631
   466
  this ERROR will vanish during re-engineering towards Know_Store.]]]
Walther@60631
   467
Walther@60631
   468
   ...and all other related rls by hand;
Walther@60631
   469
   TODO: lift errpattIDs from theorems to respective rls AUTOMATICALLY
Walther@60631
   470
*)
Walther@60631
   471
wenzelm@60314
   472
ML \<open>
walther@60278
   473
\<close> ML \<open>
walther@60278
   474
\<close>
neuper@37906
   475
end