src/Tools/isac/Knowledge/GCD_Poly.thy
changeset 48868 1676be88dbcb
parent 48867 4d4254cc6e34
child 48869 90847afab532
equal deleted inserted replaced
48867:4d4254cc6e34 48868:1676be88dbcb
   380                p1 is primitive  \<and>  p2 is primitive
   380                p1 is primitive  \<and>  p2 is primitive
   381        yields  gcd | p1  \<and>  gcd | p2  \<and>  gcd is primitive
   381        yields  gcd | p1  \<and>  gcd | p2  \<and>  gcd is primitive
   382 
   382 
   383     argumentns "a b d M p" named according to [1] p.93 *)
   383     argumentns "a b d M p" named according to [1] p.93 *)
   384   fun HENSEL_lifting_up a b d M p = 
   384   fun HENSEL_lifting_up a b d M p = 
   385     let 
   385     let
       
   386 val _ = writeln ("HENSEL-univ d = " ^ PolyML.makestring d ^ 
       
   387 ", M = " ^ PolyML.makestring (2 * d * LANDAU_MIGNOTTE_bound a b) ^ 
       
   388 ", p = " ^ PolyML.makestring p)
   386       val p = p next_prime_not_dvd d 
   389       val p = p next_prime_not_dvd d 
   387       val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p (*see above*)
   390       val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p (*see above*)
   388     in
   391     in
   389       if deg_up g_p = 0 then [1] else
   392       if deg_up g_p = 0 then [1] else
   390         let 
   393         let 
   391           val g = primitive_up (try_new_prime_up a b d M p g_p p)
   394           val g = primitive_up (try_new_prime_up a b d M p g_p p)
   392         in
   395         in
   393           if (g %|% a) andalso (g %|% b) then 
   396           if (g %|% a) andalso (g %|% b) then 
   394 (writeln ("HENSEL-univ M = " ^ PolyML.makestring M ^ ", p = " ^ PolyML.makestring p ^ 
   397 (writeln ("HENSEL-univ -------------------> " ^ PolyML.makestring g);
   395 ": " ^ PolyML.makestring g ^ " %|% " ^ PolyML.makestring a  ^ 
       
   396 " /\\ " ^ PolyML.makestring g ^ " %|% " ^ PolyML.makestring b);
       
   397                                               g:unipoly 
   398                                               g:unipoly 
   398 )
   399 )
   399                                                         else HENSEL_lifting_up a b d M p
   400                                                         else HENSEL_lifting_up a b d M p
   400         end
   401         end
   401     end
   402     end
   491   fun max_deg_var (p: poly) var = (maxs o (map ((nth_swapped var) o snd))) p;
   492   fun max_deg_var (p: poly) var = (maxs o (map ((nth_swapped var) o snd))) p;
   492 *}
   493 *}
   493 
   494 
   494 subsection {* evaluation, translation uni--multivariate, etc *}
   495 subsection {* evaluation, translation uni--multivariate, etc *}
   495 ML {*
   496 ML {*
   496   (* evaluate a polynomial in a certain variable and remove this from the exp-list *)         
   497   (* evaluate a polynomial in a certain variable and remove this var from the exp-list *)         
   497   fun eval (p: poly) var value = 
   498   fun eval (p: poly) var value = (* TODO use "map" instead*)
   498     let 
   499     let 
   499       fun eval [] _ _ new = order new 
   500       fun eval [] _ _ new = order new 
   500         | eval ((c, es)::ps) var value new =
   501         | eval ((c, es)::ps) var value new =
   501           eval ps var value (new @ [((Integer.pow  (nth es var) value) * c, nth_drop var es)]);
   502           eval ps var value (new @ [((Integer.pow  (nth es var) value) * c, nth_drop var es)]);
   502     in eval p var value [] end
   503     in eval p var value [] end
   677       in (order p', new_vals, steps) end 
   678       in (order p', new_vals, steps) end 
   678 *}
   679 *}
   679 
   680 
   680 subsection {* gcd_poly algorithm, code for [1] p.95 *}
   681 subsection {* gcd_poly algorithm, code for [1] p.95 *}
   681 ML {*
   682 ML {*
   682   (* naming of n, M, m, r, ...  follows Winkler p. 95 *)
   683   (* naming of n, M, m, r, ...  follows Winkler p. 95 
       
   684     n: amount of variables 
       
   685     r: *)
   683   fun gcd_poly' (a as (_, es1)::_ : poly) (b as (_, es2)::_ : poly) n r =
   686   fun gcd_poly' (a as (_, es1)::_ : poly) (b as (_, es2)::_ : poly) n r =
   684     if lex_ord (lmonom b) (lmonom a) then gcd_poly' b a n r else
   687     if lex_ord (lmonom b) (lmonom a) then gcd_poly' b a n r else
   685       if n - 1 = 0 
   688       if n > 1
   686       then
   689       then
       
   690         let val M = 1 + Int.min (max_deg_var a (length es1 - 2), max_deg_var b (length es2 - 2)); 
       
   691         in try_new_r a b n M r [] [] end
       
   692       else 
   687         let val (a', b') = (multi_to_uni a, multi_to_uni b)
   693         let val (a', b') = (multi_to_uni a, multi_to_uni b)
   688         in
   694         in
   689           (* a b are made primitive and this is compensated by multiplying with gcd of divisors *)
   695           (* a b are made primitive and this is compensated by multiplying with gcd of divisors *)
   690           uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* 
   696           uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* 
   691                         (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b'))))
   697                         (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b'))))
   692         end
   698         end
   693       else 
       
   694         let val M = 1 + Int.min (max_deg_var a (length es1 - 2), max_deg_var b (length es2 - 2)); 
       
   695         in try_new_r a b n M r [] [] end
       
   696 
   699 
   697   (* fn: poly -> poly -> int -> 
   700   (* fn: poly -> poly -> int -> 
   698                       int -> int -> int list -> poly list -> poly*)
   701                       int -> int -> int list -> poly list -> poly*)
   699   and try_new_r a b n M r r_list steps = 
   702   and try_new_r a b n M r r_list steps = 
   700      let 
   703      let 
   710                                                                          end
   713                                                                          end
   711   (* fn: poly -> poly -> int -> 
   714   (* fn: poly -> poly -> int -> 
   712                            int -> int -> int -> int list -> poly list -> 
   715                            int -> int -> int -> int list -> poly list -> 
   713                            |                  poly -> poly -> int list -> poly*)
   716                            |                  poly -> poly -> int list -> poly*)
   714   and HENSEL_lifting a b n M m r r_list steps g g_n mult =
   717   and HENSEL_lifting a b n M m r r_list steps g g_n mult =
       
   718 ((*begin function body*)
       
   719 writeln ("HENSEL-poly n = " ^ PolyML.makestring n ^ 
       
   720 ", M = " ^ PolyML.makestring M ^ ", m = " ^ PolyML.makestring m ^ 
       
   721 ", r = " ^ PolyML.makestring r ^ ", r_list = " ^ PolyML.makestring r_list^ 
       
   722 ", steps = " ^ PolyML.makestring steps ^ ", g = " ^ PolyML.makestring g ^ 
       
   723 ", g_n = " ^ PolyML.makestring g_n ^ ", mult = " ^ PolyML.makestring mult);
   715     if m > M then if g_n %%|%% a andalso g_n %%|%% b then
   724     if m > M then if g_n %%|%% a andalso g_n %%|%% b then
   716 (writeln ("HENSEL-poly M = " ^ PolyML.makestring M ^ "HENSEL-poly M = " ^ PolyML.makestring M ^ 
   725 (writeln ("HENSEL-poly ------------------------------> " ^ PolyML.makestring g_n);
   717 ": " ^ PolyML.makestring g_n ^ " %%|%% " ^ PolyML.makestring a ^ 
       
   718 " /\\ " ^ PolyML.makestring g_n ^ " %%|%% " ^ PolyML.makestring b);
       
   719                                                           g_n
   726                                                           g_n
   720 ) 
   727 ) 
   721                                                               else
   728                                                               else
   722       try_new_r a b n M r r_list steps 
   729       try_new_r a b n M r r_list steps 
   723     else
   730     else
   748             end
   755             end
   749           else (* \<not> lex_ord (lmonom g) (lmonom g_r) *)
   756           else (* \<not> lex_ord (lmonom g) (lmonom g_r) *)
   750 (writeln ("recurs.call 4 HENSEL-poly"); 
   757 (writeln ("recurs.call 4 HENSEL-poly"); 
   751                HENSEL_lifting a b n M (m + 1) r r_list steps g  g_n mult
   758                HENSEL_lifting a b n M (m + 1) r r_list steps g  g_n mult
   752 )
   759 )
   753       end     
   760       end
       
   761 )(*end function body*)     
   754 
   762 
   755   (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly
   763   (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly
   756      gcd_poly a b = ((a', b'), c)
   764      gcd_poly a b = ((a', b'), c)
   757      assumes a \<noteq> [] \<and> b \<noteq> [] \<and> 
   765      assumes a \<noteq> [] \<and> b \<noteq> [] \<and> 
   758      yields a = a' *\<^isub>p c  \<and>  b = b' *\<^isub>p c \<and> 
   766      yields a = a' *\<^isub>p c  \<and>  b = b' *\<^isub>p c \<and>