src/Tools/isac/Knowledge/Partial_Fractions.thy
author Walther Neuper <neuper@ist.tugraz.at>
Thu, 05 Jan 2012 17:43:48 +0100
changeset 42359 b9d382f20232
parent 42358 6708c37fd3dd
child 42360 2c8de368c64c
permissions -rwxr-xr-x
quick&dirty solution for "drop_questionmarks"

The "ansatz" rules contradict the principle, that the rhs must not contain
variables which do not occur in the lhs: "A", "B", etc introduced in rhs
appear as Var ("?A" etc) in the calculation.

3 ad-hoch solutions were considered:
(1) A_ansatz, B_ansatz, etc are constants defined before the rules
+ logically cleanest
- constants do not work as bound variables in the subsequent equation
(2) put a "Calc (drop_questionsmarks ..." into the ansatz rule set
- drop_questionmarks (?A / (...)..)" would be shown to the user
(3) call "drop_questionmarks" as a script expression
- first "?A" etc appear and then disappear without explicit reason.

The case (3) has been taken as preliminary solution.
jan@42344
     1
(* Partial_Fractions
jan@42344
     2
   author: Jan Rocnik, isac team
jan@42344
     3
   Copyright (c) isac team 2011
jan@42344
     4
   Use is subject to license terms.
jan@42344
     5
jan@42344
     6
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
jan@42344
     7
        10        20        30        40        50        60        70        80         90      100
jan@42344
     8
*)
jan@42344
     9
neuper@42289
    10
theory Partial_Fractions imports Rational begin
neuper@42289
    11
jan@42353
    12
ML {*Context.theory_name thy = "Isac"*}
jan@42353
    13
jan@42353
    14
ML{*
jan@42353
    15
val thy = @{theory};
jan@42353
    16
jan@42353
    17
signature PARTFRAC =
jan@42353
    18
sig
jan@42353
    19
  val ansatz_rls : rls
jan@42353
    20
  val ansatz_rls_ : theory -> term -> (term * term list) option
jan@42353
    21
end
jan@42353
    22
*}
jan@42353
    23
jan@42344
    24
consts
jan@42344
    25
neuper@42359
    26
  factors_from_solution :: "bool list => real"
neuper@42359
    27
  drop_questionmarks    :: "'a => 'a"
jan@42344
    28
neuper@42289
    29
subsection {*get the denominator out of a fraction*}
jan@42344
    30
text {*this functions have been stored in Rationals.thy and can be put into rule sets*}
jan@42344
    31
jan@42345
    32
ML {*
jan@42345
    33
(*("get_denominator", ("Rational.get'_denominator", eval_get_denominator ""))*)
jan@42345
    34
fun eval_get_denominator (thmid:string) _ 
jan@42345
    35
		      (t as (Const("Rings.inverse_class.divide", _) $ num $ denom)) thy = 
jan@42345
    36
    SOME (mk_thmid thmid "" 
jan@42345
    37
            (Print_Mode.setmp [] (Syntax.string_of_term (thy2ctxt thy)) denom) "", 
jan@42345
    38
	          Trueprop $ (mk_equality (t, denom)))
jan@42345
    39
  | eval_get_denominator _ _ _ _ = NONE; 
jan@42345
    40
*}
jan@42345
    41
jan@42345
    42
jan@42344
    43
subsubsection {*get solutions out of list*}
jan@42344
    44
jan@42344
    45
neuper@42289
    46
ML {*
jan@42344
    47
fun mk_minus_1 T = Free("-1", T); (*TODO DELETE WITH numbers_to_string*)
jan@42344
    48
fun flip_sign t = (*TODO improve for use in factors_from_solution: -(-1) etc*)
jan@42344
    49
  let val minus_1 = t |> type_of |> mk_minus_1
jan@42344
    50
  in HOLogic.mk_binop "Groups.times_class.times" (minus_1, t) end;
jan@42344
    51
fun fac_from_sol s =
jan@42344
    52
  let val (lhs, rhs) = HOLogic.dest_eq s
jan@42344
    53
  in HOLogic.mk_binop "Groups.plus_class.plus" (lhs, flip_sign rhs) end;
neuper@42289
    54
*}
jan@42344
    55
jan@42344
    56
ML {*
jan@42344
    57
e_term
jan@42344
    58
*}
jan@42344
    59
jan@42344
    60
ML {*
jan@42344
    61
fun mk_prod prod [] =
jan@42344
    62
      if prod = e_term then error "mk_prod called with []" else prod
jan@42344
    63
  | mk_prod prod (t :: []) =
jan@42344
    64
      if prod = e_term then t else HOLogic.mk_binop "Groups.times_class.times" (prod, t)
jan@42344
    65
  | mk_prod prod (t1 :: t2 :: ts) =
jan@42344
    66
        if prod = e_term 
jan@42344
    67
        then 
jan@42344
    68
           let val p = HOLogic.mk_binop "Groups.times_class.times" (t1, t2)
jan@42344
    69
           in mk_prod p ts end 
jan@42344
    70
        else 
jan@42344
    71
           let val p = HOLogic.mk_binop "Groups.times_class.times" (prod, t1)
jan@42344
    72
           in mk_prod p (t2 :: ts) end 
jan@42344
    73
*}
jan@42344
    74
jan@42344
    75
ML {*
jan@42344
    76
jan@42344
    77
jan@42344
    78
fun factors_from_solution sol = 
jan@42344
    79
  let val ts = HOLogic.dest_list sol
jan@42344
    80
  in mk_prod e_term (map fac_from_sol ts) end;
jan@42344
    81
jan@42344
    82
*}
jan@42344
    83
