diff options
Diffstat (limited to 'plugins/nsatz/ideal.ml')
-rw-r--r-- | plugins/nsatz/ideal.ml | 1057 |
1 files changed, 1057 insertions, 0 deletions
diff --git a/plugins/nsatz/ideal.ml b/plugins/nsatz/ideal.ml new file mode 100644 index 00000000..b91f01d1 --- /dev/null +++ b/plugins/nsatz/ideal.ml @@ -0,0 +1,1057 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* Nullstellensatz with Groebner basis computation + +We use a sparse representation for polynomials: +a monomial is an array of exponents (one for each variable) +with its degree in head +a polynomial is a sorted list of (coefficient, monomial) + + *) + +open Utile +open List + +exception NotInIdeal + +module type S = sig + +(* Monomials *) +type mon = int array + +val mult_mon : mon -> mon -> mon +val deg : mon -> int +val compare_mon : mon -> mon -> int +val div_mon : mon -> mon -> mon +val div_mon_test : mon -> mon -> bool +val ppcm_mon : mon -> mon -> mon + +(* Polynomials *) + +type deg = int +type coef +type poly +type polynom + +val repr : poly -> (coef * mon) list +val polconst : coef -> poly +val zeroP : poly +val gen : int -> poly + +val equal : poly -> poly -> bool +val name_var : string list ref +val getvar : string list -> int -> string +val lstringP : poly list -> string +val printP : poly -> unit +val lprintP : poly list -> unit + +val div_pol_coef : poly -> coef -> poly +val plusP : poly -> poly -> poly +val mult_t_pol : coef -> mon -> poly -> poly +val selectdiv : mon -> poly list -> poly +val oppP : poly -> poly +val emultP : coef -> poly -> poly +val multP : poly -> poly -> poly +val puisP : poly -> int -> poly +val contentP : poly -> coef +val contentPlist : poly list -> coef +val pgcdpos : coef -> coef -> coef +val div_pol : poly -> poly -> coef -> coef -> mon -> poly +val reduce2 : poly -> poly list -> coef * poly + +val poldepcontent : coef list ref +val coefpoldep_find : poly -> poly -> poly +val coefpoldep_set : poly -> poly -> poly -> unit +val initcoefpoldep : poly list -> unit +val reduce2_trace : poly -> poly list -> poly list -> poly list * poly +val spol : poly -> poly -> poly +val etrangers : poly -> poly -> bool +val div_ppcm : poly -> poly -> poly -> bool + +val genPcPf : poly -> poly list -> poly list -> poly list +val genOCPf : poly list -> poly list + +val is_homogeneous : poly -> bool + +type certificate = + { coef : coef; power : int; + gb_comb : poly list list; last_comb : poly list } + +val test_dans_ideal : poly -> poly list -> poly list -> + poly list * poly * certificate +val in_ideal : deg -> poly list -> poly -> poly list * poly * certificate + +end + +(*********************************************************************** + Global options +*) +let lexico = ref false +let use_hmon = ref false + +(* division of tail monomials *) + +let reduire_les_queues = false + +(* divide first with new polynomials *) + +let nouveaux_pol_en_tete = false + +(*********************************************************************** + Functor +*) + +module Make (P:Polynom.S) = struct + + type coef = P.t + let coef0 = P.of_num (Num.Int 0) + let coef1 = P.of_num (Num.Int 1) + let coefm1 = P.of_num (Num.Int (-1)) + let string_of_coef c = "["^(P.to_string c)^"]" + +(*********************************************************************** + Monomials + array of integers, first is the degree +*) + +type mon = int array +type deg = int +type poly = (coef * mon) list +type polynom = + {pol : poly ref; + num : int; + sugar : int} + +let nvar m = Array.length m - 1 + +let deg m = m.(0) + +let mult_mon m m' = + let d = nvar m in + let m'' = Array.create (d+1) 0 in + for i=0 to d do + m''.(i)<- (m.(i)+m'.(i)); + done; + m'' + + +let compare_mon m m' = + let d = nvar m in + if !lexico + then ( + (* Comparaison de monomes avec ordre du degre lexicographique = on commence par regarder la 1ere variable*) + let res=ref 0 in + let i=ref 1 in (* 1 si lexico pur 0 si degre*) + while (!res=0) && (!i<=d) do + res:= (compare m.(!i) m'.(!i)); + i:=!i+1; + done; + !res) + else ( + (* degre lexicographique inverse *) + match compare m.(0) m'.(0) with + | 0 -> (* meme degre total *) + let res=ref 0 in + let i=ref d in + while (!res=0) && (!i>=1) do + res:= - (compare m.(!i) m'.(!i)); + i:=!i-1; + done; + !res + | x -> x) + +let div_mon m m' = + let d = nvar m in + let m'' = Array.create (d+1) 0 in + for i=0 to d do + m''.(i)<- (m.(i)-m'.(i)); + done; + m'' + +let div_pol_coef p c = + List.map (fun (a,m) -> (P.divP a c,m)) p + +(* m' divides m *) +let div_mon_test m m' = + let d = nvar m in + let res=ref true in + let i=ref 0 in (*il faut que le degre total soit bien mis sinon, i=ref 1*) + while (!res) && (!i<=d) do + res:= (m.(!i) >= m'.(!i)); + i:=succ !i; + done; + !res + +let set_deg m = + let d = nvar m in + m.(0)<-0; + for i=1 to d do + m.(0)<- m.(i)+m.(0); + done; + m + +(* lcm *) +let ppcm_mon m m' = + let d = nvar m in + let m'' = Array.create (d+1) 0 in + for i=1 to d do + m''.(i)<- (max m.(i) m'.(i)); + done; + set_deg m'' + + + +(********************************************************************** + Polynomials + list of (coefficient, monomial) decreasing order +*) + +let repr p = p + +let equal = + Util.list_for_all2eq + (fun (c1,m1) (c2,m2) -> P.equal c1 c2 && m1=m2) + +let hash p = + let c = map fst p in + let m = map snd p in + fold_left (fun h p -> h * 17 + P.hash p) (Hashtbl.hash m) c + +module Hashpol = Hashtbl.Make( + struct + type t = poly + let equal = equal + let hash = hash + end) + + +(* A pretty printer for polynomials, with Maple-like syntax. *) + +open Format + +let getvar lv i = + try (nth lv i) + with _ -> (fold_left (fun r x -> r^" "^x) "lv= " lv) + ^" i="^(string_of_int i) + +let string_of_pol zeroP hdP tlP coefterm monterm string_of_coef + dimmon string_of_exp lvar p = + + + let rec string_of_mon m coefone = + let s=ref [] in + for i=1 to (dimmon m) do + (match (string_of_exp m i) with + "0" -> () + | "1" -> s:= (!s) @ [(getvar !lvar (i-1))] + | e -> s:= (!s) @ [((getvar !lvar (i-1)) ^ "^" ^ e)]); + done; + (match !s with + [] -> if coefone + then "1" + else "" + | l -> if coefone + then (String.concat "*" l) + else ( "*" ^ + (String.concat "*" l))) + and string_of_term t start = let a = coefterm t and m = monterm t in + match (string_of_coef a) with + "0" -> "" + | "1" ->(match start with + true -> string_of_mon m true + |false -> ( "+ "^ + (string_of_mon m true))) + | "-1" ->( "-" ^" "^(string_of_mon m true)) + | c -> if (String.get c 0)='-' + then ( "- "^ + (String.sub c 1 + ((String.length c)-1))^ + (string_of_mon m false)) + else (match start with + true -> ( c^(string_of_mon m false)) + |false -> ( "+ "^ + c^(string_of_mon m false))) + and stringP p start = + if (zeroP p) + then (if start + then ("0") + else "") + else ((string_of_term (hdP p) start)^ + " "^ + (stringP (tlP p) false)) + in + (stringP p true) + + + +let print_pol zeroP hdP tlP coefterm monterm string_of_coef + dimmon string_of_exp lvar p = + + let rec print_mon m coefone = + let s=ref [] in + for i=1 to (dimmon m) do + (match (string_of_exp m i) with + "0" -> () + | "1" -> s:= (!s) @ [(getvar !lvar (i-1))] + | e -> s:= (!s) @ [((getvar !lvar (i-1)) ^ "^" ^ e)]); + done; + (match !s with + [] -> if coefone + then print_string "1" + else () + | l -> if coefone + then print_string (String.concat "*" l) + else (print_string "*"; + print_string (String.concat "*" l))) + and print_term t start = let a = coefterm t and m = monterm t in + match (string_of_coef a) with + "0" -> () + | "1" ->(match start with + true -> print_mon m true + |false -> (print_string "+ "; + print_mon m true)) + | "-1" ->(print_string "-";print_space();print_mon m true) + | c -> if (String.get c 0)='-' + then (print_string "- "; + print_string (String.sub c 1 + ((String.length c)-1)); + print_mon m false) + else (match start with + true -> (print_string c;print_mon m false) + |false -> (print_string "+ "; + print_string c;print_mon m false)) + and printP p start = + if (zeroP p) + then (if start + then print_string("0") + else ()) + else (print_term (hdP p) start; + if start then open_hovbox 0; + print_space(); + print_cut(); + printP (tlP p) false) + in open_hovbox 3; + printP p true; + print_flush() + + +let name_var= ref [] + +let stringP p = + string_of_pol + (fun p -> match p with [] -> true | _ -> false) + (fun p -> match p with (t::p) -> t |_ -> failwith "print_pol dans dansideal") + (fun p -> match p with (t::p) -> p |_ -> failwith "print_pol dans dansideal") + (fun (a,m) -> a) + (fun (a,m) -> m) + string_of_coef + (fun m -> (Array.length m)-1) + (fun m i -> (string_of_int (m.(i)))) + name_var + p + +let nsP2 = ref max_int + +let stringPcut p = + (*Polynomesrec.nsP1:=20;*) + nsP2:=10; + let res = + if (length p)> !nsP2 + then (stringP [hd p])^" + "^(string_of_int (length p))^" termes" + else stringP p in + (*Polynomesrec.nsP1:= max_int;*) + nsP2:= max_int; + res + +let rec lstringP l = + match l with + [] -> "" + |p::l -> (stringP p)^("\n")^(lstringP l) + +let printP = print_pol + (fun p -> match p with [] -> true | _ -> false) + (fun p -> match p with (t::p) -> t |_ -> failwith "print_pol dans dansideal") + (fun p -> match p with (t::p) -> p |_ -> failwith "print_pol dans dansideal") + (fun (a,m) -> a) + (fun (a,m) -> m) + string_of_coef + (fun m -> (Array.length m)-1) + (fun m i -> (string_of_int (m.(i)))) + name_var + + +let rec lprintP l = + match l with + [] -> () + |p::l -> printP p;print_string "\n"; lprintP l + + +(* Operations *) + +let zeroP = [] + +(* returns a constant polynom ial with d variables *) +let polconst d c = + let m = Array.create (d+1) 0 in + let m = set_deg m in + [(c,m)] + +let plusP p q = + let rec plusP p q = + match p with + [] -> q + |t::p' -> + match q with + [] -> p + |t'::q' -> + match compare_mon (snd t) (snd t') with + 1 -> t::(plusP p' q) + |(-1) -> t'::(plusP p q') + |_ -> let c=P.plusP (fst t) (fst t') in + match P.equal c coef0 with + true -> (plusP p' q') + |false -> (c,(snd t))::(plusP p' q') + in plusP p q + +(* multiplication by (a,monomial) *) +let mult_t_pol a m p = + let rec mult_t_pol p = + match p with + [] -> [] + |(b,m')::p -> ((P.multP a b),(mult_mon m m'))::(mult_t_pol p) + in mult_t_pol p + +let coef_of_int x = P.of_num (Num.Int x) + +(* variable i *) +let gen d i = + let m = Array.create (d+1) 0 in + m.(i) <- 1; + let m = set_deg m in + [((coef_of_int 1),m)] + +let oppP p = + let rec oppP p = + match p with + [] -> [] + |(b,m')::p -> ((P.oppP b),m')::(oppP p) + in oppP p + +(* multiplication by a coefficient *) +let emultP a p = + let rec emultP p = + match p with + [] -> [] + |(b,m')::p -> ((P.multP a b),m')::(emultP p) + in emultP p + +let multP p q = + let rec aux p = + match p with + [] -> [] + |(a,m)::p' -> plusP (mult_t_pol a m q) (aux p') + in aux p + +let puisP p n= + match p with + [] -> [] + |_ -> + let d = nvar (snd (hd p)) in + let rec puisP n = + match n with + 0 -> [coef1, Array.create (d+1) 0] + | 1 -> p + |_ -> multP p (puisP (n-1)) + in puisP n + +let rec contentP p = + match p with + |[] -> coef1 + |[a,m] -> a + |(a,m)::p1 -> + if P.equal a coef1 || P.equal a coefm1 + then a + else P.pgcdP a (contentP p1) + +let contentPlist lp = + match lp with + |[] -> coef1 + |p::l1 -> + fold_left + (fun r q -> + if P.equal r coef1 || P.equal r coefm1 + then r + else P.pgcdP r (contentP q)) + (contentP p) l1 + +(*********************************************************************** + Division of polynomials + *) + +let pgcdpos a b = P.pgcdP a b + +let polynom0 = {pol = ref []; num = 0; sugar = 0} + +let ppol p = !(p.pol) + +let lm p = snd (hd (ppol p)) + +let nallpol = ref 0 + +let allpol = ref (Array.create 1000 polynom0) + +let new_allpol p s = + nallpol := !nallpol + 1; + if !nallpol >= Array.length !allpol + then + allpol := Array.append !allpol (Array.create !nallpol polynom0); + let p = {pol = ref p; num = !nallpol; sugar = s} in + !allpol.(!nallpol)<- p; + p + +(* returns a polynomial of l whose head monomial divides m, else [] *) + +let rec selectdiv m l = + match l with + [] -> polynom0 + |q::r -> let m'= snd (hd (ppol q)) in + match (div_mon_test m m') with + true -> q + |false -> selectdiv m r + +let div_pol p q a b m = +(* info ".";*) + plusP (emultP a p) (mult_t_pol b m q) + +let hmon = Hashtbl.create 1000 + +let use_hmon = ref false + +let find_hmon m = + if !use_hmon + then Hashtbl.find hmon m + else raise Not_found + +let add_hmon m q = + if !use_hmon + then Hashtbl.add hmon m q + else () + +let div_coef a b = P.divP a b + + +(* remainder r of the division of p by polynomials of l, returns (c,r) where c is the coefficient for pseudo-division : c p = sum_i q_i p_i + r *) + +let reduce2 p l = + let l = if nouveaux_pol_en_tete then rev l else l in + let rec reduce p = + match p with + [] -> (coef1,[]) + |t::p' -> + let (a,m)=t in + let q = (try find_hmon m + with Not_found -> + let q = selectdiv m l in + match (ppol q) with + t'::q' -> (add_hmon m q; + q) + |[] -> q) in + match (ppol q) with + [] -> if reduire_les_queues + then + let (c,r)=(reduce p') in + (c,((P.multP a c,m)::r)) + else (coef1,p) + |(b,m')::q' -> + let c=(pgcdpos a b) in + let a'= (div_coef b c) in + let b'=(P.oppP (div_coef a c)) in + let (e,r)=reduce (div_pol p' q' a' b' + (div_mon m m')) in + (P.multP a' e,r) + in let (c,r) = reduce p in + (c,r) + +(* trace of divisions *) + +(* list of initial polynomials *) +let poldep = ref [] +let poldepcontent = ref [] + +(* coefficients of polynomials when written with initial polynomials *) +let coefpoldep = Hashtbl.create 51 + +(* coef of q in p = sum_i c_i*q_i *) +let coefpoldep_find p q = + try (Hashtbl.find coefpoldep (p.num,q.num)) + with _ -> [] + +let coefpoldep_remove p q = + Hashtbl.remove coefpoldep (p.num,q.num) + +let coefpoldep_set p q c = + Hashtbl.add coefpoldep (p.num,q.num) c + +let initcoefpoldep d lp = + poldep:=lp; + poldepcontent:= map (fun p -> contentP (ppol p)) lp; + iter + (fun p -> coefpoldep_set p p (polconst d (coef_of_int 1))) + lp + +(* keeps trace in coefpoldep + divides without pseudodivisions *) + +let reduce2_trace p l lcp = + let l = if nouveaux_pol_en_tete then rev l else l in + (* rend (lq,r), ou r = p + sum(lq) *) + let rec reduce p = + match p with + [] -> ([],[]) + |t::p' -> + let (a,m)=t in + let q = + (try find_hmon m + with Not_found -> + let q = selectdiv m l in + match (ppol q) with + t'::q' -> (add_hmon m q; + q) + |[] -> q) in + match (ppol q) with + [] -> + if reduire_les_queues + then + let (lq,r)=(reduce p') in + (lq,((a,m)::r)) + else ([],p) + |(b,m')::q' -> + let b'=(P.oppP (div_coef a b)) in + let m''= div_mon m m' in + let p1=plusP p' (mult_t_pol b' m'' q') in + let (lq,r)=reduce p1 in + ((b',m'',q)::lq, r) + in let (lq,r) = reduce p in + (*info "reduce2_trace:\n"; + iter + (fun (a,m,s) -> + let x = mult_t_pol a m s in + info ((stringP x)^"\n")) + lq; + info "ok\n";*) + (map2 + (fun c0 q -> + let c = + fold_left + (fun x (a,m,s) -> + if equal (ppol s) (ppol q) + then + plusP x (mult_t_pol a m (polconst (nvar m) (coef_of_int 1))) + else x) + c0 + lq in + c) + lcp + !poldep, + r) + +let homogeneous = ref false +let pol_courant = ref polynom0 + +(*********************************************************************** + Completion + *) + +let sugar_flag = ref true + +let compute_sugar p = + fold_left (fun s (a,m) -> max s m.(0)) 0 p + +let mk_polynom p = + new_allpol p (compute_sugar p) + +let spol ps qs= + let p = ppol ps in + let q = ppol qs in + let m = snd (hd p) in + let m'= snd (hd q) in + let a = fst (hd p) in + let b = fst (hd q) in + let p'= tl p in + let q'= tl q in + let c = (pgcdpos a b) in + let m''=(ppcm_mon m m') in + let m1 = div_mon m'' m in + let m2 = div_mon m'' m' in + let fsp p' q' = + plusP + (mult_t_pol + (div_coef b c) + m1 p') + (mult_t_pol + (P.oppP (div_coef a c)) + m2 q') in + let sp = fsp p' q' in + let sps = + new_allpol + sp + (max (m1.(0) + ps.sugar) (m2.(0) + qs.sugar)) in + coefpoldep_set sps ps (fsp (polconst (nvar m) (coef_of_int 1)) []); + coefpoldep_set sps qs (fsp [] (polconst (nvar m) (coef_of_int 1))); + sps + + +let etrangers p p'= + let m = snd (hd p) in + let m'= snd (hd p') in + let d = nvar m in + let res=ref true in + let i=ref 1 in + while (!res) && (!i<=d) do + res:= (m.(!i) = 0) || (m'.(!i)=0); + i:=!i+1; + done; + !res + +(* teste if head monomial of p'' divides lcm of lhead monomials of p and p' *) + +let div_ppcm p p' p'' = + let m = snd (hd p) in + let m'= snd (hd p') in + let m''= snd (hd p'') in + let d = nvar m in + let res=ref true in + let i=ref 1 in + while (!res) && (!i<=d) do + res:= ((max m.(!i) m'.(!i)) >= m''.(!i)); + i:=!i+1; + done; + !res + +(* code from extraction of Laurent Théry Coq program *) + +type 'poly cpRes = + Keep of ('poly list) + | DontKeep of ('poly list) + +let list_rec f0 f1 = + let rec f2 = function + [] -> f0 + | a0::l0 -> f1 a0 l0 (f2 l0) + in f2 + +let addRes i = function + Keep h'0 -> Keep (i::h'0) + | DontKeep h'0 -> DontKeep (i::h'0) + +let slice i a q = + list_rec + (match etrangers (ppol i) (ppol a) with + true -> DontKeep [] + | false -> Keep []) + (fun b q1 rec_ren -> + match div_ppcm (ppol i) (ppol a) (ppol b) with + true -> DontKeep (b::q1) + | false -> + (match div_ppcm (ppol i) (ppol b) (ppol a) with + true -> rec_ren + | false -> addRes b rec_ren)) q + +(* sugar strategy *) + +let rec addS x l = l @ [x] (* oblige de mettre en queue sinon le certificat deconne *) + +let addSsugar x l = + if !sugar_flag + then + let sx = x.sugar in + let rec insere l = + match l with + | [] -> [x] + | y::l1 -> + if sx <= y.sugar + then x::l + else y::(insere l1) + in insere l + else addS x l + +(* ajoute les spolynomes de i avec la liste de polynomes aP, + a la liste q *) + +let genPcPf i aP q = + (let rec genPc aP0 = + match aP0 with + [] -> (fun r -> r) + | a::l1 -> + (fun l -> + (match slice i a l1 with + Keep l2 -> addSsugar (spol i a) (genPc l2 l) + | DontKeep l2 -> genPc l2 l)) + in genPc aP) q + +let genOCPf h' = + list_rec [] (fun a l rec_ren -> + genPcPf a l rec_ren) h' + +(*********************************************************************** + critical pairs/s-polynomials + *) + +let ordcpair ((i1,j1),m1) ((i2,j2),m2) = +(* let s1 = (max + (!allpol.(i1).sugar + m1.(0) + - (snd (hd (ppol !allpol.(i1)))).(0)) + (!allpol.(j1).sugar + m1.(0) + - (snd (hd (ppol !allpol.(j1)))).(0))) in + let s2 = (max + (!allpol.(i2).sugar + m2.(0) + - (snd (hd (ppol !allpol.(i2)))).(0)) + (!allpol.(j2).sugar + m2.(0) + - (snd (hd (ppol !allpol.(j2)))).(0))) in + match compare s1 s2 with + | 1 -> 1 + |(-1) -> -1 + |0 -> compare_mon m1 m2*) + + compare_mon m1 m2 + +let sortcpairs lcp = + sort ordcpair lcp + +let mergecpairs l1 l2 = + merge ordcpair l1 l2 + +let ord i j = + if i<j then (i,j) else (j,i) + +let cpair p q = + if etrangers (ppol p) (ppol q) + then [] + else [(ord p.num q.num, + ppcm_mon (lm p) (lm q))] + +let cpairs1 p lq = + sortcpairs (fold_left (fun r q -> r @ (cpair p q)) [] lq) + +let cpairs lp = + let rec aux l = + match l with + []|[_] -> [] + |p::l1 -> mergecpairs (cpairs1 p l1) (aux l1) + in aux lp + + +let critere2 ((i,j),m) lp lcp = + exists + (fun h -> + h.num <> i && h.num <> j + && (div_mon_test m (lm h)) + && (let c1 = ord i h.num in + not (exists (fun (c,_) -> c1 = c) lcp)) + && (let c1 = ord j h.num in + not (exists (fun (c,_) -> c1 = c) lcp))) + lp + +let critere3 ((i,j),m) lp lcp = + exists + (fun h -> + h.num <> i && h.num <> j + && (div_mon_test m (lm h)) + && (h.num < j + || not (m = ppcm_mon + (lm (!allpol.(i))) + (lm h))) + && (h.num < i + || not (m = ppcm_mon + (lm (!allpol.(j))) + (lm h)))) + lp + +let add_cpairs p lp lcp = + mergecpairs (cpairs1 p lp) lcp + +let step = ref 0 + +let infobuch p q = + if !step = 0 + then (info ("[" ^ (string_of_int (length p)) + ^ "," ^ (string_of_int (length q)) + ^ "]")) + +(* in lp new polynomials are at the end *) + +let coef_courant = ref coef1 + +type certificate = + { coef : coef; power : int; + gb_comb : poly list list; last_comb : poly list } + +let test_dans_ideal p lp lp0 = + let (c,r) = reduce2 (ppol !pol_courant) lp in + info ("remainder: "^(stringPcut r)^"\n"); + coef_courant:= P.multP !coef_courant c; + pol_courant:= mk_polynom r; + if r=[] + then (info "polynomial reduced to 0\n"; + let lcp = map (fun q -> []) !poldep in + let c = !coef_courant in + let (lcq,r) = reduce2_trace (emultP c p) lp lcp in + info "r ok\n"; + info ("r: "^(stringP r)^"\n"); + let res=ref (emultP c p) in + iter2 + (fun cq q -> res:=plusP (!res) (multP cq (ppol q)); + ) + lcq !poldep; + info ("verif sum: "^(stringP (!res))^"\n"); + info ("coefficient: "^(stringP (polconst 1 c))^"\n"); + let rec aux lp = + match lp with + |[] -> [] + |p::lp -> + (map + (fun q -> coefpoldep_find p q) + lp)::(aux lp) + in + let coefficient_multiplicateur = c in + let liste_polynomes_de_depart = rev lp0 in + let polynome_a_tester = p in + let liste_des_coefficients_intermediaires = + (let lci = rev (aux (rev lp)) in + let lci = ref lci (* (map rev lci) *) in + iter (fun x -> lci := tl (!lci)) lp0; + !lci) in + let liste_des_coefficients = + map + (fun cq -> emultP (coef_of_int (-1)) cq) + (rev lcq) in + (liste_polynomes_de_depart, + polynome_a_tester, + {coef = coefficient_multiplicateur; + power = 1; + gb_comb = liste_des_coefficients_intermediaires; + last_comb = liste_des_coefficients}) + ) + else ((*info "polynomial not reduced to 0\n"; + info ("\nremainder: "^(stringPcut r)^"\n");*) + raise NotInIdeal) + +let divide_rem_with_critical_pair = ref false + +let list_diff l x = + filter (fun y -> y <> x) l + +let deg_hom p = + match p with + | [] -> -1 + | (a,m)::_ -> m.(0) + +let pbuchf pq p lp0= + info "computation of the Groebner basis\n"; + step:=0; + Hashtbl.clear hmon; + let rec pbuchf (lp, lpc) = + infobuch lp lpc; +(* step:=(!step+1)mod 10;*) + match lpc with + [] -> + + (* info ("List of polynomials:\n"^(fold_left (fun r p -> r^(stringP p)^"\n") "" lp)); + info "--------------------\n";*) + test_dans_ideal (ppol p) lp lp0 + | ((i,j),m) :: lpc2 -> +(* info "choosen pair\n";*) + if critere3 ((i,j),m) lp lpc2 + then (info "c"; pbuchf (lp, lpc2)) + else + let a = spol !allpol.(i) !allpol.(j) in + if !homogeneous && (ppol a)<>[] && deg_hom (ppol a) + > deg_hom (ppol !pol_courant) + then (info "h"; pbuchf (lp, lpc2)) + else +(* let sa = a.sugar in*) + let (ca,a0)= reduce2 (ppol a) lp in + match a0 with + [] -> info "0";pbuchf (lp, lpc2) + | _ -> +(* info "pair reduced\n";*) + a.pol := emultP ca (ppol a); + let (lca,a0) = reduce2_trace (ppol a) lp + (map (fun q -> emultP ca (coefpoldep_find a q)) + !poldep) in +(* info "paire re-reduced";*) + a.pol := a0; +(* let a0 = new_allpol a0 sa in*) + iter2 (fun c q -> + coefpoldep_remove a q; + coefpoldep_set a q c) lca !poldep; + let a0 = a in + info ("\nnew polynomials: "^(stringPcut (ppol a0))^"\n"); + let ct = coef1 (* contentP a0 *) in + (*info ("content: "^(string_of_coef ct)^"\n");*) + poldep:=addS a0 lp; + poldepcontent:=addS ct (!poldepcontent); + + try test_dans_ideal (ppol p) (addS a0 lp) lp0 + with NotInIdeal -> + let newlpc = add_cpairs a0 lp lpc2 in + pbuchf (((addS a0 lp), newlpc)) + in pbuchf pq + +let is_homogeneous p = + match p with + | [] -> true + | (a,m)::p1 -> let d = m.(0) in + for_all (fun (b,m') -> m'.(0)=d) p1 + +(* returns + c + lp = [pn;...;p1] + p + lci = [[a(n+1,n);...;a(n+1,1)]; + [a(n+2,n+1);...;a(n+2,1)]; + ... + [a(n+m,n+m-1);...;a(n+m,1)]] + lc = [qn+m; ... q1] + + such that + c*p = sum qi*pi + where pn+k = a(n+k,n+k-1)*pn+k-1 + ... + a(n+k,1)* p1 + *) + +let in_ideal d lp p = + Hashtbl.clear hmon; + Hashtbl.clear coefpoldep; + nallpol := 0; + allpol := Array.create 1000 polynom0; + homogeneous := for_all is_homogeneous (p::lp); + if !homogeneous then info "homogeneous polynomials\n"; + info ("p: "^(stringPcut p)^"\n"); + info ("lp:\n"^(fold_left (fun r p -> r^(stringPcut p)^"\n") "" lp)); + (*info ("p: "^(stringP p)^"\n"); + info ("lp:\n"^(fold_left (fun r p -> r^(stringP p)^"\n") "" lp));*) + + let lp = map mk_polynom lp in + let p = mk_polynom p in + initcoefpoldep d lp; + coef_courant:=coef1; + pol_courant:=p; + + let (lp1,p1,cert) = + try test_dans_ideal (ppol p) lp lp + with NotInIdeal -> pbuchf (lp, (cpairs lp)) p lp in + info "computed\n"; + + (map ppol lp1, p1, cert) + +(* *) +end + + + |