src/Tools/isac/Knowledge/GCD_Poly_ML.thy
changeset 52101 c3f399ce32af
parent 52099 2a95fc276d0a
child 52104 83166e7c7e52
equal deleted inserted replaced
52100:0831a4a6ec8a 52101:c3f399ce32af
   372               val P = P * p
   372               val P = P * p
   373               val g = centr_up ((chinese_remainder_up (P, p) (g, g_p)) mod_up P) P
   373               val g = centr_up ((chinese_remainder_up (P, p) (g, g_p)) mod_up P) P
   374             in try_new_prime_up a b d M P g p end
   374             in try_new_prime_up a b d M P g p end
   375       end
   375       end
   376     
   376     
   377   (* HENSEL_lifting_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> unipoly
   377   (* iterate_CHINESE_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> unipoly
   378      HENSEL_lifting_up p1 p2 d M p = gcd
   378      iterate_CHINESE_up p1 p2 d M p = gcd
   379        assumes d = gcd (lcoeff_up p1, lcoeff_up p2) \<and> 
   379        assumes d = gcd (lcoeff_up p1, lcoeff_up p2) \<and> 
   380                M = LANDAU_MIGNOTTE_bound \<and> p = prime  \<and>  p ~| d  \<and>
   380                M = LANDAU_MIGNOTTE_bound \<and> p = prime  \<and>  p ~| d  \<and>
   381                p1 is primitive  \<and>  p2 is primitive
   381                p1 is primitive  \<and>  p2 is primitive
   382        yields  gcd | p1  \<and>  gcd | p2  \<and>  gcd is primitive
   382        yields  gcd | p1  \<and>  gcd | p2  \<and>  gcd is primitive
   383 
   383 
   384     argumentns "a b d M p" named according to [1] p.93 *)
   384     argumentns "a b d M p" named according to [1] p.93 *)
   385   fun HENSEL_lifting_up a b d M p =
   385   fun iterate_CHINESE_up a b d M p =
   386     let
   386     let
   387       val p = p next_prime_not_dvd d 
   387       val p = p next_prime_not_dvd d 
   388       val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p 
   388       val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p 
   389         (*.. nesting of functions see above*)
   389         (*.. nesting of functions see above*)
   390     in
   390     in
   391       if deg_up g_p = 0 then [1] else
   391       if deg_up g_p = 0 then [1] else
   392         let 
   392         let 
   393           val g = primitive_up (try_new_prime_up a b d M p g_p p)
   393           val g = primitive_up (try_new_prime_up a b d M p g_p p)
   394         in
   394         in
   395           if (g %|% a) andalso (g %|% b) then g:unipoly else HENSEL_lifting_up a b d M p
   395           if (g %|% a) andalso (g %|% b) then g:unipoly else iterate_CHINESE_up a b d M p
   396         end
   396         end
   397     end
   397     end
   398 
   398 
   399   (* gcd_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly
   399   (* gcd_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly
   400      gcd_up a b = c
   400      gcd_up a b = c
   403      yields c dvd a \<and> c dvd b \<and> (\<forall>c'. (c' dvd a \<and> c' dvd b) \<longrightarrow> c' \<le> c) *)
   403      yields c dvd a \<and> c dvd b \<and> (\<forall>c'. (c' dvd a \<and> c' dvd b) \<longrightarrow> c' \<le> c) *)
   404   fun gcd_up a b =
   404   fun gcd_up a b =
   405     let val d = abs (Integer.gcd (lcoeff_up a) (lcoeff_up b))
   405     let val d = abs (Integer.gcd (lcoeff_up a) (lcoeff_up b))
   406     in 
   406     in 
   407       if a = b then a else
   407       if a = b then a else
   408         HENSEL_lifting_up a b d (2 * d * LANDAU_MIGNOTTE_bound a b) 1
   408         iterate_CHINESE_up a b d (2 * d * LANDAU_MIGNOTTE_bound a b) 1
   409     end;
   409     end;
   410 *}
   410 *}
   411 
   411 
   412 section {* gcd for multivariate polynomials *}
   412 section {* gcd for multivariate polynomials *}
   413 ML {*
   413 ML {*
   677             (* a b are made primitive and this is compensated by multiplying with gcd of divisors *)
   677             (* a b are made primitive and this is compensated by multiplying with gcd of divisors *)
   678             uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* 
   678             uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* 
   679                           (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b'))))
   679                           (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b'))))
   680           end
   680           end
   681 
   681 
   682   (* fn: poly -> poly -> int -> 
   682   (* try_new_r :: poly -> poly -> int -> int -> int -> int list -> poly list -> poly
   683                       int -> int -> int list -> poly list -> poly
   683      try_new_r    a       b       n      M      r      r_list      steps = 
   684      assumes length a > 1  \<and>  length b > 1
   684      assumes length a > 1  \<and>  length b > 1
   685      yields TODO  
   685      yields TODO
   686   *)
   686   *)
   687   and try_new_r a b n M r r_list steps = 
   687   and try_new_r a b n M r r_list steps = 
   688      let 
   688      let 
   689         val r = find_new_r a b r;
   689         val r = find_new_r a b r;
   690         val r_list = r_list @ [r];
   690         val r_list = r_list @ [r];
   691         val g_r = gcd_poly' (order (eval a (n - 2) r)) 
   691         val g_r = gcd_poly' (order (eval a (n - 2) r)) 
   692                             (order (eval b (n - 2) r)) (n - 1) 0
   692                             (order (eval b (n - 2) r)) (n - 1) 0
   693         val steps = steps @ [g_r];
   693         val steps = steps @ [g_r];
   694       in HENSEL_lifting a b n M 1 r r_list steps g_r ( zero_poly n ) [1] end
   694       in iterate_CHINESE a b n M 1 r r_list steps g_r (zero_poly n) [1] end
   695   (* fn: poly -> poly -> int -> 
   695 
   696                            int -> int -> int -> int list -> poly list -> 
   696   (* iterate_CHINESE :: poly -> poly -> int -> int -> int -> int -> int list -> 
   697                            |                  poly -> poly -> int list -> poly
   697                         |    poly list -> poly -> poly -> int list -> poly
       
   698      iterate_CHINESE    a    |  b       n      M      m      r      r_list 
       
   699                              steps        g       g_n     mult =
   698      assumes length a > 1  \<and>  length b > 1
   700      assumes length a > 1  \<and>  length b > 1
   699      yields TODO  
   701      yields TODO
   700   *)
   702   *)
   701   and HENSEL_lifting a b n M m r r_list steps g g_n mult =
   703   and iterate_CHINESE a b n M m r r_list steps g g_n mult =
   702     if m > M then if g_n %%|%% a andalso g_n %%|%% b then g_n else
   704     if m > M then if g_n %%|%% a andalso g_n %%|%% b then g_n else
   703       try_new_r a b n M r r_list steps 
   705       try_new_r a b n M r r_list steps
   704     else
   706     else
   705       let 
   707       let 
   706         val r = find_new_r a b r; 
   708         val r = find_new_r a b r; 
   707         val r_list = r_list @ [r];
   709         val r_list = r_list @ [r];
   708         val g_r = gcd_poly' (order (eval a (n - 2) r)) 
   710         val g_r = gcd_poly' (order (eval a (n - 2) r)) 
   709                             (order (eval b (n - 2) r)) (n - 1) 0
   711                             (order (eval b (n - 2) r)) (n - 1) 0
   710       in  
   712       in  
   711         if lex_ord (lmonom g) (lmonom g_r)
   713         if lex_ord (lmonom g) (lmonom g_r)
   712         then HENSEL_lifting a b n M 1 r r_list steps g g_n mult
   714         then iterate_CHINESE a b n M 1 r r_list steps g g_n mult
   713         else if (lexp g) = (lexp g_r) 
   715         else if lexp g = lexp g_r
   714           then
   716           then
   715             let val (g_n, new, steps) = NEWTON r_list [g, g_r] steps mult g_n (n - 2)
   717             let val (g_n, new, steps) = NEWTON r_list [g, g_r] steps mult g_n (n - 2)
   716             in 
   718             in 
   717               if (nth steps (length steps - 1)) = (zero_poly (n - 1))
   719               if nth steps (length steps - 1) = zero_poly (n - 1)
   718               then HENSEL_lifting a b n M (M + 1) r r_list steps g_r g_n new
   720               then iterate_CHINESE a b n M (M + 1) r r_list steps g_r g_n new
   719               else HENSEL_lifting a b n M (m + 1) r r_list steps g_r g_n new
   721               else iterate_CHINESE a b n M (m + 1) r r_list steps g_r g_n new
   720             end
   722             end
   721           else (* \<not> lex_ord (lmonom g) (lmonom g_r) *)
   723           else (* \<not> lex_ord (lmonom g) (lmonom g_r) *)
   722             HENSEL_lifting a b n M (m + 1) r r_list steps g  g_n mult
   724             iterate_CHINESE a b n M (m + 1) r r_list steps g  g_n mult
   723       end
   725       end
   724 
   726 
   725   fun majority_of_coefficients_is_negative a b c =
   727   fun majority_of_coefficients_is_negative_in a b c =
   726     let val cs = (coeffs a) @ (coeffs b) @ (coeffs c)
   728     let val cs = (coeffs a) @ (coeffs b) @ (coeffs c)
   727     in length (filter (curry op < 0) cs) < length cs div 2 end
   729     in length (filter (curry op < 0) cs) < length cs div 2 end
   728 
   730 
   729   (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly
   731   (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly
   730      gcd_poly a b = ((a', b'), c)
   732      gcd_poly a b = ((a', b'), c)
   734   fun gcd_poly (a as (_, es)::_ : poly) b = 
   736   fun gcd_poly (a as (_, es)::_ : poly) b = 
   735     let val c = gcd_poly' a b (length es) 0
   737     let val c = gcd_poly' a b (length es) 0
   736         val (a': poly, _) = a %%/%% c
   738         val (a': poly, _) = a %%/%% c
   737         val (b': poly, _) = b %%/%% c
   739         val (b': poly, _) = b %%/%% c
   738     in 
   740     in 
   739       if majority_of_coefficients_is_negative a' b' c
   741       if majority_of_coefficients_is_negative_in a' b' c
   740       then ((a' %%* ~1, b' %%* ~1), c %%* ~1) (*makes results look nicer*)
   742       then ((a' %%* ~1, b' %%* ~1), c %%* ~1) (*makes results look nicer*)
   741       else ((a', b'), c)
   743       else ((a', b'), c)
   742     end
   744     end
   743 *}
   745 *}
   744 
   746