jan@42344
    84
ML {*
neuper@42359
    85
(*("factors_from_solution", ("Partial_Fractions.factors_from_solution", eval_factors_from_solution ""))*)
jan@42352
    86
fun eval_factors_from_solution (thmid:string) _
jan@42352
    87
     (t as Const ("Partial_Fractions.factors_from_solution", _) $ sol) thy =
jan@42352
    88
       ((let val prod = factors_from_solution sol
jan@42352
    89
         in SOME (mk_thmid thmid ""
jan@42352
    90
           (Print_Mode.setmp [] (Syntax.string_of_term (thy2ctxt thy)) prod) "",
jan@42352
    91
               Trueprop $ (mk_equality (t, prod)))
jan@42352
    92
         end)
jan@42352
    93
       handle _ => NONE)
jan@42352
    94
 | eval_factors_from_solution _ _ _ _ = NONE;
jan@42344
    95
*}
jan@42344
    96
neuper@42359
    97
ML {*
neuper@42359
    98
(*("drop_questionmarks", ("Partial_Fractions.drop_questionmarks", eval_drop_questionmarks ""))*)
neuper@42359
    99
fun eval_drop_questionmarks (thmid:string) _
neuper@42359
   100
     (t as Const ("Partial_Fractions.drop_questionmarks", _) $ tm) thy =
neuper@42359
   101
        if contains_Var tm
neuper@42359
   102
        then
neuper@42359
   103
          let
neuper@42359
   104
            val tm' = var2free tm
neuper@42359
   105
            in SOME (mk_thmid thmid ""
neuper@42359
   106
              (Print_Mode.setmp [] (Syntax.string_of_term (thy2ctxt thy)) tm') "",
neuper@42359
   107
                Trueprop $ (mk_equality (t, tm')))
neuper@42359
   108
            end
neuper@42359
   109
        else NONE
neuper@42359
   110
  | eval_drop_questionmarks _ _ _ _ = NONE;
neuper@42359
   111
neuper@42359
   112
calclist':= overwritel (!calclist',
neuper@42359
   113
  [("drop_questionmarks", ("Partial_Fractions.drop'_questionmarks", eval_drop_questionmarks ""))
neuper@42359
   114
  ]);
neuper@42359
   115
*}
neuper@42359
   116
neuper@42359
   117
neuper@42359
   118
neuper@42359
   119
text {* this definition's scope is all Isac; so no equation etc with "A" would be possible:
jan@42358
   120
consts
jan@42358
   121
  A :: "real"
jan@42358
   122
  B :: "real"
neuper@42359
   123
*}
jan@42358
   124
jan@42353
   125
axiomatization where
jan@42358
   126
  ansatz_2nd_order: "n / (a*b) = A/a + B/b" and
jan@42358
   127
  equival_trans_2nd_order: "( n/(a*b) = A/a + B/b ) = ( n = A*b + B*a )"
jan@42353
   128
jan@42353
   129
jan@42353
   130
ML {*
jan@42353
   131
val ansatz_rls = prep_rls(
jan@42353
   132
  Rls {id = "ansatz_rls", preconds = [], rew_ord = ("dummy_ord",dummy_ord), 
jan@42353
   133
	  erls = Erls, srls = Erls, calc = [],
jan@42353
   134
	  rules = 
jan@42354
   135
	   [Thm ("ansatz_2nd_order",num_str @{thm ansatz_2nd_order})
jan@42353
   136
	   ], 
jan@42353
   137
	 scr = EmptyScr}:rls);
jan@42353
   138
*}
jan@42353
   139
jan@42353
   140
ML {*
jan@42354
   141
val equival_trans = prep_rls(
jan@42354
   142
  Rls {id = "equival_trans", preconds = [], rew_ord = ("dummy_ord",dummy_ord), 
jan@42354
   143
	  erls = Erls, srls = Erls, calc = [],
jan@42354
   144
	  rules = 
jan@42354
   145
	   [Thm ("equival_trans_2nd_order",num_str @{thm equival_trans_2nd_order})
jan@42354
   146
	   ], 
jan@42354
   147
	 scr = EmptyScr}:rls);
jan@42354
   148
*}
jan@42354
   149
jan@42354
   150
jan@42354
   151
text {*store the rule set for math engine*}
jan@42354
   152
jan@42354
   153
ML {*
jan@42353
   154
ruleset' := overwritelthy @{theory} (!ruleset',
jan@42354
   155
  [("ansatz_rls", ansatz_rls),
jan@42354
   156
   ("equival_trans", equival_trans)
jan@42353
   157
   ]);
jan@42353
   158
*}
jan@42344
   159
jan@42344
   160
jan@42344
   161
jan@42295
   162
text {*rule set for partial fractions*}
neuper@42289
   163
ML {*
neuper@42289
   164
val partial_fraction = 
neuper@42289
   165
  Rls {id="partial_fraction", preconds = [], rew_ord = ("termlessI",termlessI), 
neuper@42289
   166
	  erls = Erls, srls = Erls, calc = [],
neuper@42289
   167
	  rules = [
jan@42345
   168
				    Calc ("Rings.inverse_class.divide", eval_get_denominator "#")
neuper@42289
   169
		  ],
neuper@42289
   170
	 scr = EmptyScr};
neuper@42289
   171
*}
jan@42354
   172
jan@42353
   173
neuper@42289
   174
jan@42295
   175
neuper@42289
   176
end