src/Tools/isac/Knowledge/Root.thy
author wneuper <walther.neuper@jku.at>
Mon, 19 Jul 2021 15:34:54 +0200
changeset 60335 7701598a2182
parent 60331 40eb8aa2b0d6
child 60358 8377b6c37640
permissions -rw-r--r--
ALL const_name replaces (others cannot be replaced)
     1 (* theory collecting all knowledge for Root
     2    created by: 
     3          date: 
     4    changed by: rlang
     5    last change by: rlang
     6              date: 02.10.21
     7 *)
     8 
     9 theory Root imports Poly begin
    10 
    11 consts
    12 
    13   (*sqrt   :: "real => real"         Isabelle "NthRoot.sqrt"*)
    14   nroot  :: "[real, real] => real"
    15 
    16 axiomatization where (*.not contained in Isabelle2002,
    17          stated as axioms, TODO: prove as theorems;
    18          theorem-IDs 'xxxI' with ^^^ instead of ^ in 'xxx' in Isabelle2002.*)
    19 
    20   root_plus_minus:         "0 <= b ==> 
    21 			   (a \<up> 2 = b) = ((a = sqrt b) | (a = (-1)*sqrt b))" and
    22   root_false:		  "b < 0 ==> (a \<up> 2 = b) = False" and
    23 
    24  (* for expand_rootbinom *)
    25   real_pp_binom_times:     "(a + b)*(c + d) = a*c + a*d + b*c + b*d" and
    26   real_pm_binom_times:     "(a + b)*(c - d) = a*c - a*d + b*c - b*d" and
    27   real_mp_binom_times:     "(a - b)*(c + d) = a*c + a*d - b*c - b*d" and
    28   real_mm_binom_times:     "(a - b)*(c - d) = a*c - a*d - b*c + b*d" and
    29   real_plus_binom_pow3:    "(a + b) \<up> 3 = a \<up> 3 + 3*a \<up> 2*b + 3*a*b \<up> 2 + b \<up> 3" and
    30   real_minus_binom_pow3:   "(a - b) \<up> 3 = a \<up> 3 - 3*a \<up> 2*b + 3*a*b \<up> 2 - b \<up> 3" and
    31   realpow_mul:             "(a*b) \<up> n = a \<up> n * b \<up> n" and
    32 
    33   real_diff_minus:         "a - b = a + (-1) * b" and
    34   real_plus_binom_times:   "(a + b)*(a + b) = a \<up> 2 + 2*a*b + b \<up> 2" and
    35   real_minus_binom_times:  "(a - b)*(a - b) = a \<up> 2 - 2*a*b + b \<up> 2" and
    36   real_plus_binom_pow2:    "(a + b) \<up> 2 = a \<up> 2 + 2*a*b + b \<up> 2" and
    37   real_minus_binom_pow2:   "(a - b) \<up> 2 = a \<up> 2 - 2*a*b + b \<up> 2" and
    38   real_plus_minus_binom1:  "(a + b)*(a - b) = a \<up> 2 - b \<up> 2" and
    39   real_plus_minus_binom2:  "(a - b)*(a + b) = a \<up> 2 - b \<up> 2" and
    40 
    41   real_root_positive:      "0 <= a ==> (x  \<up>  2 = a) = (x = sqrt a)" and
    42   real_root_negative:      "a <  0 ==> (x  \<up>  2 = a) = False"
    43 
    44 ML \<open>
    45 (*-------------------------functions---------------------*)
    46 (*evaluation square-root over the integers*)
    47 fun eval_sqrt (_ : string) (_ : string) (t as (Const (op0, _) $ arg)) _(*thy*) = 
    48     (case arg of 
    49   	  (Const (\<^const_name>\<open>numeral\<close>, T) $ num) =>
    50         let val ni = HOLogic.dest_numeral num
    51         in
    52     	    if ni < 0 then NONE
    53     	    else
    54     		    let val fact = Eval.squfact ni;
    55     		    in
    56               if fact * fact = ni 
    57     		      then
    58                 SOME ("#sqrt #" ^ string_of_int ni ^ " = #"
    59     			          ^ string_of_int (if ni = 0 then 0 else ni div fact),
    60     			        HOLogic.Trueprop $ TermC.mk_equality (t, TermC.term_of_num T fact))
    61     		      else if fact = 1 then NONE
    62       		    else
    63                 SOME ("#sqrt #" ^ string_of_int ni ^ " = sqrt (#"
    64       		          ^ string_of_int fact ^ " * #" ^ string_of_int fact ^ " * #"
    65       		          ^ string_of_int (ni div (fact * fact)) ^ ")",
    66       		        HOLogic.Trueprop $ TermC.mk_equality 
    67                     (t, (TermC.mk_factroot op0 T fact (ni div (fact*fact)))))
    68     	      end
    69   	    end
    70     | _ => NONE)
    71   | eval_sqrt _ _ _ _ = NONE;
    72 (*val (thmid, op_, t as Const(op0,t0) $ arg) = ("", "", str2term "sqrt 0");
    73 > eval_sqrt thmid op_ t thy;
    74 > val Free (n1,t1) = arg; 
    75 > val SOME ni = int_of_str n1;
    76 *)
    77 \<close>
    78 calculation SQRT (sqrt) = \<open>eval_sqrt "#sqrt_"\<close>
    79     (*different types for 'sqrt 4' --- 'Calculate SQRT'*)
    80 ML \<open>
    81 local (* Vers. 7.10.99.A *)
    82 
    83 open Term;  (* for type order = EQUAL | LESS | GREATER *)
    84 
    85 fun pr_ord EQUAL = "EQUAL"
    86   | pr_ord LESS  = "LESS"
    87   | pr_ord GREATER = "GREATER";
    88 
    89 fun dest_hd' (Const (a, T)) =                          (* ~ term.ML *)
    90   (case a of \<^const_name>\<open>sqrt\<close>  => ((("|||", 0), T), 0)      (*WN greatest *)
    91 	   | _ => (((a, 0), T), 0))
    92   | dest_hd' (Free (a, T)) = (((a, 0), T), 1)(*TODOO handle this as numeral, too? see EqSystem.thy*)
    93   | dest_hd' (Var v) = (v, 2)
    94   | dest_hd' (Bound i) = ((("", i), dummyT), 3)
    95   | dest_hd' (Abs (_, T, _)) = ((("", 0), T), 4)
    96   | dest_hd' _ = raise ERROR "dest_hd': uncovered case in fun.def.";
    97 fun size_of_term' (Const(str,_) $ t) =
    98     (case str of \<^const_name>\<open>sqrt\<close>  => (1000 + size_of_term' t)
    99                | _ => 1 + size_of_term' t)
   100   | size_of_term' (Abs (_,_,body)) = 1 + size_of_term' body
   101   | size_of_term' (f $ t) = size_of_term' f  +  size_of_term' t
   102   | size_of_term' _ = 1;
   103 fun term_ord' pr thy (Abs (_, T, t), Abs(_, U, u)) =       (* ~ term.ML *)
   104     (case term_ord' pr thy (t, u) of EQUAL => Term_Ord.typ_ord (T, U) 
   105                                    | ord => ord)
   106   | term_ord' pr _(*thy*) (t, u) =
   107     (if pr then 
   108 	 let
   109 	     val (f, ts) = strip_comb t and (g, us) = strip_comb u;
   110 	     val _ = tracing ("t= f@ts= \"" ^ UnparseC.term f ^"\" @ \"[" ^
   111 	                      commas (map UnparseC.term ts) ^ "]\"");
   112 	     val _ = tracing ("u= g@us= \"" ^ UnparseC.term g ^"\" @ \"[" ^
   113 	                      commas (map UnparseC.term us) ^ "]\"");
   114 	     val _ = tracing ("size_of_term(t,u)= (" ^
   115 	                      string_of_int(size_of_term' t) ^", " ^
   116 	                      string_of_int(size_of_term' u) ^")");
   117 	     val _ = tracing ("hd_ord(f,g)      = " ^ (pr_ord o hd_ord) (f,g));
   118 	     val _ = tracing ("terms_ord(ts,us) = " ^
   119 			      (pr_ord o terms_ord str false) (ts,us));
   120 	     val _=tracing("-------");
   121 	 in () end
   122      else ();
   123      case int_ord (size_of_term' t, size_of_term' u) of
   124 	 EQUAL =>
   125 	 let val (f, ts) = strip_comb t and (g, us) = strip_comb u in
   126 	     (case hd_ord (f, g) of EQUAL => (terms_ord str pr) (ts, us) 
   127 	                          | ord => ord)
   128 	 end
   129        | ord => ord)
   130 and hd_ord (f, g) =                                        (* ~ term.ML *)
   131   prod_ord (prod_ord Term_Ord.indexname_ord Term_Ord.typ_ord) int_ord 
   132             (dest_hd' f, dest_hd' g)
   133 and terms_ord _(*str*) pr (ts, us) = 
   134     list_ord (term_ord' pr (ThyC.get_theory "Isac_Knowledge"))(ts, us);
   135 
   136 in
   137 (* associates a+(b+c) => (a+b)+c = a+b+c ... avoiding parentheses 
   138   by (1) size_of_term: less(!) to right, size_of 'sqrt (...)' = 1 
   139      (2) hd_ord: greater to right, 'sqrt' < numerals < variables
   140      (3) terms_ord: recurs. on args, greater to right
   141 *)
   142 
   143 (*args
   144    pr: print trace, WN0509 'sqrt_right true' not used anymore
   145    thy:
   146    subst: no bound variables, only Root.sqrt
   147    tu: the terms to compare (t1, t2) ... *)
   148 fun sqrt_right (pr:bool) thy (_: subst) (ts, us) = 
   149     (term_ord' pr thy(***) (TermC.numerals_to_Free ts, TermC.numerals_to_Free us) = LESS );
   150 end;
   151 
   152 Rewrite_Ord.rew_ord' := overwritel (! Rewrite_Ord.rew_ord',
   153 [("termlessI", termlessI),
   154  ("sqrt_right", sqrt_right false @{theory "Pure"})
   155  ]);
   156 
   157 (*-------------------------rulse-------------------------*)
   158 val Root_crls = 
   159       Rule_Set.append_rules "Root_crls" Atools_erls 
   160        [\<^rule_thm>\<open>real_unari_minus\<close>,
   161         \<^rule_eval>\<open>sqrt\<close> (eval_sqrt "#sqrt_"),
   162         \<^rule_eval>\<open>divide\<close> (Prog_Expr.eval_cancel "#divide_e"),
   163         \<^rule_eval>\<open>powr\<close> (**)(eval_binop "#power_"),
   164         \<^rule_eval>\<open>plus\<close> (**)(eval_binop "#add_"), 
   165         \<^rule_eval>\<open>minus\<close> (**)(eval_binop "#sub_"),
   166         \<^rule_eval>\<open>times\<close> (**)(eval_binop "#mult_"),
   167         \<^rule_eval>\<open>HOL.eq\<close> (Prog_Expr.eval_equal "#equal_") 
   168         ];
   169 
   170 val Root_erls = 
   171       Rule_Set.append_rules "Root_erls" Atools_erls 
   172        [\<^rule_thm>\<open>real_unari_minus\<close>,
   173         \<^rule_eval>\<open>sqrt\<close> (eval_sqrt "#sqrt_"),
   174         \<^rule_eval>\<open>Rings.divide_class.divide\<close> (Prog_Expr.eval_cancel "#divide_e"),
   175         \<^rule_eval>\<open>Transcendental.powr\<close> (**)(eval_binop "#power_"),
   176         \<^rule_eval>\<open>Groups.plus_class.plus\<close> (**)(eval_binop "#add_"), 
   177         \<^rule_eval>\<open>Groups.minus_class.minus\<close> (**)(eval_binop "#sub_"),
   178         \<^rule_eval>\<open>Groups.times_class.times\<close> (**)(eval_binop "#mult_"),
   179         \<^rule_eval>\<open>HOL.eq\<close> (Prog_Expr.eval_equal "#equal_") 
   180         ];
   181 \<close>
   182 rule_set_knowledge Root_erls = Root_erls
   183 ML \<open>
   184 
   185 val make_rooteq = prep_rls'(
   186   Rule_Def.Repeat{id = "make_rooteq", preconds = []:term list, 
   187       rew_ord = ("sqrt_right", sqrt_right false \<^theory>),
   188       erls = Atools_erls, srls = Rule_Set.Empty,
   189       calc = [], errpatts = [],
   190       rules = [\<^rule_thm>\<open>real_diff_minus\<close>,			
   191 	       (*"a - b = a + (-1) * b"*)
   192 
   193 	       \<^rule_thm>\<open>distrib_right\<close>,	
   194 	       (*"(z1.0 + z2.0) * w = z1.0 * w + z2.0 * w"*)
   195 	       \<^rule_thm>\<open>distrib_left\<close>,	
   196 	       (*"w * (z1.0 + z2.0) = w * z1.0 + w * z2.0"*)
   197 	       \<^rule_thm>\<open>left_diff_distrib\<close>,	
   198 	       (*"(z1.0 - z2.0) * w = z1.0 * w - z2.0 * w"*)
   199 	       \<^rule_thm>\<open>right_diff_distrib\<close>,	
   200 	       (*"w * (z1.0 - z2.0) = w * z1.0 - w * z2.0"*)
   201 
   202 	       \<^rule_thm>\<open>mult_1_left\<close>,                         
   203 	       (*"1 * z = z"*)
   204 	       \<^rule_thm>\<open>mult_zero_left\<close>,                         
   205 	       (*"0 * z = 0"*)
   206 	       \<^rule_thm>\<open>add_0_left\<close>,		
   207 	       (*"0 + z = z"*)
   208  
   209 	       \<^rule_thm>\<open>mult.commute\<close>,
   210 		(*AC-rewriting*)
   211 	       \<^rule_thm>\<open>real_mult_left_commute\<close>,
   212          	(**)
   213 	       \<^rule_thm>\<open>mult.assoc\<close>,
   214 	        (**)
   215 	       \<^rule_thm>\<open>add.commute\<close>,
   216 		(**)
   217 	       \<^rule_thm>\<open>add.left_commute\<close>,
   218 	        (**)
   219 	       \<^rule_thm>\<open>add.assoc\<close>,
   220 	        (**)
   221 
   222 	       \<^rule_thm_sym>\<open>realpow_twoI\<close>,
   223 	       (*"r1 * r1 = r1  \<up>  2"*)
   224 	       \<^rule_thm>\<open>realpow_plus_1\<close>,			
   225 	       (*"r * r  \<up>  n = r  \<up>  (n + 1)"*)
   226 	       \<^rule_thm_sym>\<open>real_mult_2\<close>,
   227 	       (*"z1 + z1 = 2 * z1"*)
   228 	       \<^rule_thm>\<open>real_mult_2_assoc\<close>,		
   229 	       (*"z1 + (z1 + k) = 2 * z1 + k"*)
   230 
   231 	       \<^rule_thm>\<open>real_num_collect\<close>, 
   232 	       (*"[| l is_const; m is_const |]==> l * n + m * n = (l + m) * n"*)
   233 	       \<^rule_thm>\<open>real_num_collect_assoc\<close>,	
   234 	       (*"[| l is_const; m is_const |] ==>  
   235                                    l * n + (m * n + k) =  (l + m) * n + k"*)
   236 	       \<^rule_thm>\<open>real_one_collect\<close>,		
   237 	       (*"m is_const ==> n + m * n = (1 + m) * n"*)
   238 	       \<^rule_thm>\<open>real_one_collect_assoc\<close>, 
   239 	       (*"m is_const ==> k + (n + m * n) = k + (1 + m) * n"*)
   240 
   241 	       \<^rule_eval>\<open>plus\<close> (**)(eval_binop "#add_"), 
   242 	       \<^rule_eval>\<open>times\<close> (**)(eval_binop "#mult_"),
   243 	       \<^rule_eval>\<open>powr\<close> (**)(eval_binop "#power_")
   244 	       ],
   245       scr = Rule.Empty_Prog
   246       });      
   247 \<close>
   248 rule_set_knowledge make_rooteq = make_rooteq
   249 ML \<open>
   250 
   251 val prep_rls' = Auto_Prog.prep_rls @{theory};
   252 
   253 val expand_rootbinoms = prep_rls'(
   254   Rule_Def.Repeat{id = "expand_rootbinoms", preconds = [], 
   255       rew_ord = ("termlessI",termlessI),
   256       erls = Atools_erls, srls = Rule_Set.Empty,
   257       calc = [], errpatts = [],
   258       rules = [\<^rule_thm>\<open>real_plus_binom_pow2\<close>,     
   259 	       (*"(a + b)  \<up>  2 = a  \<up>  2 + 2 * a * b + b  \<up>  2"*)
   260 	       \<^rule_thm>\<open>real_plus_binom_times\<close>,    
   261 	       (*"(a + b)*(a + b) = ...*)
   262 	       \<^rule_thm>\<open>real_minus_binom_pow2\<close>,    
   263 		(*"(a - b)  \<up>  2 = a  \<up>  2 - 2 * a * b + b  \<up>  2"*)
   264 	       \<^rule_thm>\<open>real_minus_binom_times\<close>,   
   265 	       (*"(a - b)*(a - b) = ...*)
   266 	       \<^rule_thm>\<open>real_plus_minus_binom1\<close>,   
   267 		(*"(a + b) * (a - b) = a  \<up>  2 - b  \<up>  2"*)
   268 	       \<^rule_thm>\<open>real_plus_minus_binom2\<close>,   
   269 		(*"(a - b) * (a + b) = a  \<up>  2 - b  \<up>  2"*)
   270 	       (*RL 020915*)
   271 	       \<^rule_thm>\<open>real_pp_binom_times\<close>, 
   272 		(*(a + b)*(c + d) = a*c + a*d + b*c + b*d*)
   273                \<^rule_thm>\<open>real_pm_binom_times\<close>, 
   274 		(*(a + b)*(c - d) = a*c - a*d + b*c - b*d*)
   275                \<^rule_thm>\<open>real_mp_binom_times\<close>, 
   276 		(*(a - b)*(c p d) = a*c + a*d - b*c - b*d*)
   277                \<^rule_thm>\<open>real_mm_binom_times\<close>, 
   278 		(*(a - b)*(c p d) = a*c - a*d - b*c + b*d*)
   279 	       \<^rule_thm>\<open>realpow_mul\<close>,                 
   280 		(*(a*b) \<up> n = a \<up> n * b \<up> n*)
   281 
   282 	       \<^rule_thm>\<open>mult_1_left\<close>,         (*"1 * z = z"*)
   283 	       \<^rule_thm>\<open>mult_zero_left\<close>,         (*"0 * z = 0"*)
   284 	       \<^rule_thm>\<open>add_0_left\<close>, 
   285                  (*"0 + z = z"*)
   286 
   287 	       \<^rule_eval>\<open>plus\<close> (**)(eval_binop "#add_"), 
   288 	       \<^rule_eval>\<open>minus\<close> (**)(eval_binop "#sub_"), 
   289 	       \<^rule_eval>\<open>times\<close> (**)(eval_binop "#mult_"),
   290 	       \<^rule_eval>\<open>divide\<close> (Prog_Expr.eval_cancel "#divide_e"),
   291 	       \<^rule_eval>\<open>sqrt\<close> (eval_sqrt "#sqrt_"),
   292 	       \<^rule_eval>\<open>powr\<close> (**)(eval_binop "#power_"),
   293 
   294 	       \<^rule_thm_sym>\<open>realpow_twoI\<close>,
   295 	       (*"r1 * r1 = r1  \<up>  2"*)
   296 	       \<^rule_thm>\<open>realpow_plus_1\<close>,			
   297 	       (*"r * r  \<up>  n = r  \<up>  (n + 1)"*)
   298 	       \<^rule_thm>\<open>real_mult_2_assoc\<close>,		
   299 	       (*"z1 + (z1 + k) = 2 * z1 + k"*)
   300 
   301 	       \<^rule_thm>\<open>real_num_collect\<close>, 
   302 	       (*"[| l is_const; m is_const |] ==>l * n + m * n = (l + m) * n"*)
   303 	       \<^rule_thm>\<open>real_num_collect_assoc\<close>,	
   304 	       (*"[| l is_const; m is_const |] ==>
   305                   l * n + (m * n + k) =  (l + m) * n + k"*)
   306 	       \<^rule_thm>\<open>real_one_collect\<close>,		
   307 	       (*"m is_const ==> n + m * n = (1 + m) * n"*)
   308 	       \<^rule_thm>\<open>real_one_collect_assoc\<close>, 
   309 	       (*"m is_const ==> k + (n + m * n) = k + (1 + m) * n"*)
   310 
   311 	       \<^rule_eval>\<open>plus\<close> (**)(eval_binop "#add_"), 
   312 	       \<^rule_eval>\<open>minus\<close> (**)(eval_binop "#sub_"), 
   313 	       \<^rule_eval>\<open>times\<close> (**)(eval_binop "#mult_"),
   314 	       \<^rule_eval>\<open>divide\<close> (Prog_Expr.eval_cancel "#divide_e"),
   315 	       \<^rule_eval>\<open>sqrt\<close> (eval_sqrt "#sqrt_"),
   316 	       \<^rule_eval>\<open>powr\<close> (**)(eval_binop "#power_")
   317 	       ],
   318       scr = Rule.Empty_Prog
   319        });      
   320 \<close>
   321 rule_set_knowledge expand_rootbinoms = expand_rootbinoms
   322 ML \<open>
   323 \<close> ML \<open>
   324 \<close> ML \<open>
   325 \<close>
   326 end