解多项式方程组的吴方法的Maple代码和使用

点击打开链接 王定康研究员的中科院 数学与系统科学研究院 主页;


通常  x:\program files\maple xx\ 的路径是

currentdir() 命令返回的路径, 下载 点击打开链接 文本格式代码文件到"当前路径"即可

######################################################### 
#11111111111111111111111111111111111111111111111111111111 
# 
#Part I: The basic functions 
#        Class, Leader, Initial 
######################################################### 

readlib(factors): 
with(Groebner):
_field_characteristic_:=0;

      
# the class of poly f wrt variable ordering ord 
Class := proc(dp,ord) 
     local i,idt; 
     options remember,system; 
                     idt:=dIndets(dp); 
                     for i to nops(ord) do 
                         if member(ord[i], idt) then RETURN(nops(ord)-i+1) fi 
                     od; 
                     0 
                 end: 
# the highest order of the indeterminate var in dp 
# INPUT: 
#     dp : a diff pol 
#     var: an indeterminate 
# OUTPUT: the order 
# 
dOrder:=proc(dp,var) 
    local idt,i,dvar; 
    options remember,system;     
    idt:=indets(dp); 
    dvar:=-1;      
    for i in idt do 
      if has(i,var) then 
           if  dvar=-1 or type(dvar,symbol) 
               or (   ( not type(i,symbol) ) and ( op(1,i) > op(1,dvar) ) ) then 
               dvar:=i  ; 
           fi 
     fi; 
    od; 
    if dvar=-1 then -1 
       elif   type(dvar,symbol) then 0 
       else if nops(dvar) =1 then op(1,dvar) 
                else [op(1..nops(dvar),dvar)] 
             fi; 
                 fi; 
    end:     
       
                         
dIndets:=proc(dp) 
    local i,indet_d,idt; 
    options remember,system;      
    idt:={}; 
    indet_d:=indets(dp); 
     
    if POLY_MODE='Algebraic' then RETURN(indet_d) fi; 
     
    for i in indet_d do 
      if type(i,symbol) then idt:={op(idt),i} else idt:={op(idt),op(0,i)} fi; 
    od; 
      idt 
    end: 

# the initial of poly f wrt ord 
Initial := 

   proc(f,ord) 
   options remember,system; 
       if Class(f,ord) = 0 then 1 
       else lcoeff(f,Leader(f,ord)); 
       fi 
   end: 

# the separant of poly f wrt ord 
Separant := 

   proc(f,ord) 
   options remember,system; 
       if Class(f,ord) = 0 then 1 
       else diff(f,Leader(f,ord)); 
       fi 
   end: 

Sept:=proc(p,ord) 
local pol;
options remember,system;  
     pol:=Separant(p,ord); 
     if Class(pol,ord)=0 then RETURN(1) fi; 
     pol 
end: 

# the set of all nonconstant factors of separants of polys in as 
    
Septs:=proc(bset,ord) 
local i,list;
  options remember,system; 
    list:={}; 
    for i in bset do list:=list union Factorlist(Sept(i,ord)) od; 
    for i in list do if Class(i,ord)=0 then list:=list minus {i} fi od; 
    list 
end: 
  
    


Lessp:= 

proc(f,g,ord) 
local cf,cg,cmp,df,dg,leadf,leadg; 
options remember,system; 
   cf := Class(f,ord); 
   cg := Class(g,ord); 
   if type(f,integer) then 
         true 
   elif type(g,integer) then 
        false      
   elif cf = 0 then 
        true     
   elif cg = 0 then 
        false     
   else 
        leadf:=Leader(f,ord); 
        leadg:=Leader(g,ord); 
        
        cmp:=dercmp(leadf,leadg,ord); 
        if cmp = 1 then 
            true 
        elif cmp=-1 then 
            false 
        else         
            df := degree(f,leadf); 
            dg := degree(g,leadg); 
            if df < dg then 
               true 
            elif df = dg then 
               Lessp(Initial(f,ord),Initial(g,ord),ord) 
            else 
               false 
            fi 
        fi 
   fi 
end:     

Least:= 

proc(ps,ord) 
local i,lpol; 
options remember,system; 

  lpol:=op(1,ps); 
  for i from 2 to nops( ps ) do     
    if Lessp(op(i,ps),lpol,ord) then lpol:=op(i,ps) fi; 
  od; 
  lpol 
end: 


#############################################4 Reduced Definitions########################3 

Reducedp:= 
proc(p,q,ord,T) 
local mvar,var,idt; 
options remember,system; 

    mvar:=Leader(q,ord); 
    if type(mvar,symbol) then var:=mvar else var:=op(0,mvar) fi; 
     
     if POLY_MODE='Algebraic' then 
###############Algebraic mode#################################       
       if   nargs <4 or T='std_asc' then 
      if Class(p,ord) > Class(q,ord) and degree(p,mvar) < degree(q,mvar) then 1 else 0 fi; 
    elif T='wu_asc' then 
      if Class(p,ord) > Class(q,ord) and degree(Initial(p,ord),mvar) < degree(q,mvar) then 1 else 0 fi;        
    elif T='gao_asc' then 
    ###########################in the following case , q is a list################# 
      if Class(p,ord) > Class(op(1,q),ord) and Premas(Initial(p,ord),q,ord,'std_asc') <>0 then 1 else 0 fi;      
    elif T='tri_asc' then 
      if Class(p,ord) > Class(q,ord) then 1 else 0 fi;      
    fi;             
###############Algebraic mode#################################          
     elif POLY_MODE='Ordinary_Differential' then 
###############ODE mode#################################           
       if nargs <4 or T='std_asc' then 
        
           if Class(p,ord) > Class(q,ord) and degree(p,mvar) < degree(q,mvar) 
              and dOrder(p,var) <= dOrder(q,var) then 
              1 
           else 
              0 
           fi; 
    elif T='wu_asc' then 
      if Class(p,ord) > Class(q,ord) and degree(Initial(p,ord),mvar) < degree(q,mvar) then 1 else 0 fi;        
    elif T='gao_asc' then 
    ###########################in the following case , q is a list################# 
      if Class(p,ord) > Class(op(1,q),ord) and Premas(Initial(p,ord),q,ord,'std_asc') <>0 then 1 else 0 fi;      
    elif T='tri_asc' then 
      if Class(p,ord) > Class(q,ord) then 1 else 0 fi;                  
            
       fi; 
###############ODE mode#################################     
     elif POLY_MODE='Partial_Differential' then         
###############PDE mode#################################       
       if nargs <4 or T='std_asc' then 
              idt:=indets(p); 
              
           if dercmp(Leader(p,ord), mvar, ord)=-1 and degree(p,mvar) < degree(q,mvar) 
              and   (not member(true, map(Is_proper_derivative,idt,mvar)) )  then 
              1 
           else 
              0 
           fi; 
    elif T='wu_asc' then 
      if Class(p,ord) > Class(q,ord) and degree(Initial(p,ord),mvar) < degree(q,mvar) then 1 else 0 fi;        
    elif T='gao_asc' then 
    ###########################in the following case , q is a list################# 
      if Class(p,ord) > Class(op(1,q),ord) and Premas(Initial(p,ord),q,ord,'std_asc') <>0 then 1 else 0 fi;      
    elif T='tri_asc' then 
      if Class(p,ord) > Class(q,ord) then 1 else 0 fi;                  
            
       fi; 

      
###############PDE mode#################################       
     fi; 
end:      

############################# 
# 
# Name:          Reducedset 
# Input:     ps:     a poly set 
#          p:     a polynomial 
# OUTPUT:     redset:={q | q is in ps, q is rReduced to p } 
############################# 

Reducedset:= 

proc(ps,p,ord,T) 
local i, redset;   
options remember,system; 
    redset:={}; 
    for i in ps do 
      if Reducedp(i,p,ord,T)=1 then redset:={i,op(redset)} fi; 
    od; 
redset 
end:      

############################################################################## 
############################################################################## 
# the basic set of polyset ps 
Basicset:= 

proc(ps,ord,T) 
local qs,b,bs; 
options remember,system; 
         if nops(ps) < 2 then [op(ps)] 
         else 
             qs:=ps;             
             bs:=[]; 
             while (nops(qs) <>0) do 
                b:=Least(qs,ord); 
                bs:=[b,op(bs)]; 
                if T='gao_asc' then 
                  qs :=Reducedset(qs,bs,ord,T);                 
                else 
                  qs :=Reducedset(qs,b,ord,T); 
                fi; 
             od; 
             bs                               
         fi 
end: 

############################################################## 
# modified pseudo division: I1^s1...Ir^sr*uu = q*vv + r, 
#    where I1, ..., I_r are all distinct factors of lcoeff(vv,x) 
#    and s1, ..., sr are chosen to be the smallest 
############################################################## 
NPrem := 

   proc(uu,vv,x) 
   local r,v,dr,dv,l,t,lu,lv,gcd0; 
   options remember,system; 
       if type(vv/x,integer) then subs(x = 0,uu) 
       else 
           r := expand(uu); 
           dr := degree(r,x); 
           v := expand(vv); 
           dv := degree(v,x); 
           if dv <= dr then l := coeff(v,x,dv); v := expand(v-l*x^dv) 
           else l := 1 
           fi; 
           while dv <= dr and r <> 0 do 
#                gcd0:=gcd(l,coeff(r,x,dr),'lu','lv'); 
         gcd0:=gcd(l,coeff(r,x,dr)); 
               lu:=simplify(l/gcd0); 
               lv:=simplify(coeff(r,x,dr)/gcd0); 
         lu:=l; 
         lv:=coeff(r,x,dr); 
               t := expand(x^(dr-dv)*v*lv); 
               if dr = 0 then r := 0 else r := subs(x^dr = 0,r) fi; 
               r := expand(lu*r)-t; 
               dr := degree(r,x) 
           od; 
           r 
       fi 
   end: 
    
    
################################################################################### 
############################################################## 
# modified pseudo division: I1^s1...Ir^sr*uu = q*vv + r, 
#    where I1, ..., I_r are all distinct factors of lcoeff(vv,x) 
#    and s1, ..., sr are chosen to be the smallest 
############################################################## 
NPremfinite := 

   proc(uu,vv,x,ord) 
   local r,v,dr,dv,l,t,lu,lv,gcd0; 
   options remember,system; 
   global _field_characteristic_;
       if type(vv/x,integer) then subs(x = 0,uu) 
       else 
           r := expand(uu); 
           dr := degree(r,x); 
           v := expand(vv); 
           dv := degree(v,x); 
           if dv <= dr then l := coeff(v,x,dv); v := expand(v-l*x^dv) 
           else l := 1 
           fi; 
           while dv <= dr and r <> 0 do 
#                gcd0:=gcd(l,coeff(r,x,dr),'lu','lv'); 
         gcd0:=gcd(l,coeff(r,x,dr)); 
               lu:=simplify(l/gcd0); 
               lv:=simplify(coeff(r,x,dr)/gcd0); 
         lu:=l; 
         lv:=coeff(r,x,dr); 
               t := expand(x^(dr-dv)*v*lv) mod _field_characteristic_; 
               if dr = 0 then r := 0 else r := subs(x^dr = 0,r) mod _field_characteristic_ fi; 
               r := expand(lu*r)-t mod _field_characteristic_; 
#               r :=finite_simplify(r,ord,_field_characteristic_);
               dr := degree(r,x) 
           od; 
           r 
       fi 
   end: 
#################################################
finite_simplify:=proc(r,ord,p)
local i,res;    
   res:=r;
   for i to nops(ord) do
     res:=subs(ord[i]^p=ord[i],res) mod p;
  od;
  res:
end: 

    
################################################################################### 
################################################################################### 
# 
# pseudo remainder of poly f wrt ascending set as 

Premas := 

   proc(f,as,ord,T) 
   local r0,r1,asc;
   options remember,system;
   if nargs < 4 then asc:='std_asc' else asc:=T fi;      
     r0:=Premas_a(f,as,ord,asc);
   if POLY_MODE <> 'Partial_Differential' then RETURN(r0) fi;
   
     r1:=Premas_a(r0,as,ord,asc);
     while(r1 <> r0) do
        r0:=r1;
        r1:=Premas_a(r0,as,ord,asc);
     od;
     r1:
end:     
     




Premas_a := 

   proc(f,as,ord,T) 
   local remd,i,degenerate;
   options remember,system;  
   global  _field_characteristic_ ;  
       remd := f; 
#################下面专门处理有限域的情形############
       if (_field_characteristic_ <> 0) then
         for i to nops(as)  do 

            
           remd := NPremfinite(remd,as[i],Leader(as[i],ord),ord); 

            
         od;        
       fi;


#######################################################        
       if nargs <4 then 
        
         for i to nops(as)  do 

            
           remd := NewPrem(remd,as[i],Leader(as[i],ord)); 

            
         od; 
          
       elif T='std_asc' then 
  
         for i to nops(as)  do 
        
           remd := NewPrem(remd,as[i],Leader(as[i],ord)); 
        
         od; 
          
       elif T='tri_asc' then 
        
         for i to nops(as) do 
               if Class(remd,ord) = Class(as[i],ord) then                   
                       remd := NewPrem(remd,as[i],Leader(as[i],ord)); 
               fi 
         od;         
         

###########for wu ascending set#############         
       elif T='wu_asc' then 
        
         for i to nops(as) do 
             remd := WuPrem(remd,as[i],Leader(as[i],ord),ord,'degenerate'); 
             if degenerate=1 then RETURN( Premas(remd,as,ord,T)) fi;
         od;       
##################################################                  
        
       elif T='gao_asc' then 
        
         if Premas( Initial(remd,ord), as,ord,'std_asc' ) =0 then RETURN( Premas(remd,as,ord,'std_asc') ) fi;         
            for i to nops(as) do 
               if Class(remd,ord) = Class(as[i],ord) then 
                       remd := NewPrem(remd,as[i],Leader(as[i],ord));
                       if Premas( Initial(remd,ord), as,ord,'std_asc' ) =0 then RETURN( Premas(remd,as,ord,'std_asc') ) fi;  
 
               fi 
            od;         
          
       fi; 
        
        
       if remd <> 0 then numer(remd/lcoeff(remd)) else 0 fi 
   end: 

    
################################################################################### 
################################################################################### 

# set of non-zero remainders of polys in ps wrt ascending set as 
Remset := 

  proc(ps,as,ord,T) 
  local i,set,pset,r;
  options remember,system; 
  
     set:={}; 
     pset:={op(ps)} minus {op(as)}; 
      
     if POLY_MODE='Partial_Differential' then pset := pset union spolyset(as,ord) fi; 
      
#       print("pset=",pset); 
      
      for i in pset do r:=Premas(i,as,ord,T); 
            if r <>0  and Class(r,ord) =0 
                 then RETURN({1}) 
                 else set:=set union {r} fi 
                  od; 
    set minus {0} 
    end: 
###############################misc procedures###########
Reverse:=proc(list)
local i,n,list1;
    n := nops(list); list1 := [seq(list[n-i+1],i = 1 .. n)]; list1
end:

################ 

################################################################################### 
# Factor the polynomials in Remaider set 
################################################################################### 

Produce:=proc(rs,ord,test) 
global remfac;
options remember,system;  
local i,j,list1,list2; 
   list2 := {}; 
   for i in rs do 
       list1 := Nonumber(Factorlist(i),ord); 
       remfac := remfac union (list1 intersect test); 
       list1 := list1 minus test; 
       for j in list1 do 
           if Class(j,ord) = 0 then list1 := list1 minus {j} fi 
       od; 
       list2 := list2 union {list1} 
   od; 
   for j in list2 do  if j = {} then RETURN({}) fi od; 
   list2 
end: 

Nonumber:=proc(list,ord) 
local i,ls;
  options remember,system;  
   ls := {}; 
   for i in list do  if 0 < Class(i,ord) then ls := ls union {i} fi od; 
   ls 
end: 

Factorlist:=proc(pol) 
local i,list1,list2; 
     options remember,system; 
   if (_field_characteristic_ <>0) then 
     list1:=(Factors(pol) mod _field_characteristic_)[2]; 
   else
     list1 := factors(pol)[2]; 
   fi;
   list2 := {}; 
   for i in list1 do  list2 := list2 union {numer(i[1])} od; 
   list2 
end: 

#input  two poly set set1,set2 
#output 
Ltl:=proc(list1,list2) 
local set,i,j; 
     options remember,system; 
   set := {}; 
   for i in list1 do  for j in list2 do  set := set union {{j,i}} od od 
end: 

Lltl:=proc(llist1,list2) 
local set,i,j; 
     options remember,system; 
   set := {}; 
   for i in llist1 do 
       for j in list2 do  set := set union {i union {j}} od 
   od 
end: 

# Procedure Nrs: 
#input  a polynomial set  RS:={R1,R2,...,Rn} 
#output a set in which every element is a poly set. set:={set1,set2,...,sets} 

Nrs:=proc(rs,ord,test) 
local rm,rss,l1,i,j,rset; 
     options remember,system; 
   rss := Produce(rs,ord,test); 
   if rss={} then RETURN({}) fi; 
#    print("rss=");print(rss); 
   rset:=LProduct(rss); 
   rset 
end: 

LProduct:=proc(inlist)    # 输入是集合的集合,输出也是集合的集合 
  local i,j,k,m,n,B,C,D,T; 
     options remember,system;   
   B:=[]; 
   for i from 1 to nops(op(1,inlist)) do 
     B:=[op(B),{op(i,op(1,inlist))}]; 
   end: 
   for i from 2 to nops(inlist) do 
      C:=[];D:=[]; 
      for j from 1 to nops(B) do       
        if ((B[j] intersect op(i,inlist))<>{}) then   
           C:=[op(C),B[j]]; 
         else D:=[op(D),B[j]]; 
        end: 
      end: 
      B:=C; 
      for m from 1 to nops(D) do 
        T:=op(i,inlist); 
        for n from 1 to nops(C) do 
           if (nops(C[n] minus D[m])=1) then 
            T:=T minus (C[n] minus D[m]);   
           end:   
         end: 
       for k from 1 to nops(T) do 
           B:= [op(B),D[m] union {op(k,T)}]; 
        end : 
      end:     
    end:   
    B:={op(B)}; 
 end: 
  
LProduct_wdk:=proc(list1) 
local len,lls,i,j; 
     options remember,system; 
 len:=nops(list1); 
 if len=0 then RETURN(list1) fi; 
 lls:={}; 
 for i in op(1,list1) do 
   lls:=lls union { {i} } 
 od; 
 if len=1 then RETURN (lls) fi; 
 for j from 2 to len do 
   lls:=Lltl(lls, op(j,list1)); 
 od; 
 lls; 
end: 

Lltl:=proc(lls,ls) 
local res,i,j,l1,rm; 
     options remember,system; 
 res:={}; 
 for i in lls do 
   if i intersect ls ={} then 
      for j in ls do 
      res:= res union { i union {j} }; 
      od; 
   else 
      res:=res union {i}; 
   fi; 
 od; 
  
   l1 := nops(res); 
   rm := {}; 
   for i to l1-1 do 
       for j from i+1 to l1 do 
           if op(i,res) minus op(j,res) = {} then 
               rm := rm union {op(j,res)} 
           fi; 
           if op(j,res) minus op(i,res) = {} then 
               rm := rm union {op(i,res)} 
           fi 
       od 
   od; 
   res := res minus rm; 
   res   
end: 

####################################################### 
# Aux functions: 
# 
# 
###################################################### 
Nums:=proc(ps,ord) 
local i,n; 
     options remember,system; 
     n:=0; 
     for i in ps do 
       if Class(i,ord)=1 and POLY_MODE='Algebraic' then n:=n+1 fi ; 
       if Class(i,ord)=1 and (POLY_MODE='Partial_Differential'  or POLY_MODE='Ordinary_Differential') and torder(Leader(i,ord))=0 then n:=n+1 fi; 
     od; 
     n 
end: 

Emptyset:=proc(ds,as,ord) 
local i; 
     options remember,system; 

    if {op(ds)} intersect {op(as)} <> {} then RETURN(1) fi;
#    for i in ds do if grobner[normalf](i,as,tdeg(op(ord)))=0 then RETURN(1) fi od; 
   0; 
end: 

Non0Constp:=proc(ps,ord) 
local i; 
     options remember,system; 
   for i in ps do if Class(i,ord)=0 and i <> 0 then RETURN(1) fi od; 
   0; 
end:     
    

TestQ:=proc(ps,as,ord) 
global remfac; 
local i; 
     options remember,system; 

   for i in ps do  if grobner[normalf](i,as,ord) = 0 then remfac:=remfac union {i};RETURN(1) fi od; 
   0 
end: 

Init:=proc(p,ord) 
local pol; 
     options remember,system; 
     pol:=Initial(p,ord); 
     if Class(pol,ord)=0 then RETURN(1) fi; 
     pol 
end: 

JInitials:=proc(bset,ord) 
local pol, product; 
     options remember,system; 
     product:=1; 
     for pol in bset do 
    product:=product*Initial(pol,ord); 
     od; 
     product; 
end: 
        

Inits:=proc(bset,ord) 
local i,list; 
     options remember,system; 
    list:={}; 
    for i in bset do list:=list union Factorlist(Init(i,ord)) od; 
    for i in list do if Class(i,ord)=0 then list:=list minus {i} fi od; 
    list 
end: 

#The following will be used in algebraci case ONLY!!! 

Inits1:=proc(bset,ord) 
local i,list; 
     options remember,system; 
    list:={}; 
    for i in bset do if Class(Init(i,ord),ord)>1 then list:=list union Factorlist(Init(i,ord)) fi od; 
###  remove the the factors with class <2 
    for i in list do if Class(i,ord) < 2 then list:=list minus {i} fi od; 
    list 
end: 

####################################################################### 
####################################################################### 
# Compute the Characteristic set with FACTORIZATION      
####################################################################### 
####################################################################### 
# 
# NAME:  Cs_a 
# INPUT: ps:     a polynomial set, Suppose each pol in ps is irreducible over Q. 
#      ord:   indeterminate ordering. if ord:=[z,y,x] means z>y>x; 
#      nzero: a polynomial set. Each pol in nzero is NOT equal to 0 
#                       
#      test:  a polynomial set, which is NOT equal to 0. 
#      T:     a symbol to decide to use which kind of ascending set 
#          T: r_asc, w_asc,g_asc,q_asc=t_asc 
# OUTPUT: a list of ascending set 
##################################################################### 

Cs_a:=proc(ps,ord,nzero,test,T) 
global asc_set,INDEX,time_bs,time_rs, time_f,__testp__; 
local asc,i,j,rm,cset,test1,ps1,bset,rset, ltime_b,ltime_r,ltime_f; 
options remember,system; 

   if Nums(ps,ord)>1 then RETURN({}) fi; 
   rm := {}; 
   cset := {}; 
  if {op(ps)} intersect nzero <> {} then RETURN({}) fi; 
  if POLY_MODE='Algebraic' then 
       if nops(nzero) <> 0 and  Emptyset(nzero,ps,ord) = 1 then print("An empty set");RETURN({})  fi; 
  
       if __testp__= 1 and nops(test)  <> 0 and TestQ(test ,ps,ord) = 1 then 
           print("One factor of an initial has been found and it will be appended to the original polynomial set "); 
#           print("remfac=",remfac);
           RETURN({}) 
       fi; 
   fi; 
  
#      print("ps=",ps); 
     ltime_b:=time(); 
     bset := Basicset(ps,ord,T); 
#      print("bset=",bset); 
     time_bs:=time_bs+time()-ltime_b; 
     ltime_r:=time(); 
               
     
     rset := Remset([op(ps)],bset,ord,T); 
#       print("rset=",rset); 
     time_rs:=time_rs+time()-ltime_r; 

  
   if rset={1} then RETURN({}) fi; 
# for i in rset do if Class(i,ord)=0 then RETURN({}) fi od; 
   if rset = {} then 
       INDEX:= INDEX+1; 
       asc_set[INDEX] := bset; 
       print(`A New Component`); 
       RETURN({bset}) 
   fi; 
#    for i in rset do 
#        if (Class(i,ord) = 0) and (i <> 0) then RETURN({}) fi 
#    od; 

############## 
    if POLY_MODE='Algebraic' and __testp__= 1 then
       test1 := test union Inits(bset,ord); 
    else
       test1:=test;
    fi;
##############   
   
   
   ltime_f:=time(); 
   rset := Nrs(rset,ord,nzero union test1); 
   time_f:=time_f+time()-ltime_f; 
   if rset = {} then RETURN({}) fi; 
   cset:=map(Cs_a,map(`union`,rset,{op(bset)}),ord,nzero,test1,T); 
   map(op,cset); 
end: 

####################################################################### 
####################################################################### 
# 
# NAME:  charset_a 
# INPUT: ps:     a polynomial set, Suppose each pol in ps is irreducible over Q. 
#      ord:   indeterminate ordering. if ord:=[z,y,x] means z>y>x; 
#      nzero: a polynomial set. Each pol in nzero is NOT equal to 0 
#                       
#      T:     a symbol to decide to use which kind of ascending set 
#          T: r_asc, w_asc,g_asc,q_asc=t_asc 
# OUTPUT: a list of ascending set 
##################################################################### 

charset_a:=proc(ps,ord,nzero,T) 
global asc_set,INDEX,time_bs,time_rs, time_f; 
local asc,i,j,rm,cset,test1,ps1,bset,rset, ltime_b,ltime_r,ltime_f; 
options remember,system; 
#    if Nums(ps,ord)>1 then RETURN({}) fi; 
   rm := {}; 
   cset := {}; 
  if {op(ps)} intersect nzero <> {} then RETURN({}) fi; 
  
  if nops(nzero) <> 0 and Emptyset(nzero,ps,ord) = 1 then print("An empty set");RETURN({})   fi;   

  
#      print("ps=",ps); 
     ltime_b:=time(); 
     bset := Basicset(ps,ord,T); 
#      print("bset=",bset); 
     time_bs:=time_bs+time()-ltime_b; 
     ltime_r:=time(); 
     rset := Remset([op(ps)],bset,ord,T); 
     rset := map(primpart,rset,ord);
#      print("rset=",rset); 
     time_rs:=time_rs+time()-ltime_r; 

  
   if rset={1} or Non0Constp(rset,ord)=1 then RETURN([]) fi; 
# for i in rset do if Class(i,ord)=0 then RETURN({}) fi od; 
   if rset = {} then 
       INDEX:= INDEX+1; 
       asc_set[INDEX] := bset; 
       print(`A New Component`); 
       RETURN(bset) 
   fi; 
#    for i in rset do 
#        if (Class(i,ord) = 0) and (i <> 0) then RETURN({}) fi 
#    od; 
#    test1 := test union Inits(bset,ord); 
   ltime_f:=time(); 
#    rset := Nrs(rset,ord,nzero union test1); 
   time_f:=time_f+time()-ltime_f; 
#    if rset = {} then RETURN({}) fi; 

   cset:=charset_a({op(bset)} union rset,ord,nzero,T); 
   cset; 
end: 

charset_b:=proc(ps,ord,nzero,T) 
local cset,rs; 
options remember,system; 

   cset := charset_a(ps,ord,nzero,T); 
   rs:=Remset([op(ps)],cset,ord,T);
#   rs:=map(primpart,rs,ord);

   if rs={} then RETURN(cset) fi; 
   if rs={1} then RETURN([]) fi; 
   if cset=[] then RETURN([]) fi; 
#   #lprint("kkkkkkkkkkkkk");
#   cset:=charset_b({op(ps)} union {op(cset)} union rs,ord,nzero,T); 
   while rs<> {} do
      cset:=charset_a({op(cset)} union rs, ord,nzero,T);
#####we should consider the the following special case which  cset=[]      
      if nops(cset)=0 then RETURN(cset) fi;
      rs:=Remset(ps,cset,ord,T);
   od;
   cset 
end: 

CS_a:=proc(ps,ord,nzero,T) 
local  pset,cset,order,nonzero,asc; 
options remember, system; 
   if nargs < 1 then ERROR(`too few arguments`) 
     elif nargs>4 then ERROR(`too many arguments`) 
   fi; 
   if nargs<2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; 
   if nargs<3 then nonzero:={} else nonzero:=nzero fi; 
   if nargs<4 then asc:=`` else asc:=T fi; 
   cset:={}; 
   pset:=Nrs(ps,order,nonzero); 
   cset:=map(Cs_a,pset,order,nonzero,{},asc); 
   [op(map(op,cset))]; 
end: 

####################################################################### 
# 
# NAME:  Cs_b 
# INPUT: ps:     a polynomial set, Suppose each pol in ps is irreducible over Q. 
#      ord:   indeterminate ordering. if ord:=[z,y,x] means z>y>x; 
#      nzero: a polynomial set. Each pol in nzero is NOT equal to 0 
#                       
#      test:  a polynomial set, which is NOT equal to 0. 
#      T:     a symbol to decide to use which kind of ascending set 
#          T: r_asc, w_asc,g_asc,q_asc=t_asc 
# OUTPUT: a list of ascending set 
##################################################################### 

Cs_b:=proc(ps,ord,nzero,test,T) 
local cset,cset1,i,j,rs,rs1; 
options remember,system; 
if Nums(ps,ord)>1 then RETURN({}) fi; 
   rs1:={}; 
   cset := Cs_a(ps,ord,nzero,test,T); 
   cset1:=cset; 
   for i in cset1 do rs:=Remset([op(ps)],i,ord,'std_asc'); 
   
#    for i in cset1 do rs:=Remset([op(ps)],i,ord,T); 
#                    if rs<>{} then if rs <> {1} then rs1:=rs1 union {rs union {op(i)} } fi; 
if rs<>{} then if rs <> {1} then rs:=Nrs(rs,ord,nzero union test); rs1:=rs1 union map(`union`,rs , {op(i)} ) fi; 
                                   cset:=cset minus {i} fi 
                  od; 
   if rs1={} then RETURN(cset) fi; 
   for j in rs1 do  cset:=cset union Cs_b(ps union j,ord,nzero,test,T) od; 
   cset 
end: 

####################################################################### 
# 
# NAME:  Cs_c 
# INPUT: ps:     a polynomial set, Suppose each pol in ps is irreducible over Q. 
#      ord:   indeterminate ordering. if ord:=[z,y,x] means z>y>x; 
#      nzero: a polynomial set. Each pol in nzero is NOT equal to 0 
#                       
#      test:  a polynomial set, which is NOT equal to 0. 
#      T:     a symbol to decide to use which kind of ascending set 
#          T: r_asc, w_asc,g_asc,q_asc=t_asc 
# OUTPUT: a list of ascending set 
##################################################################### 
Cs_c:=proc(ps,ord,nzero,T) 
local cset,remf,ps1,i,nzeros; 
global remfac; 
options remember,system; 

if Nums(ps,ord)>1 then RETURN({}) fi; 
    remfac:={}; 
        cset:=Cs_b({op(ps)},ord,{op(nzero)},{},T); 
    remf:=remfac minus {op(nzero)}; 
#    print(remf);
#     print(remf); 
  for i to nops(remf) do 
#     print(remf[i]); 
#     print(ps); 
       ps1 := {op(ps)} union {remf[i]}; 
       if i = 1 then nzeros := {op(nzero)} else nzeros := nzeros union {remf[i-1]} fi; 
       cset := cset union Cs_c(ps1,ord,nzeros,T) 
   od; 
   cset 
end: 

CS:=proc(ps,ord,nzero,T) 
local i,pset,cset,order,nonzero,asc; 
options remember, system; 
   if nargs < 1 then ERROR(`too few arguments`) 
    elif nargs > 4 then ERROR(`too many arguments`) 
   fi; 
   if nargs < 2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; 
   if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; 
   if nargs < 4 then asc:='std_asc' else asc:=T fi; 
   cset:={}; 
   pset:=Nrs(ps,order,nonzero); 
   for i to nops(pset) do cset:=cset union Cs_c(pset[i],order,nonzero,asc) od; 
   [op(cset)] 
end: 

checknum:=0: 
Css:=proc(ps,ord,nzero,T) 
global remfac,checknum; 
local cset1,cset,i,j,nzero1, ps1,ps2,Is,Ninits; 
options remember,system; 
    checknum:=checknum+1; 
   remfac := {}; 
   cset1 := Cs_c(ps,ord,nzero,T); 
   cset := cset1; 
#          nn:=0;
      for i in cset1 do 
#      	  print(nops(cset1));
#      	  nn:=nn+1;
#      	  print(nn);
       if Class(i[nops(i)],ord)=1 and POLY_MODE='Algebraic' then Is:=Inits1(i,ord) else Is := Inits(i,ord) fi; 
       if POLY_MODE='Partial_Differential' or POLY_MODE='Ordinary_Differential' then Is := Is union Septs(i,ord) fi; 
       Ninits := Is minus {op(nzero)}; 
#        print("checknum=",checknum, "Ninits=",Ninits); 
       for j to nops(Ninits) do 
           ps1 := ({op(ps)} union {op(i)}) union {Ninits[j]}; 
           if j = 1 then nzero1 := {op(nzero)} 
           else nzero1 := nzero1 union {Ninits[j-1]} 
           fi; 
           cset := cset union Css(ps1,ord,nzero1,T) 
       od 
   od; 
   cset 
end: 

realfac:=proc(ps,ord) 
local  s,res,i; 
     options remember,system; 
      s:=Produce(ps,ord,{}); 
      res:={}; 
      for i in s do 
         res:=res union i; 
      od; 
      res; 
end:               
  
Degenerate:=proc(ds,as,ord) 
local i,r; 
     options remember,system; 
       for i in ds do 
         r:=Premas(i,as,ord,'std_asc'); 
         if r =0 then return 1 fi; 
       od; 
         0; 
end: 
          
###  POLY_MODE:= one of ['Algebraic','Ordinary_Differential','Partial_Differential']
### depend_relation  is like : [[x,y],[t]];          
#### T:= one of ['std_asc','norm_asc','wu_asc','gao_asc','tri_asc']          
CSS:=proc(ps,ord,nzero,T) 
global factor_time,prem_time, t_time,time_bs,time_rs,time_f; 
local asc,i,pset,cset,nonzero,order,result,wm; 
options remember,system; 
   if nargs < 2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; 
   if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; 
   if nargs < 4 then asc:='std_asc' else asc:=T fi; 
   if asc='norm_asc' then return Dec({op(ps)},order,nonzero,'std_asc');fi; 
   cset:={}; 
   factor_time:=0; 
   prem_time:=0; 
   time_bs:=0; 
   time_rs:=0; 
   time_f:=0; 
    
   t_time:=time(); 
   pset:=Nrs(ps,order,nonzero); 

   
   if asc='norm_asc' then 
        for i to nops(pset) do cset:=cset union Dec(pset[i],order,nonzero,'std_asc') od;
   else         
   	for i to nops(pset) do cset:=cset union Css(pset[i],order,nonzero,asc) od; 
   fi;
   result:=[]; 
   for i in cset do if Degenerate(nonzero,i,order)<>1 then result:=[op(result),i]; fi od; 
       #lprint("Timing","Total", time()-t_time, "Factoring", factor_time,"Prem",prem_time); 
       #lprint("BasicSet",time_bs,"RS",time_rs,"factor",time_f); 
   result; 

end: 

charset:=proc(ps,ord,nzero,T) 
global factor_time,prem_time, t_time,time_bs,time_rs,time_f; 
local asc,nonzero,order,result,cm; 
options remember,system; 
   if nargs < 2 then order:=[op(indets(ps))] else order:=[op(ord)] fi; 
   if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; 
   if nargs < 4 then asc:='std_asc' else asc:=T fi; 

   prem_time:=0; 
   time_bs:=0; 
    
  
        
   t_time:=time(); 
   
  result:=charset_b({op(ps)}, order,nonzero,asc); 
#   result:=charset_b(map(primpart,{op(ps)},order),order,nonzero,asc); 

       #lprint("Timing","Total", time()-t_time, "BasicSet",time_bs,"Prem",prem_time); 

   result; 

end: 

Css1:=proc(ps,ord,test,type) 
local  cset,i,j,septs,cset1,nonzero,vv; 
     options remember,system; 
       cset:=CSS(ps,ord,test,type); 
#       septs:={}; 
       cset1:=cset; 
       nonzero:={op(test)};
       for i in cset1 do 
               septs:=Septs(i,ord) minus Inits(i,ord); 
               if septs<>{} then

                       for j in septs do 
                       vv:=  {op(Css1(ps union {op(i)} union {j},ord,nonzero,type))};   
                       nonzero:={op(nonzero),j};                   
                       cset:={op(cset)} union vv ;
                       od 
               fi 
       od; 
   [op(cset)] 
end: 

Gsolve:=proc(ps,ord,test) 
    gsolve(ps,ord,test) 
end: 

e_val:=proc(ps,ord,test,T) 
global factor_time,prem_time, t_time,time_bs,time_rs,time_f; 
local asc,nonzero,order,result,cm; 
options remember,system; 
   if nargs < 2 then error("The input should have at least 2 parameters") fi; 
   if nargs < 3 then nonzero:={} else nonzero:=realfac({op(nzero)},ord) fi; 
   if nargs < 4 then asc:='std_asc' else asc:=T fi; 

   prem_time:=0; 
   time_bs:=0;               
   t_time:=time(); 
   nonzero:=test;
  result:=Css1({op(ps)}, ord,nonzero,asc); 
       #lprint("Timing","Total", time()-t_time, "BasicSet",time_bs,"Prem",prem_time); 

   result; 
end: 

 

wsolve:=proc() 
local rt; 
global POLY_MODE; 
POLY_MODE:='Algebraic'; 
 rt:=CSS(args); 
 rt; 
end: 

od_wsolve:=proc() 
local rt; 
global POLY_MODE,depend_relation; 
POLY_MODE:='Ordinary_Differential'; 
 if type(depend_relation,'list') and nops(depend_relation) >1 and 
    type(depend_relation[2],'list') and nops(depend_relation[2])=1 then 
     rt:=CSS(args); 
  else 
     #lprint("Please set depend_relation:=[[x,y,...],[t]] first, if x,y,... depend on t"); 
     rt:=0; 
  fi; 
 rt; 
end: 

pd_wsolve:=proc() 
local rt; 
global POLY_MODE,depend_relation; 
POLY_MODE:='Partial_Differential'; 
 if type(depend_relation,'list') and nops(depend_relation) >1 and 
    type(depend_relation[2],'list') and nops(depend_relation[2])>1 then 
     rt:=CSS(args); 
  else 
     #lprint("Please set depend_relation:=[[x1,x2,...],[t1,t2,...]] first, if x1,x2,... depend on t1,t2,..."); 
     rt:=0; 
  fi; 
 rt; 
end: 

INDEX:=0: 
__testp__:=0:
remfac:={}: 
prem_time:=0: 
factor_time:=0: 
time_bs:=0: 
time_rs:=0: 
time_f:=0: 
POLY_MODE:=Algebraic: 
RANKING_MODE:='cls_ord_var': 

# Test Program for Differentiation 


#---------------------------------------- 
# Global dependence 
#---------------------------------------- 

######################################################### 
#11111111111111111111111111111111111111111111111111111111 
# 
#Part IV: The basic functions for differential poly 
#         
######################################################### 

#Diff_Var:=[u,v,w]; # Declare variables; 

#Diff_Indets:=[X1,X2,X3]; # Declare Diff ndeterminates; 

#Lvar:=nops(Diff_Var); 

#---------------------------------------------------------- 
# main function 
#---------------------------------------------------------- 

dDiff:=proc(dp,var,n) 
   local df,i; 
     options remember,system;    
   df:=dp; 
   if nargs=2 then RETURN (DF(dp,var)) fi; 
   for i to n do 
      df:=DF(df,var); 
   od; 
   df; 
end: 
          
#========================================================== 
#         
#          dq  <- DF(dp, var) 
# 
#          (differetiating a diff polynomial) 
# 
# 
#          Input: dp, a diff polynomial; 
#                 var,  the variable w.r.t which to be differentiate   
# 
#          Output: dq,  the result after differentiating dp w.r.t var; 
# 
#=========================================================== 

DF:=proc(dp, var) 
   local dq, dp1, dp2; 
     options remember,system;    

#Step1 [Recursive base] 

      if op(0,dp) <> `+` then 
         dq:=DF_prod(dp,var); 
         RETURN(dq); 
      fi; 
    
#Step2 [Recursion] 

     dp1:=op(1,dp); 
     dp2:=normal(dp-dp1); 
     dq:=normal(DF_prod(dp1,var)+DF(dp2,var));             
          
#Step3 [Prepare for return] 

     RETURN(dq); 
      
end: 

#------------------------------------------ 
# subroutines 
#------------------------------------------ 

#========================================================= 
# 
# 
#                der <- DF_indet(indet, var) 
#       
#           (differentiate a differential indeterminante) 
# 
#   Input: indet, a differential indeterminate which is a 
#                 derivative of symobls in Diff_Indets w.r.t 
#                 some variables in Diff_Var; 
# 
#          var,   the variable w.r.t which to be differeniated 
# 
#   Output: der,  the derivative of indet w.r.t var 
# 
#=========================================================== 

DF_indet:=proc(indet, var) 
         local der, p, i, index, j,Diff_Var,Diff_Indets,Lvar; 
         global depend_relation; 
     options remember,system;          

#STEP0 [Initiation diffs]; 
          
         Diff_Var:=depend_relation[2]; 
         Diff_Indets:=depend_relation[1]; 
         Lvar:=nops(Diff_Var); 
          
#STEP1 [Special cases] 
          
         if  not member(var, Diff_Var, 'p') then 
             der := diff(indet, var); 
             RETURN(der); 
         fi; 
          
         if not member(indet, Diff_Indets) and 
            not member(op(0,indet), Diff_Indets) then 
            der := diff(indet, var); 
            RETURN(der); 
         fi; 
          
#STEP2 [Compute] 

         index:=NULL; #Initialization 
          
         if member(indet, Diff_Indets) then   
          
         # build a derivative from a diff indet       
          
            for i from 1 to Lvar do 
                if i = p then 
                   index:=index,1; 
                else 
                   index:=index,0; 
                fi; 
            od; 
            der:=indet[index]; 
         else   
          
         # modify a derivative from a given one 
          
           for i from 1 to Lvar do 
               j:=op(i,indet); 
               if i = p then 
                  index:=index,(j+1); 
               else 
                  index:=index,j; 
               fi; 
           od; 
           der:=op(0,indet)[index] 
         fi; 
          
#STEP3 [Prepare for return] 
          
          RETURN(der); 
          
end: 

#======================================================== 
# 
#           dq <- DF_power(dp, var) 
# 
#           (differentiating a power of a drivative of a diff indet) 
# 
#           input:  dp, a power of a diff indet 
#                   var, the variable w.r.t which to be differentiated 
# 
#           output: dq, the result after differentiating dp w.r.t var 
# 
#========================================================= 

DF_power:=proc(dp, var) 
         local dq, indet, expon; 
              options remember,system; 
          
#Step1 [Special cases] 

      # constant case 
      
      if dp = 1 then 
         dq := 0; 
         RETURN(dq); 
      fi; 
      
      # indeterminate case 
      
      if op(0,dp) <> `^` then 
         dq := DF_indet(dp, var); 
         RETURN(dq); 
      fi; 
                
#Step2 [Compute] 

      indet:=op(1,dp); 
      expon:=op(2,dp); 
      dq:=expon*indet^(expon-1)*DF_indet(indet,var); 
    
#Step3 [Prepare for return] 

      RETURN(dq); 

end: 

#========================================================= 
# 
#        dq <- DF_prod(dp, var) 
# 
#        (differentiating a product of derivatives of some diff indets)     
# 
#        input: dp, a product of derivatives of some diff indets   
#               var,  the variable w.r.t which to be differentiated 
# 
#        output:  dq, the result after differentiating dp w.r.t var; 
# 
#========================================================== 

DF_prod:=proc(dp, var) 
        local dq, dp1, dp2; 
             options remember,system; 

#Step1 [Recursive base] 

      if op(0,dp) <> `*` then 
         dq := DF_power(dp, var); 
         RETURN(dq); 
     fi; 

#Step2 [Recursion] 

     dp1:=op(1,dp); 
     dp2:=normal(dp/dp1); 
      
     dq:=normal(DF_power(dp1,var)*dp2+dp1*DF_prod(dp2,var)); 
      
#Step3 [Prepare for return] 

     RETURN(dq); 
      
end: 
                                        
#=============================================================== 
# 
#            ord  <- torder(der) 
# 
#           computing the order of a derivative of a diff indet 
# 
#           input: der, a derivative of a diff indet 
# 
#           output: ord, ord is the order of der. 
# 
#================================================================= 

torder:=proc(der) 
local ord,i,Diff_Var,Lvar; 
global depend_relation; 
     options remember,system; 

#STEP1 [Initialize] 

      if type(der,symbol) then RETURN(0) fi; 

         ord := 0; 
              
#STEP2 [Compute] 

           
              for i from 1 to nops(der) do 
                 ord := ord + op(i, der); 
              od; 
 ord; 
end: 
                    

#================================================================== 
#     
#            lead <- Leader(dp, ranking,ord, _cls, _ord) 
#     
#            Input: dp, a  nonzero diff poly; 
#                   ranking, a specified ranking; 
# 
#            Output: the Leader w.r.t. ranking; 
# 
#            Option: _cls, the class of the lead; 
#                   _ord,, the order of the lead; 
# 
#=================================================================== 
Mainvar:=proc(p,ord) 
     options remember,system; 
 Leader(p,ord); 
 end: 

Leader := proc(dp, ord, _cls, _ord) 
         local lead, cls, order, L, l,  der, clsord, i, j, cls1, ord1,Diff_Var,Lvar; 
      global depend_relation; 
           options remember,system;     
           
#Step1 [Initialize] 

         Diff_Var:=depend_relation[2]; 
         Lvar:=nops(Diff_Var); 
         L:=indets(dp); l:=nops(L); 
         lead := 1; 
         cls := 0; 
         order := 0; 

#Step 2 [Algebraic mode] 

        if POLY_MODE='Algebraic' then 
         for i to nops(ord) do 
           if member(ord[i],L) then RETURN(ord[i]) fi 
         od; 
        fi; 

#Step2 [cls_ord_var case] 

         if RANKING_MODE = cls_ord_var then 
            for i from  1 to l do 
                der := L[i]; 

                cls1:=Class(der,ord); 
                ord1:=torder(der); 
                
                if cls1 > cls  or (cls1 = cls and ord1 > order) then 
                   lead := der; 
                   cls := cls1; 
                   order := ord1 
                else 
                   if cls1 = cls and ord1 = order and ord1 > 0 then 
                      for j from 1 to Lvar do 
                         if op(j, lead) < op(j, der) then 
                            lead := der; 
                            cls := cls1; 
                            order := ord1; 
                            break; 
                         else 
                            if op(j, lead) > op(j, der) then; 
                            break; 
                            fi; 
                         fi; 
                     od; 
                   fi; 
               fi; 
            od; 
         fi; 
          
#Step3 [ord_cls_var case] 
          
         if RANKING_MODE = ord_cls_var then 
            for i from  1 to l do 
                der := L[i]; 
                cls1:=Class(der,ord); 
                ord1:=torder(der); 
                if ord1 > order or (ord1 = order and cls1 > cls) then 
                   lead := der; 
                   cls := cls1; 
                   order := ord1 
                elif ord1 = order and cls1 = cls and ord1 > 0 then 
                     for j from 1 to Lvar do 
                         if op(j, lead) < op(j, der) then 
                            lead := der; 
                            cls := cls1; 
                            order := ord1; 
                            break; 
                         elif op(j, lead) > op(j, der) then; 
                            break; 
                         fi; 
                     od; 
               fi; 
            od; 
         fi; 
          

#STEP3 [Prepare for return] 

          
         if nargs > 2 then 
            _cls := cls; 
         fi; 
         if nargs > 3 then 
            _ord := order; 
         fi; 
          
         RETURN(lead); 
          
end: 



         


          
depend:=proc(l1,l2) 
global depend_relation; 
 depend_relation:=[l1,l2]; 
 1: 
 end: 
#============================================================ 
# 
#       {1,-1,0} <- dercmp(der1, der2) 
# 
#       input: der1, der2, two derivatives; 
#           
# 
#       output: 0 if der1 = der2 
#               1 if der1 < der2 
#              -1 if der1 > der2 
# 
#============================================================   
dercmp:=proc(der1, der2,ord) 
           local dp, lead; 
                options remember,system; 
            
           if der1=der2 then RETURN(0) fi; 
            
           dp := der1 + der2; 
           lead:=Leader(dp,ord); 
           if lead = der1 then 
              RETURN(-1); 
           else 
              RETURN(1); 
           fi; 
            
end: 

#if der1 is a derivative of der2 then return true else false
Is_derivative:=proc(der1, der2) 
              local dt1,dt2,i, l1,l2; 
                   options remember,system; 
              
              
               if type(der1,symbol) then dt1:=der1 else dt1:=op(0,der1) fi; 
               if type(der2,symbol) then dt2:=der2 else dt2:=op(0,der2) fi; 
            if dt1<>dt2 then RETURN(false) fi; 
            if der1=der2 then RETURN(true) fi; 
             
            if torder(der2)=0 then 
                 RETURN(true) 
            elif torder(der1)=0 then 
                   RETURN(false) ; 
           else 
                l1:=dOrder(der1,dt1); 
                l2:=dOrder(der2,dt1); 
                for i to nops(l1) do 
                     if op(i,l1) < op(i,l2) then RETURN(false) fi; 
                od; 
         fi; 
                           
           true; 
end: 
                                                  
#if der1 is a proper derivative of der2 then return true else false
Is_proper_derivative:=proc(der1, der2) 
              local dt1,dt2,i, l1,l2; 
                   options remember,system; 
              
              
               if type(der1,symbol) then dt1:=der1 else dt1:=op(0,der1) fi; 
               if type(der2,symbol) then dt2:=der2 else dt2:=op(0,der2) fi; 
            if dt1<>dt2 then RETURN(false) fi; 
            if der1=der2 then RETURN(false) fi; 
             
            if torder(der2)=0 then 
                 RETURN(true) 
            elif torder(der1)=0 then 
                   RETURN(false) ; 
           else 
                l1:=dOrder(der1,dt1); 
                l2:=dOrder(der2,dt1); 
                for i to nops(l1) do 
                     if op(i,l1) < op(i,l2) then RETURN(false) fi; 
                od; 
         fi; 
                           
           true; 
end: 

#return all the derivatives in dp of der
proper_derivatives:=proc(dp,der) 
    local i,idt,dets; 
         options remember,system; 
    idt:=indets(dp); 
    dets:={}; 
     
    for i in idt do 
      if Is_proper_derivative(i,der) then 
         dets:={i,op(dets)}; 
         
      fi; 
    od; 
    dets;      
end:      

       
     
     

#sometimes, Maple's GCD is NOT valid for parameters which has indexes such a[1],a[2]; 

NPremO := 

   proc(uu,vv,xx) 
   local r,v,dr,dv,lcv,rtv,g,lu,lv; 
    options remember,system; 
     if degree(vv,xx)=0 then RETURN(0) fi; 
     if type(vv/xx,integer) then coeff(uu,xx,0) 
       else 
           r := expand(uu); 
           dr := degree(r,xx); 
           v := expand(vv); 
           dv := degree(v,xx); 
            
             lcv:=lcoeff(v,xx); 
#            rtv:=sterm(v,xx); 
           rtv:=v-expand(lcoeff(v,xx)*xx^degree(v,xx)); 

           while dv <= dr and r <> 0 do 

#              g:=gcd(lcv,coeff(r,xx,dr)); 

             lu:=lcv; 

             lv:=coeff(r,xx,dr); 
                  
               r:=expand(lu*(r-expand(lcoeff(r,xx)*xx^degree(r,xx)))-lv*rtv*xx^(dr-dv)); 
               dr := degree(r,xx) 
           od; 
           r 
       fi 
   end: 
  
  
#######变量y有两种情形.y and y[1]所以要小心. 

  
ODPrem:= 

  proc(uu,vv,y) 
    local u,x,dv,du,d,t,var; 
    global depend_relation; 
    options remember,system;         
    
       t:=depend_relation[2][1]; 
       var:=depend_relation[1]; 
  
#        if dClass(uu,var)=0 then RETURN(uu) fi; 

          u:=uu; 
          if type(y,symbol) then x:=y else         x:=op(0,y)  fi;                 
          dv:=dOrder(vv,x); 
          du:=dOrder(u,x); 
          d:=du-dv; 
          if d<0 then RETURN(uu) fi; 
#the following program is for ordinary differential case                 
          while d>0 do 

            u:=NPremO(u,dDiff(vv,t,d), x[du]); 
            du:=dOrder(u,x); 
            d:=du-dv; 
          od; 
#         
          if dv =0 then NPremO(u,vv,x) else NPremO(u,vv,x[dv]) fi;                           

            
   end:     

    
NewPrem:= 

  proc(uu,vv,y) 
    local u,x,dv,du,d,t,var; 
    global depend_relation;
    options remember,system;      
    
    if POLY_MODE='Algebraic' then 
    
       NPrem(uu,vv,y); 
        
    elif POLY_MODE='Ordinary_Differential' then         
    
    ODPrem(uu,vv,y);                      
     
    elif POLY_MODE='Partial_Differential' then 
        
       PDPrem(uu,vv,y); 
        
    fi; 
            
   end:     



Headder:=proc(idts) 
local hder,i,j; 
     options remember,system; 
  hder:=op(1,idts);   
  
#   if type(hder,symbol) then var:=hder else var:=op(0,hder) fi; 
        
  for i in idts do 
  
    if torder(i) > torder(hder) then 
        hder:=i ;           
    elif torder(i)=torder(her) then 
       for j to nops(hder) do 
          if op(j,i) > op(j,hder) then hder:=i;break; 
          elif op(j,i) < op(j,hder) then break; 
          fi; 
       od; 
    fi; 
                   
   od; 
    
  hder: 
  
end: 


PDPrem:=proc(dp, dq, y) 
          local Diff_Indets,Diff_Var, var,dr, idt,l2,lder,da,l1,i,s; 
          options remember,system; 

#Step1 [Special case] 

          
    Diff_Indets:=depend_relation[1]; 
    Diff_Var:=depend_relation[2]; 
               
    if y=1 then RETURN(0) fi; 
     
    if type(y,symbol) then var:=y else var:=op(0,y) fi; 
     
    dr:=dp; 
     
       idt:=proper_derivatives(dr,y); 
       l2:=dOrder(y,var); 

#Step2 [Recursive base]         

       while  nops(idt)<>0 do 

          
          lder:=Headder(idt); 
          
          da := dq; 
                    

          
          l1:=dOrder(lder,var); 

          
          
          for i to nops(l1) do 
          
           if l2=0 then s:=op(i,l1) else s:=op(i,l1) -op(i,l2) fi; 
           
                  da := dDiff(da, Diff_Var[i],s); 
            
          od; 
          
          dr := NPremO(dr, da, lder); 
          
       idt:=proper_derivatives(dr,y);           
          
    od; 

         dr:=NPremO(dr,dq,y) ; 
          
#Step4 [Prepare for return] 

    dr;           
          
end:                 
          
  
    

# 
# set:  A set; 

cmb:=proc(set0) 
local p,q, ls,set1; 
     options remember,system; 
    ls:={}; 
    
    set1:=set0; 
    
 for p in set0 do 
    set1:=set1 minus {p}; 
    for q in set1  do 
        ls:={op(ls),[p,q]} 
    od; 
 od; 
 ls; 
end: 
  

######## modified Nov.6 ######## 

          
spolyset:=proc(as,ord) 
local res,bs,l,p,cls,i,poly; 
     options remember,system; 
    
   res:={}; 
   bs:={op(as)}; 
   l:=nops(bs); 
   if l <= 1 then RETURN(res) fi; 
    
   p:=op(1,bs); 
   cls:=Class(Leader(p,ord),ord); 
   bs:=bs minus {p}; 
        
   while nops(bs) <>0  do 
     for i in bs do 
        if Class(Leader(i,ord),ord) = cls then poly:=PD_spoly(i,p,ord); res:=res union {poly} fi; 
     od; 
      
      
   p:=op(1,bs); 
   cls:=Class(Leader(p,ord),ord); 
   bs:=bs minus {p};   
      
   od; 
  
   res minus {0}; 
end: 
    
          

      
            
    
    
PD_spoly:=proc(p,q,ord)     
local     leadp,leadq,var,l1,l2,ml,dp,dq,i,Diff_Var; 
global  depend_relation; 
options remember,system; 
    leadp:=Leader(p,ord); 
    leadq:=Leader(q,ord); 
     
    var:=op(0,leadp); 
    Diff_Var:=depend_relation[2]; 
     
    l1:=dOrder(leadp,var); 
    l2:=dOrder(leadq,var); 
     
    ml:=maxlist(l1,l2); 
     
    dp:=p; 
    dq:=q; 
     
    for i to nops(ml) do 
      dp:=dDiff(dp,Diff_Var[i],ml[i]-l1[i]); 
      dq:=dDiff(dq,Diff_Var[i],ml[i]-l2[i]); 
    od; 
     
######直觉觉得可以直接用PDPrem(dp,q,Leader(q,ord)) 更好。而这里用的是标准的方法。      
   NPremO(dp,dq, Leader(dq,ord)); 
    
end:     
     
     
maxlist:=proc(l1,l2)      
local i,list;
options remember,system;  
    list:=[]; 
    for i to nops(l1) do 
      list:=[op(list), max(l1[i],l2[i])]; 
    od: 
list 
end:      

#torder   Is_deriv Reducedp Leader Head Leader PDE map Num spoly NewPrem 

# the class of poly f wrt variable ordering ord 
MainVariables := proc(ps,ord) 
    local i,set; 
       options remember,system; 
    set:={}; 
    for i in ps do 
      set:=set union {Leader(i,ord)}; 
    od; 
set 
end:      
            
PNormalp:=proc(p,as,ord) 
    local i,idts,mvs,initp;
    options remember,system;      
    initp:=Initial(p,ord); 
    idts:=indets(initp); 
    if idts={} then RETURN(true) fi; 
    mvs:=MainVariables(as,ord); 
    for i in idts do 
       if member(i,mvs) then RETURN(false) fi; 
    od; 
true 
end:      

ASNormalp:=proc(ps,ord) 
    local i,l,as,p; 
    options remember,system; 
    l:=nops(ps); 
    if l=1 then RETURN(true) fi; 
    as:=[ps[l]]; 
    for i from l-1 to 1 by -1 do 
      p:=ps[i]; 
      if not PNormalp(p,as,ord) then RETURN(false) fi; 
      as:=[p,op(as)]; 
    od;        
true 
end:      

Dec:=proc(ps,ord,nzero,T) 
global remfac,checknum; 
local i,cset1,cset;
options remember,system; 

    cset1:=Cs_c(ps,ord,nzero,T); 
    cset:={}; 
    for i in cset1 do 
      if ASNormalp(i,ord) then 
         cset:=cset union NormDec1(ps,i,ord,nzero,T);      
         else 
                cset:=cset union NormDec2(ps,i,ord,nzero,T); 
         fi;                     
   od; 
cset 
end: 

NormDec1:=proc(ps,as,ord,nzero,T) 
local     cset,j,nzero1, ps1,ps2,Is,Ninits;
options remember,system;

        cset:= {as};      
         if Class(as[nops(as)],ord)=1 then Is:=Inits1(as,ord) else Is := Inits(as,ord) fi;             
         Ninits := Is minus {op(nzero)}; 
     
         for j to nops(Ninits) do 
               ps1 := ({op(ps)} union {op(as)}) union {Ninits[j]}; 
               if j = 1 then nzero1 := {op(nzero)} 
               else nzero1 := nzero1 union {Ninits[j-1]} 
               fi; 
               cset := cset union Dec(ps1,ord,nzero1,T) 
         od; 
cset 
end:           
          
NormDec2:=proc(ps,as,ord,nzero,T) 
local cset,i,j,l,regas,p,initp,lp,pol,r1,r2,Is,Ninits,l2,ps1,nzero1,mvar,vars,mv,d,f,g;
options remember,system; 
    cset:={}; 
     
    l:=nops(as); 
    regas:=[as[l]]; 
     
    for i from 2 to l do 
      p:=as[l-i+1]; 
      mvar:=Leader(p,ord); 
      d:=degree(p,mvar); 
      if PNormalp(p,regas,ord) then 
         regas:= [p,op(regas)] 
      else 
         initp:=Initial(p,ord); 
         vars:=indets(initp); 
         lp:=nops(regas); 
         ###1 开始111 
             for j to lp do 
                 pol:=regas[j]; 
                 mv:=Leader(pol,ord); 
                 if member(mv,vars) then 
#                  注意Resultant函数 

                 r1:=NResultantE(initp,pol, Leader(pol,ord),'f','g'); 
                 r2:=Premas(r1,regas,ord,'std_asc'); 
                 if r2=0 then 
       
                          if Class(as[nops(regas)],ord)=1 then Is:=Inits1(regas,ord) else Is := Inits(regas,ord) fi;             
                          Ninits := Is minus {op(nzero)}; 
               
                       l2:=nops(Ninits); 
                       nzero1:={op(nzero)}; 

                          for j to l2 do 
                              ps1 := ({op(ps)} union {op(as)}) union {Ninits[j]}; 
                              if j <> 1 then 
                               nzero1 := nzero1 union {Ninits[j-1]} 
                              fi; 
                              cset := cset union Dec(ps1,ord,nzero1,T) 
                          od; 
                          print("kkkkkkkkkk"); 
                          if l2 <> 0 then nzero1:=nzero1 union {Ninits[l2]} fi; 
#                   f;g; 
#                   print("cset=",cset);
#                   print("ps=",ps);
#                   print("as=", as);
#                   print("regas=",regas);
                   
                          cset:=cset union Dec(ps union {op(as)} union {op(regas)} union {f},ord,nzero1,T) union Dec(ps union {op(as)} union {op(regas)} union {initp},ord,nzero1,T); 
                   RETURN(cset);            
                 else 
             
#                  p 变形成新的p 
              p:=expand(f*p+g*pol*mvar^d); 
              p:=Premas(p,regas,ord,'std_asc'); 
                 initp:=Initial(p,ord); 
                 vars:=indets(initp); 
              fi; 
              fi; 
             od;   
         ###1 结束111   
         regas:=[p,op(regas)]   
      fi;        
      od; 
    cset:=NormDec1(ps,regas,ord,nzero,T); 
cset      
end:        


#如果首项系数变成0,而余式不是0则置degenerate为1否则为0。
WuPrem:=

   proc(uu,vv,x,ord,degenerate)
   local r,init,lead,lmono,red,init_r,s,t;
   options remember,system;    
   degenerate:=0;
   if uu=0 then RETURN(0) fi;
      r:=uu;  
   if Class(uu,ord) = Class(vv,ord) then 
      r:= NPrem(uu,vv,x);
   elif Class(uu,ord) > Class(vv,ord) then
      init:=Initial(uu,ord); 
      if  degree(init,x) >0 and Reducedp(init, vv,ord,'std_asc') = 0  then 
          lead:=Leader(uu,ord);
#	  collect(uu,lead);
          lmono:=lead^degree(uu,lead);
          red:=expand(uu-init*lmono);
          init_r:=NPremE(init,vv,x,'s','t');    
          r:=expand(init_r*lmono+s*red); 
          if init_r=0 and r <>0 then degenerate:=1 fi;
#          collect(r,lead);
       fi;
    fi;
    r;
end:    

NPremE := 

   proc(uu,vv,x,s1,t1) 
   local r,v,dr,dv,l,t,lu,lv,s0,t0; 
   options remember,system; 

        s0:=1; 
        t0:=0;           
           r := expand(uu); 
           dr := degree(r,x); 
           v := expand(vv); 
           dv := degree(v,x); 
           if dv <= dr then l := coeff(v,x,dv); v := expand(v-l*x^dv) 
           else l := 1 
           fi; 
           while dv <= dr and r <> 0 do 
               gcd(l,coeff(r,x,dr),'lu','lv'); 
         s0:=lu*s0; 
         t0:=lu*t0+lv*x^(dr-dv); 
               t := expand(x^(dr-dv)*v*lv); 
               if dr = 0 then r := 0 else r := subs(x^dr = 0,r) fi; 
               r := expand(lu*r)-t; 
               dr := degree(r,x) 
           od; 
        s1:=expand(s0); 
        t1:=expand(t0);           
           r 
   end: 

#This function is for ascending set normalization. 
#in fact, it is not  a resultant for 2 pols with indeterminate x. 
#for two polys uu,vv with indeterminate x 
#it has the property m*uu+n*vv=r with degree(r,x)=0; 
NResultantE := 

   proc(uu,vv,x,m,n) 
   local r,s,t,r0,s0,t0,r1,s1,t1,tmpr,tmps,tmpt; 
   options remember,system; 
        r0:=uu; 
        s0:=1; 
        t0:=0; 
        r1:=vv; 
        s1:=0; 
        t1:=1;           
        if degree(r0,x)=0 then m:=1;n:=0;RETURN(r0) fi; 
           if degree(r1,x)=0 then m:=0;n:=1;RETURN(r1) fi; 

           while degree(r1,x) >= 1 do 
             r:=NPremE(r0,r1,x,'s','t');        
          
            tmpr:=r1; 
         tmps:=s1; 
         tmpt:=t1; 
         r1:=r; 
         s1:=s*s0-t*s1; 
         t1:=s*t0-t*t1; 
         r0:=tmpr; 
         s0:=tmps; 
         t0:=tmpt; 
           od; 
        m:=s1; 
        n:=t1; 
           r 
   end: 



##############################################################################
# Name: SylvesterResultant
# Calling sequence:  SylvesterResultant(f, g, x, u, v)
#   Input: f, g two polynomials in x with positive degrees
#          x, a name
#   Output: the Sylvester resultant of f and g with respect to x
#   Optional: u, v,  such that 
#                   u*f+v*g = resultant
###############################################################################

#SylvesterResultant := proc(f, g, x, u, v)
NResultantE := proc(f, g, x, u, v)
   local df, dg, deg, A, a, b, U, V, i, m, Q, l, e, s, us, vs;

   #-------------------------------------------
   # check input
   #-------------------------------------------

   (df, dg) := degree(f, x), degree(g, x);
   if df = 0 or dg = 0 then 
      error "input polynomials should be of positive degrees";
   end if;

   #---------------------------------------------
   # initialize data
   #---------------------------------------------

   if df >= dg then
      (A[1], A[2]) := f, g;
      (deg[1], deg[2]) := df, dg;
   else
      (A[1], A[2]) := g, f;
      (deg[1], deg[2]) := dg, df;
   end if;

   if nargs > 3 then
         (U[1], U[2]) := 1, 0;
         if nargs > 4 then
            (V[1], V[2]) := 0, 1;
         end if;
   end if;

   (a[1], b[1], a[2], b[2]) := (1, 1, lcoeff(A[2],x), lcoeff(A[2], x)^(deg[1]-deg[2]));

   i := 2;
   l[i] := deg[i-1]-deg[i]+1;

   #----------------------------------------------
   #  compute
   #----------------------------------------------

   while true do
         i := i + 1;

	 #-------------------------------
	 # form extraneous factor
	 #-------------------------------

	 e[i] := (-1)^l[i-1]*a[i-2]*b[i-2];

	 #--------------------------------
	 # compute remainder
	 #--------------------------------

	 if nargs = 3 then
	    A[i] := evala(Simplify(prem(A[i-2], A[i-1], x)/e[i]));
	 else
	    A[i] := evala(Simplify(prem(A[i-2], A[i-1], x, 'm', 'Q')/e[i]));
	    U[i] := evala(Simplify((m*U[i-2] - Q*U[i-1])/e[i]));
	    if nargs = 5 then
	       V[i] := evala(Simplify((m*V[i-2] - Q*V[i-1])/e[i]));
	    end if;
	  end if;

	  #-----------------------------------
	  # Resultant is zero
	  #-----------------------------------
         	    
          if A[i] = 0 then 
	     if nargs > 3 then
	        u := U[i];
		if nargs > 4 then
		   v := V[i];
		end if;
	      end if;
	      return A[i];
	   end if;

	   #------------------------------------
	   # update auxiliary sequences
	   #------------------------------------

	   deg[i] := degree(A[i], x);
	   l[i] := deg[i-1]-deg[i]+1;
	   a[i] := lcoeff(A[i], x);
	   b[i] := evala(Simplify(a[i]^(l[i]-1)/b[i-1]^(l[i]-2)));
	   

           #-------------------------------------------
	   # Resultant is nonzero
	   #-------------------------------------------

	   if deg[i] = 0 then
	      if nargs > 3 then
	         s := evala(Simplify(b[i]/a[i]));
	         us := evala(Simplify(U[i]*s));
		 if nargs > 4 then
		    vs  := evala(Simplify(V[i]*s));
		 end if;
	         if df >= dg then
	            u := us;
	            if nargs > 4 then
	               v := vs;
	            end if;
	         else
	            u := (-1)^(df*dg)*vs;
	            if nargs > 4 then
	               v := (-1)^(df*dg)*us;
	            end if;
	         end if;
	      end if;
	      if df >= dg then
	         return b[i];
	      else
	         return (-1)^(df*dg)*b[i];
	      end if;
	   end if;
    end do;
end proc:
   


#printf("    Pls type 'with(linalg)' firstly before calling function 'Resultant_E' "); 

##The following is to compute the resultant of 2 pols via computing the determinant directly.
# input: M is a list of lists , whereby to denote a matrix; 
#        i,j are two integer numbers; 
# output:sM is a new list of lists, obtained by removing 
#        the ith row and jth column of L, 
SubM:=proc(M,i,j) 
    local row,tmp,sM; 
    if i<1 or i>nops(M) 
         then error "Input row index %1 broke bounds",i;fi; 
    if j<1 or j>nops(M[1]) 
         then error "Input column index %1 broke bounds",j;fi; 
    sM:=[]; 
    tmp:=subsop(i=NULL,M); 
    for row in tmp 
         do row:=subsop(j=NULL,row); 
            sM:=[op(sM),row]; 
         od; 
    sM; 
end: 
     



# with(linalg) firstly 
# input: A,B are two polynomials, v is a variable; 
# output:[R,T,U]; R,T,U are three polynomials, where R is the resultant 
#        of A,B w.r.t v, so that A*T+B*U=R 
#with(linalg); 
NResultantE_Matrix:=proc(A,B,v,TA,UB) 
    local m,n,d1,d2,cA,cB,row,i,j,syl,msyl,sM,sign,R,T,U,result; 
#    #lprint("nargs=",nargs); 

    if (nargs <> 3) and (nargs <> 5) then error "Number of parameters should be 3 or 5" fi; 
     
    m:=degree(A,v); 
    n:=degree(B,v); 
    if m=0 then error "InPut Polynomial %1 Has No Variable %2",A,v;fi; 
    if n=0 then error "InPut Polynomial %1 Has No Variable %2",B,v;fi; 
  
#  to get coefficients of A and B 
    cA:=[]; 
    for d1 from 0 to m 
         do cA:=[coeff(A,v,d1),op(cA)]; 
         od; 
    cB:=[]; 
    for d2 from 0 to n 
         do cB:=[coeff(B,v,d2),op(cB)]; 
         od; 

#  initialize sylvester matrix 
     
    syl:=[]; 
    for i from 1 to n         
         do row:=cA; 
               for j from 1 to i-1 
              do row:=[0,op(row)];od; 
            for j from 1 to n-i 
                do row:=[op(row),0];od; 
               syl:=[op(syl),row]; 
            od; 
             
    for i from 1 to m 
         do row:=cB; 
               for j from 1 to i-1 
              do row:=[0,op(row)];od; 
            for j from 1 to m-i 
                do row:=[op(row),0];od; 
               syl:=[op(syl),row]; 
            od; 
     
    msyl:=linalg[matrix](m+n,m+n,syl); 
     
#   to get resultant of A,B w.r.t v 
    R:=linalg[det](msyl); 
    R:=expand(R); 
    if nargs=3 then RETURN(R) fi; 
     
#   to get T 
    T:=0; 
    for d1 from 1 to n 
         do 
         sign:=(-1)^(d1+m+n mod 2);           
         sM:=SubM(syl,d1,m+n); 
         T:=T+(v^(n-d1))*expand(sign*linalg[det](linalg[matrix](m+n-1,m+n-1,sM))); 
         T:=expand(T); 
         od; 
          
#  to get U 
        U:=0; 
    for d2 from 1 to m 
         do 
         sign:=(-1)^(d2+m mod 2);      
         sM:=SubM(syl,d2+n,m+n); 
         U:=U+(v^(m-d2))*expand(sign*linalg[det](linalg[matrix](m+n-1,m+n-1,sM))); 
         U:=expand(U); 
         od; 
        if nargs=5 then TA:=T; UB:=U fi; 
    R; 
end: 

###########################################################################################
###########################################################################################
############## computing partioned-parametric Grobner basis 2005.11.4###################
##需要 “wsolve” 和 “project”
##文后付有主要函数调用的例子
###########################################################################################
###########################################################################################
###########################################################################################

interface(warnlevel=0);
with(Groebner): 


########p在约束Zero(a11/a12)下一定不为0,ord是参变元########## 
NotZeroUnderCons:=proc(a11,a12,p,ord) 
option remember; 
    RETURN(IsEmpty({op(a11),p},a12,ord)); 
end: 

########p在约束Zero(a11/a12)下一定为0,ord是参变元########## 
IsZeroUnderCons:=proc(a11,a12,p,ord) 
option remember; 
    RETURN(IsEmpty(a11,{op(a12),p},ord)); 
end: 

########约束多项式conspolyset形式:[[{a11},{a12}],[{a21},{a22}]]##
UnAmbiguous:=proc(conspolyset,var_para::list,term_order) 
local p,vp,result,a11,a12,a21,a22,newa11,newa22,lc,vars,paras,reduct; 

vars:=var_para[1]; 
paras:=var_para[2]; 

a11:=conspolyset[1][1]; 
a12:=conspolyset[1][2]; 
a21:=conspolyset[2][1]; 
a22:=conspolyset[2][2]; 
if a22={} then RETURN ({conspolyset}); fi; 

p:=a22[1]; 
newa22:=a22 minus {p};

if nops(a21) <>0 then p:=numer(normalf(p,a21,term_order(op(vars)))); fi;

##########AAA
if (_field_characteristic_ <>0 )	then p :=expand(p) mod _field_characteristic_ fi;

if nops(a11) <>0 then p:=numer(normalf(p,a11,term_order(op(paras)))); fi;

if (_field_characteristic_ <>0 )	then p :=expand(p) mod _field_characteristic_ fi;


#########如果p是0多项式############ 
if p=0 then  result:=UnAmbiguous([[a11,a12],[a21,newa22]],var_para,term_order);  RETURN(result); fi; 

##########如果p是非0常数##############   
if (p <> 0) and ( type(p,'constant') ) then RETURN ( {[conspolyset[1],[{1},{} ]  ]}); fi; 

#lprint("p="); #lprint(p);  
lc:=leadcoeff(p,term_order(op(vars))); 
#lprint("lc="); #lprint(lc);
reduct:=expand(p-lc*leadterm(p,term_order(op(vars)))); 
vp:=indets(p); 
    
#######如果p含有变元############   
 if (vp intersect {op(vars)}) <> {} then 
     if(type(lc,'constant')=true) then 
        result:=UnAmbiguous([[a11,a12],[a21 union {p}, newa22]],var_para,term_order); 

     elif NotZeroUnderCons(a11,a12,lc,paras) 
         then result:=UnAmbiguous([[a11,a12],[a21 union {p}, newa22]],var_para,term_order); 
             
     elif IsZeroUnderCons(a11,a12,lc,paras) 
         then result:=UnAmbiguous([[a11,a12],[a21,newa22 union {reduct}]],var_para,term_order); 
           
     else         
         lc:=CutNozeroFactors(lc,a12); 
         newa11:=CutPolyByFactor(a11,lc);
         result:=UnAmbiguous([[{op(newa11),lc},a12],[a21,newa22 union {reduct}]],var_para,term_order) 
               union UnAmbiguous([[a11,a12 union FactorList(lc)],[a21 union {p}, newa22]],var_para,term_order); 
                 
     fi; 
 else 

#######如果p不含变元,只含参数############   
##modify 
     if NotZeroUnderCons(a11,a12,p,paras) then result:={[conspolyset[1],[{1},{} ]]}; 
     elif IsZeroUnderCons(a11,a12,p,paras) then result:=UnAmbiguous([[a11,a12],[a21,newa22]],var_para,term_order) ;           
        
     else 
          lc:=CutNozeroFactors(lc,a12);  
          newa11:=CutPolyByFactor(a11,lc);    
          result:=UnAmbiguous([[{op(newa11),lc},a12],[a21,newa22]],var_para,term_order) 
                  union UnAmbiguous([[a11,a12 union FactorList(lc)],[{1}, {}]],var_para,term_order); 
     fi; 
 fi; 

result: 
end: 






######pol对list1中的多项式逐个做除法,返回商#######
DivideList:=proc(pol,list1)
local i,q,rt;
   rt:=pol;
   for i in list1 do
      if divide(rt,i,'q') then   rt:=q; fi;
   od;
   rt;
end:

###<1>list1中的多项式已不可约
###<2>去掉pol中在list1里列出的因子且忽略重数
CutNozeroFactors:=proc(pol,list1)
local i,q,sqf_pol,rt;
   sqf_pol:=sqrfree(pol);
   sqf_pol:=sqf_pol[2];
   for i from 1 to nops(sqf_pol) do
      sqf_pol[i][1]:=DivideList(sqf_pol[i][1],list1);
   od;
   rt:=1;
   for i from 1 to nops(sqf_pol) do
      rt:=rt*(sqf_pol[i][1]);
   od;
   rt;
end:      

###去掉list1中以pol为因子的多项式
CutPolyByFactor:=proc(list1,pol)
local p,rt,q;
    rt:={};
    for p in list1 do
       if not divide(p,pol,'q') then rt:={op(rt),p};fi;
    od;
rt; 
end:     



##<1>通过gb对等于零的约束部分做normalform来化简
##<2>因为gb的首系数一定不为零,通过对gb做primpart来化简
SimplifyConsgb:=proc(consgb,var_para,term_order)
local rt,i,temp,paras,vars;
    vars:=var_para[1];
    paras:=var_para[2];
    rt:={};
    for i in consgb do
        temp:=map(normalf,i[2],i[1][1],term_order(op(paras)));
        temp:=map(primpart,map(numer,temp),vars);        
        rt:={op(rt),[i[1],temp]};
    od;
    rt;
end:


FactorList:=proc(pol) 
local i,list1,list2; 
  list1 := factors(pol)[2]; 
  list2 := {}; 
  for i in list1 do  list2 := {op(list2),i[1]}; od; 
  list2 
end: 
 

#######如果p在constrain的条件下为0在返回1,np=0 
#######如果p在constrain的条件下为非0的常数返回10,np=10  
#######如果p在constrain的条件下首项系数一定不是0则返回-1 
#######其他情形返回0。np=pol 
########paracons=[ [part=0 ],[part <>0]] 是参数的约束; 

nonzerolc:=proc(pol,paracons,var_para,np,term_order) 
local lc,vars,paras,cons1,cons2,np0,t,pol2; 
global _field_characteristic_ ;
    vars:=var_para[1]; 
    paras:=var_para[2]; 
    cons1:=paracons[1]; 
    cons2:=paracons[2];
    lc:=leadcoeff(pol,term_order(op(vars))); 
    if pol=0 then np:=0; RETURN(1); fi; 
    if type(pol,'constant') then np:=10; RETURN(10); fi;       
    if type(lc,'constant') then np:=pol; RETURN(-1); fi; 
     
    
    ##########lc在约束下一定为0#######   
    if IsZeroUnderCons(cons1,cons2,lc,paras) then 
         pol2:=reductum(pol,term_order(op(vars))); 
         if (_field_characteristic_ <>0  ) then pol2:=pol2 mod _field_characteristic_ fi;
         t:=nonzerolc(pol2,paracons,var_para,'np0',term_order); 
         np:=np0; 
         RETURN(t); 
          
   ##########lc在约束下一定不为0####### 
    elif NotZeroUnderCons(cons1,cons2,lc,paras) then  
         if lc=pol then np:=10; RETURN(10);
         else  np:=pol;  RETURN(-1);
         fi; 
    
    else 
        np:=pol; 
        RETURN(0); 
    fi; 
end: 

reductum:=proc(p,ord) 
local res; 
    expand(p-leadcoeff(p,ord)*leadterm(p,ord)); 
end:       

gb:=proc(ps,var_para,term_order) 
local res; 
  res:=gb0([[{},{}],[{},{op(ps)}]],var_para,term_order); 
  res:=SimplifyConsgb(res,var_para,term_order);
end:   



gb0:=proc(conspolyset,var_para,term_order) 
local i,branches, res,temp; 
   res:={}; 
   branches:=UnAmbiguous(conspolyset,var_para,term_order); 
   for i in branches do 
        temp:=gb1(i,var_para,term_order);
        res:=res union temp; 
   od; 
   res; 
end:   

#################Step 1######################## 
gb1:=proc(conspolyset,var_para,term_order) 
local i,j,T,paracons,pset,pset0,pset1,pol,pset3,l,nonzerosp,sp,bs2,vars,newpol,cr,nf,np; 
global _field_characteristic_;
	T:={}; 
	vars:=var_para[1]; 
	paracons:=conspolyset[1];
	pset:=conspolyset[2][1]; 
	  
	pset0:=pset; 
	pset1:={}; 
	  
	if nops(pset)=0 then  RETURN({[paracons,[0]]}) fi; 
	  
	if  nops(pset) =1 then     RETURN({[paracons,[op(pset)]]}) fi; 
	
	#################Step 2-----  Normalization------#####################             
	for i in pset do 
	       pset0:=pset0 minus {i}; 
	       nf:=normalf(i,pset0 union pset1,term_order(op(vars))); 
	       pol:=expand(numer(nf )); 
	       cr:=nonzerolc(pol,paracons,var_para,'newpol',term_order); 
	       
	       newpol:=numer(normalf(newpol,pset0 union pset1,term_order(op(vars))));

	       if (_field_characteristic_ <>0 )	then newpol :=expand(newpol) mod _field_characteristic_ fi;
	       #lprint("newpol=");#lprint(newpol);
	       if cr=1 then ; 
	       elif cr=10 then RETURN( { [paracons,[1]] }); 
	       elif cr=-1 then if   newpol <>0 then pset1:=pset1 union {newpol} fi; 
	       else 
	          pset3:=[paracons,[ pset0 union pset1 ,{newpol} ]]; 
	          RETURN( gb0(pset3,var_para,term_order) ); 
	        fi;                       
	od; 
	
	##############Step 3-----  S-polynomial------#################################### 
	l:=nops(pset1); 
	if  l=1 then RETURN( {[paracons,[op(pset1)]] }) fi; 
	
	nonzerosp:={}; 
	for i to l do 
	    for j from i+1 to l do 
	       sp:=expand(numer(normalf(spoly(pset1[i],pset1[j],term_order(op(vars))),pset1,term_order(op(vars))))); 
	       if( _field_characteristic_ <>0) then sp:= expand(sp) mod _field_characteristic_ fi;
	       	      #lprint("sp="); #lprint(sp);
	       if (nonzerolc(sp,paracons,var_para,'np',term_order)<>1) then  nonzerosp:=nonzerosp union {np} fi; 
	    od; 
	od; 
	
	if nonzerosp={} then RETURN( {[paracons,inter_reduce([op(pset1)],term_order(op(vars)) )] } ) ; 
	else 
	         bs2:=[paracons,[{op(pset1)},nonzerosp ]]; 
	         T:=T union gb0(bs2,var_para,term_order); 
	fi; 

	T: 
end:


#############################
###   solution number    ####
#############################

basis:=proc(a,b,ord)
local i,j,k1,k;k:={};
for i in a do
   k1:=normalf(i,b,ord);
   if(k1<>0) then 
     k:=k union {k1};
   end if;  
end do;
return k;
end:   

mulset:=proc(a,b)
local i,j,k;
k:={};
if b={} then return a; fi;
for i in a do
  for j in b do
     k:=k union {i*j};
  od;
od;
return k;
end:    

create:=proc(a,b,num)
local i,j,k,k1,b1;

b1:=b union {1}; 
k1:=b1 union mulset(a,b1);
if num=0 then return k1;fi;
  k:=create(a,k1,num-1);

end:    

havefinitesolution:=proc(l,var)
local i,lvs,lv1;
lv1:={};
for i in l do
   lvs:=indets(i) intersect {op(var)};
   if nops(lvs)=1 then lv1:=lv1 union lvs; fi;
od;

if ({op(var)} minus lv1 )={}  then return true;
else return false;
fi;
end: 
 
  
comp:=proc(a,b)
local i,j,k,l;k:={};
for i in b do
  for j in a do
     if j=i then   
        k:=k union {j};
     fi;
   od;     
od;
return k;
end:   

getmostdegree:=proc(l)
local i,j,k1,k2;
k2:={};
k1:={};
for i in l do 
  k1:={op(i)};
  for j in k1 do
    k2:=k2 union {op(j)};
  od;
od;    
return k2;
end:

ltt:=proc(l,vorder)
 local i,k;
 k:={};
 for i to nops(l) do
 k:={leadterm(l[i],vorder)} union k;
 end do;
 return k;
 end:

GetDim:=proc(lts,vars)
local i,branch,l,rt;
rt:=nops(lts);
branch:=Nrs(lts,[op(vars)],{});
branch:=[op(branch)];
for i to nops(branch) do
   l:=nops(branch[i]);
   if l<rt then rt:=l;fi;
 od;
 return nops(vars)-rt;
 end:


##for reduced groebner basis
sumofdegree:=proc(lts)
local i,rt;
rt:=0;
for i in lts do
   if nops(indets(i))=1 then
       rt:=rt+degree(i);
   fi;
od;
return rt;
end: 

solution1:=proc(ps,ord,term_order)
local i,j,k,cgb,lt,mosttotaldeg,dim;
cgb:=gb(ps,ord,term_order);
cgb:=[op(cgb)];
for i to nops(cgb) do
  lt:=ltt(cgb[i][2],term_order(op(ord[1])));
  if  havefinitesolution(lt,ord[1]) then
    mosttotaldeg:=sumofdegree(lt); 
    k:=basis(create({op(ord[1])},{},mosttotaldeg),lt,term_order(op(ord[1])));
    cgb[i]:=[op(cgb[i]),k,cat("finite solution with number: ", nops(k))];

  elif cgb[i][2]=[1] then cgb[i]:=[op(cgb[i]),"no solution"];
  elif cgb[i][2]=[0] then cgb[i]:=[op(cgb[i]),cat("infinite solution with dimension: ",nops(ord[1]))];
  else 
       dim:=GetDim(lt,ord[1]);
       cgb[i]:=[op(cgb[i]),[lt],cat("infinite solution with dimension: ", dim)];
  fi;
od;
return {op(cgb)};
end:


##第4个参数可省,如果有,必须加单引号!
solution:=proc(ps,ord,term_order,pgb)
local i,j,k,cgb,lt,mosttotaldeg,dim;
cgb:=gb(ps,ord,term_order);
cgb:=[op(cgb)];
if nargs=4 then pgb:={op(cgb)};fi;
for i to nops(cgb) do
  lt:=ltt(cgb[i][2],term_order(op(ord[1])));
  if  havefinitesolution(lt,ord[1]) then
    mosttotaldeg:=sumofdegree(lt); 
    k:=basis(create({op(ord[1])},{},mosttotaldeg),lt,term_order(op(ord[1])));
    cgb[i][2]:=cat("finite solution with number: ", nops(k)); 
  elif cgb[i][2]=[1] then cgb[i][2]:="no solution";
  elif cgb[i][2]=[0] then cgb[i][2]:=cat("infinite solution with dimension: ",nops(ord[1]));
  else 
       dim:=GetDim(lt,ord[1]);
       cgb[i][2]:= cat("infinite solution with dimension: ", dim);
  fi;
od;
{op(cgb)};
end:

FindRightGB:=proc(paragb)
local gb,pgb,rt,i,j;
j:=0;
pgb:=[op(paragb)];
for i to nops(pgb) do
   gb:=pgb[i];
   if nops(gb[1][1])=0 then gb[1][1]:={0} fi;
    if nops(gb[1][2])=0 then gb[1][2]:={1} fi;
   if {op(gb[1][1])}={0} and (gb[1][2] intersect {0})<>{0} then 
           j:=j+1;
           rt:=gb[2];
   fi;
od;
if j<>1 then print("ambiguous occur!");fi;
rt;
end:

EvalAll:=proc(op,vars,vals)
local i,rt;
rt:=op;
for i to nops(vars) do
    rt:=eval(rt,vars[i]=vals[i]);
od;
rt;
end:


#把ps中的多项式设成首项系数为1
SetLC1:=proc(ps)
local i,p,rt;
rt:={};
for i to nops(ps) do 
    p:=expand(ps[i]);
    if p=0 then rt:={op(rt),p};
    else
         p:=p/lcoeff(p);   
         rt:={op(rt),p};
    fi;
od;
rt;
end:


###检验约束groebnerbasis程序的正确性  
check:=proc(paravalue,paragb,ps,ord,term_order)
local i,gb,gb1,spec_paragb,spec_ps;
if nops(paravalue)<>nops(ord[2]) then return "Error in parameter assignment: parameter number is NOT matched!" fi;   

spec_ps:=EvalAll(ps,ord[2],paravalue);
spec_ps:={op(spec_ps)} minus {0};
 spec_ps:=[op(spec_ps)];
gb1:=gbasis(spec_ps,term_order(op(ord[1])));

spec_paragb:=EvalAll(paragb,ord[2],paravalue);
gb:=FindRightGB(spec_paragb);

if SetLC1(gb)=SetLC1(gb1) then print( "two results are the same polynomial set!");
else print("two results are NOT the same polynomial set!");
fi;

print("greobner basis gotten by parameter assignment at begin:");
print(gb1);

print("greobner basis gotten by CGB method:");
gb;

end:


########  例子 ######################
#参数:
#ps:=[a*x^2-b*x,b*y^2-c*x,c*z^2-a*x+b];
#ord:=[[x,y,z],[a,b,c]];
#termord:=tdeg;
#'pgb'; 是一个变量名,该参数可缺省

#调用1:
#gb(ps,ord,termord)
#返回:
#ps的约束GroebnerBasis

#调用2:
#solution(ps,ord,termord,'pgb'); 
#返回:
#ps的不同约束下解的个数。
#pgb为ps的约束GroebnerBasis

#调用3:
#solution1(ps,ord,termord); 
#返回:
#ps的约束GroebnerBasis及相应解的个数(若有限,还列出不属于首理想的单项式)。

#参数:
#paraval:=[1,2,3]; 是参数[a,b,c]的特定值
#pgb; ps的约束GroebnerBasis

#调用4:
# check(paraval,pgb,ps,ord,termord); 
#该函数比较pgb在特定参数值paraval下的GroebnerBasis与先对参数取值后再求的GroebnerBasis是否相同。
#同时也列出这两个GroebnerBasis。此函数可做为全文的测试函数。
#返回:
#pgb在特定参数值paraval下的GroebnerBasis


###########################################################################################
###########################################################################################
############## computing partioned-parametric Grobner basis 2005.11.4 #####################
############## END END END END END END END END END END END END END END#####################
###########################################################################################
###########################################################################################
###########################################################################################


########################for computing the projection of quasi-variety 2005.11.4###############
###  read "wsolve.txt" firstly  ### 
if not type(wsolve,procedure) then 
#lprint(" Warning: please read 'wsolve.txt' firstly ! "):
fi:

##-----main function------------------------------------------------
##Project(ps,ds,ord,pord) //old main function
##Sproject(result_of_project,pord) //no component is redundant 
##Example:  [[ASC,[a,b]],...] == (ASC=0 and a*b<>0 ) or ...

##Proj(ps,ds,ord,pord)  //new main function 
##Sproj(result_of_project,pord)  //no component is redundant 
##Example: [[ASC,[a,b]],...] == (ASC=0 and ( a<>0 or b<>0) ) or ...
##-------------------------------------------------------------------


#-----------Part1------<algebraic case>---------------
#         project(ps,ds,ord,pord)
#         ord:= all variables (descending order list)
#         pord:=variables to eliminate (as above)
#-----------------------------------------------------
#QV (QuasiVariety) ; ASC (ascendant characteristic set)

# get the product of the initials of cs

Mainvar := proc(f,ord)
                  local i;
                  options remember,system;
                      for i to nops(ord) do
                          if has(f,ord[i]) then RETURN(ord[i]) fi
                      od;
                      #lprint(`Warning: lvar is called with constant`);
                      0
                  end:

GetIP:=proc(cs,ord)
	local i,rt;
	rt:=1;
	for i from 1 to nops(cs) do
		rt:=rt*Initial(cs[i],ord);
	od;
	rt;
end:

# get the product of the polys in ds.
GetProduct:=proc(ds)
	local jds,d;
	jds:=1;
	for d in ds do
		jds:=jds*d;
		od;
	jds;
end:

#get the union of two lists, denoted as list also.
ListUnion:=proc(list1,list2)
	local rt;
	rt:={op(list1)} union {op(list2)};
	rt:=[op(rt)];
end:

# inverse a list
Inverse:=proc(lis)
    local i,result;
    result:=[];
    for i from nops(lis)  to 1 by -1
        do result:=[op(result),lis[i]];
        od;
    result;
end:     

# inverse every list in a list.
InverseAll:=proc(lislis)
	local rt,l;
	rt:=[];
	for l in lislis do
		rt:=[op(rt),Inverse(l)];
	od;
end:

# eliminate such ASC in cslist that Premas(jds,ASC,ord)=0
Newcslist:=proc(cslist,jds,ord)
	local rt,cs;
	rt:=[];
	for cs in cslist do
	        if Premas(jds,cs,ord)<>0
	        	then rt:=[op(rt),cs]                               
	        fi;
	        od;
        rt;
end:

# factors of a polynomial w.r.t ord; 
# facts(x^2*y+x*y-x,[x,y]); [x,x*y+y-1]
# facts(x^2*y+x*y-x,[y]); [x*y+y-1]
# facts(x^2*y+x*y-x,[u,v,w]); []
Ordfacts:=proc(pol,ord)
   local i,temp,facl,result;
   if type(pol,polynom) then	  
	   result:=[];
	   facl:=factors(pol);
	   facl:=facl[2];
	   if facl=[] then RETURN([]) fi;
	   for i from 1 to nops(facl)
	       do temp:=facl[i];
	          if dClass(temp[1],ord)<>0 then
	          result:=[op(result),temp[1]];
	          fi;
	       od;
	   RETURN(result);
   else  
         #lprint(`Warning: facts is called with no polynomial`);
	 RETURN(pol);
   fi;  
end:  

# put p to proper position in notzerolist s.t. MV(ASC[i-1])<=MV(p)<MV(ASC[i])
PutToNotZero:=proc(p,notzerolist,mvl,ord)
	local i,cp,rt;
	rt:=notzerolist;
	cp:=Class(p,ord);	
	if cp=0 then RETURN(rt);fi;
	for i from 1 to nops(mvl) do 
		if cp<mvl[i] then rt:=subsop(i=rt[i]*p,rt);break;
		fi; 
	od;
	i;
        if i=nops(mvl)+1 then 
        	rt:=subsop(-1=rt[-1]*p,rt) ;
        fi;
        rt;
end:	

# all factors(noted fpolys) of polys in ds and initials, 
# notzerolist[i]= the product of p, 
# s.t. <1> p in fpolys and <2> MV(ASC[i-1])<=MV(p)<MV(ASC[i])       
CreatNotZeroList:=proc(cs,ds,mvl,ord)
	local i,fs,p,notzerolist;
	
	notzerolist:=[];
	for i from 0 to nops(cs) do
  	     notzerolist:=[op(notzerolist),1];
	od;
	
	fs:=[];
	for p in ds do
		fs:=ListUnion(fs,Ordfacts(p,ord));
		od;
	for p in fs do
		notzerolist:=PutToNotZero(p,notzerolist,mvl,ord);
		od;
	notzerolist;
end:

#a front part of ASC whose polynomials contain no variables in pord     
SubASC:=proc(asc,pord)
   local i, result;
   result:=[];
   for i from 1 to nops(asc)
       do if Class(asc[i],pord)=0 
             then result:=[op(result),asc[i]];
          else break;          
          fi;
       od;
   RETURN(result);
end:     

#judge the result of ProjectASC
#if it is [[...],1] return 1;
#if it is [[...],0] return 0;
#else return 3;
IsTrival:=proc(qv,ord)
	local rt;
	if nops(qv)<>2 then rt:=3;
	elif not type(qv[2],polynom) then rt:=3;
	elif Class(qv[2],ord)<>0 then rt:=3;
	elif qv[2]=0 then rt:=0;
	else rt:=1;
	fi;  
	RETURN(rt);
end:

# get variables of pol which are of higher order then the highest
# polynomial in asc. 
HigherOrdVars:=proc(pol,mvl,len,ord)
	local vl,rt,var,index;
	vl:=indets(pol) intersect {op(pord)};
	rt:=[];
	if len<=1 then RETURN(rt);fi;
	for var in vl do
		index:=Class(var,ord);
		if index>mvl[len-1] then
			rt:=[op(rt),var];
		fi;
	od;
	rt;
end:

# decompose the pol in [[ASC],pol] to ['UN',[[ASC],pol1],...]
# so as to eliminate variables in varl.  
DecompList:=proc(qv,subasc,notzerolist,varList,ord)
	local i,flag,lenasc,rt,pol,coeffsList,coeff;
	if varList=[] then RETURN(qv);fi;
	pol:=qv[2];
	
	if pol=0 then rt:=[subasc,pol]; 
	else 
		flag:=0; 
		lenasc:=nops(qv[1]);
		for i from 1 to lenasc do
			if notzerolist[i]!=1 then flag:=1; break;fi;
		od;
		coeffsList:=[coeffs(expand(pol),varList)];
		if nops(coeffsList)>1 then rt:=["UN"];
		else rt:=[]; 
		fi;
		for coeff in coeffsList do
			if Class(coeff,ord)=0 and flag=0 then 
				RETURN([subasc,1]);				
			else
				rt:=[op(rt),[qv[1],coeff]];
			fi;
		od;		
	fi;
        if nops(rt)=1 then rt:=rt[1];fi;
        rt;
end:


#when ASC has no variables in varl . 
# decompose the pol in [[ASC],pol] to ['UN',[[ASC],pol1],...]
# so as to eliminate variables in varl 
DecompList1:=proc(qv,subasc,notzerolist,varList,ord)
	local i,flag,lenasc,rt,pol,coeffsList,coeff;
	if varList=[] then RETURN(qv);fi;
	pol:=qv[2];
	
	if pol=0 then rt:=[subasc,pol]; 
	else 
		flag:=1; 
		lenasc:=nops(qv[1]);
		for i from 1 to lenasc do
			flag:=flag*notzerolist[i] ; 
		od;
		
		coeffsList:=[coeffs(expand(pol),varList)];
		if nops(coeffsList)>1 then rt:=["UN"];
		else rt:=[]; 
		fi;
		for coeff in coeffsList do
			if Class(coeff,ord)=0 and flag=1 then 
				RETURN([subasc,1]);				
			else
				rt:=[op(rt),[qv[1],coeff*flag]];
			fi;
		od;		
	fi;
        if nops(rt)=1 then rt:=rt[1];fi;
        rt;
end:


#  eliminate the highest polynomial in ASC, within [[ASC],pol] 
ElimPoly:=proc(qv,notzerolist,mvl,subasc,ord,pord)
	local rt,newasc,asc,pol,hPol,hVar,hDeg,rem,newPol,tempList,varList,len;
	asc:=qv[1];
	len:=nops(asc);
	newasc:=subsop(len=NULL,asc);
	pol:=qv[2];
	hPol:=asc[len];
	hVar:=Mainvar(hPol,ord);
	hDeg:=degree(hPol,hVar);
	if degree(pol,hVar)=0 then 
		rt:=[newasc,pol*notzerolist[len]];
		RETURN(rt);
	else
		rem:=sprem(pol^hDeg,hPol,hVar);
		if rem=0 then 
			rt:=[subasc,0];
			RETURN(rt);			
		fi; 
		newPol:=rem*notzerolist[len];
		tempList:=[newasc,newPol];
		varList:=HigherOrdVars(newPol,mvl,len,ord,pord);	
		rt:=DecompList(tempList,subasc,notzerolist,varList,ord);
		RETURN(rt);
	fi;
end:

# project wth one QV formed by one ASC(prepair share done by ProjASC)
ProjectASC:=proc(qv,notzerolist,mvl,subasc,lensub,ord,pord)
	local pol,asc,nproj,tempList,sign,rt,nozero,i;
	pol:=qv[2];
	asc:=qv[1];
	
#  get the nonzero polynomial to prject with here.    
	nozero:=pol;
	for i from 1 to nops(asc) do
		nozero:=nozero*notzerolist[i];
		od;

#  recursion ending conditions		
	if nops(asc)=0 or nops(asc)=lensub then
		if Class(nozero,pord)>0 then 
			rt:=DecompList1(qv,subasc,notzerolist,pord,ord);
		elif Class(nozero,ord)>0 then 
			rt:=[asc,nozero];
		else 
			rt:=[asc,Get1or0(nozero)];
		fi;
		RETURN(rt);
	elif Class(nozero,pord)=0 then
		if Class(nozero,ord)>0 then rt:=[subasc,nozero];
		else 
			rt:=[subasc,Get1or0(nozero)];
		fi;
		RETURN(rt);
	fi;
	
#  eliminate the highest polynomial in asc of QV.
	tempList:=ElimPoly(qv,notzerolist,mvl,subasc,ord,pord);
	
	# whether have many branchs in the result of ElimPoly.
	if not type(tempList[1],string) then 
		rt:=ProjectASC(tempList,notzerolist,mvl,subasc,lensub,ord,pord);
	else 
		rt:=[tempList[1]];
		for i from 2 to nops(tempList) do
			nproj:=ProjectASC(tempList[i],notzerolist,mvl,subasc,lensub,ord,pord);
			
			# deal with trival cases.
			sign:=IsTrival(nproj,ord);
			if sign=0 then next;
			elif sign=1 then rt:= [subasc,1];break;
			else rt:=[op(rt),nproj];
			fi;
		od:
		
		# rt:=["UN"]
		if nops(rt)=1 then rt:=[subasc,0]; fi;
		
		# rt:=["UN",[...]]
		if nops(rt)=2 and type(rt[2],list) then rt:=rt[2];fi;
	fi;
	rt;
end: 

# project with one QV formed by one ASC
ProjASC:=proc(cs,ds,ord,pord)
	local mvl,notzerolist,p,qv,subasc,lensub,rt;
	
	# mainvars order list
	mvl:=[];
	for p in cs do
	    mvl:=[op(mvl),Class(p,ord)];
	od;
	# notzerolist 
	notzerolist:=CreatNotZeroList(cs,ds,mvl,ord);
	
	qv:=[cs,notzerolist[-1]];
	subasc:=SubASC(cs,pord);
	lensub:=nops(subasc);
	rt:=ProjectASC(qv,notzerolist,mvl,subasc,lensub,ord,pord);
	rt:=Format1(rt);
end:
	

#whether input QuasiVariety is [[[],[1]]]
QVIsTruth:=proc(qv)
	if qv=[[[],[1]]] then RETURN(true);
	else RETURN(false);
	fi;
end:

#----main func.-------
# project with the QV [ps,ds], eliminate variables in pord
# return [] if zero(ps) is empty  
# return [[[],[0]]] if zero(ps/ds) is empty
# else return [  [[ASC],[p1,p2,...]]  , ...]
Project:=proc(ps,ds,ord,pord)
	local jds,cslist,cs,p,ini,qvs,newds,subasc,rt;
	jds:=GetProduct(ds);
	cslist:=wsolve(ps,ord);
	#printf("The characteristic sets are:");
	##lprint(cslist);
	rt:=[];
	if nops(cslist)<>0 then
		cslist:=Newcslist(cslist,jds,ord);  
		if nops(cslist)=0 then RETURN([]);
		fi;
		cslist:=InverseAll(cslist);
		for cs in cslist do
		        
		        #add initials to ds
		        newds:={op(ds)};
		        for p in cs do
				ini:=Initial(p,ord);
				if Class(ini,ord)>0 then
					newds:={op(newds),ini};
				fi;
			od;
			newds:=[op(newds)];
			
			qvs:=ProjASC(cs,newds,ord,pord);
 			subasc:=qvs[1][1];
		        qvs:=Simplify1(qvs,subasc,ord);
		        if QVIsTruth(qvs) then rt:=qvs; RETURN(rt); 
		        else  
		        	rt:=ListUnion(qvs,rt);
		        fi;
		od;
	fi;
	if nops(rt)=0 then RETURN([[[],[0]]]); fi;
	rt;
end:	        



## the subasc in qvs is the same one 
AddQVS:=proc(rt,qvs)
  local newrt,i,j,subasc;
  newrt:=rt;
  subasc:=qvs[1];
  j:=0;
  for i from 1 to nops(newrt) do
     if subasc=newrt[i][1] then newrt[i][2]:=ListUnion(qvs[2],newrt[i][2]); j:=1; break;fi;    
  od;
  if j=0 then newrt:=[op(newrt),qvs];fi;
  newrt;
end:

SqfreeList:=proc(plist)
   local j,p,q,rt,sq;
   rt:=[];
   for p in plist do
      j:=1;
      sq:=sqrfree(p);
      sq:=sq[2];
      for q in sq do
        j:=j*q[1];
      od;
      rt:=[op(rt),j];      
   od;
   rt;
end:


SqfreeGB:=proc(plist,ord)
local rt,gb1,gb2;
   gb1:=plist;
   gb2:=Groebner[gbasis](gb1,plex(op(ord)));
   gb2:=SqfreeList(gb2);
   while(gb1<>gb2) do
      gb1:=gb2;
      gb2:=Groebner[gbasis](gb1,plex(op(ord)));
      gb2:=SqfreeList(gb2);   
   od;
   gb2;
end:    

GBsimplify:=proc(qvs,ord)
local qv,rt;
   rt:=[];
   for qv in qvs do
       rt:=[op(rt),[qv[1],SqfreeGB(qv[2],ord) ] ];
   od;
   rt;
end:

Congre:=proc(qvs)
local rt,qv,notzero;
    notzero:=[];
    for qv in qvs do
        notzero:=[op(notzero),qv[2]];
     od;
     notzero:={op(notzero)};
     notzero:=[op(notzero)];
    rt:=[qvs[1][1],notzero];
end:

#new project
Proj:=proc(ps,ds,ord,pord)
	local jds,cslist,cs,p,ini,qvs,newds,subasc,rt;
	jds:=GetProduct(ds);
	cslist:=wsolve(ps,ord);
	#printf("The characteristic sets are:");
	##lprint(cslist);
	rt:=[];
	if nops(cslist)<>0 then
		cslist:=Newcslist(cslist,jds,ord);  
		if nops(cslist)=0 then RETURN("Characteristic Set is empty set");
		fi;
		cslist:=InverseAll(cslist);
		for cs in cslist do
		        
		        #add initials to ds
		        newds:={op(ds)};
		        for p in cs do
				ini:=Initial(p,ord);
				if Class(ini,ord)>0 then
					newds:={op(newds),ini};
				fi;
			od;
			newds:=[op(newds)];
			
			qvs:=ProjASC(cs,newds,ord,pord);
 			subasc:=qvs[1][1];
		        		        
		        qvs:=Simplify2(qvs,subasc,ord);
		        if qvs=[[[],1]] then RETURN([[[],[1]]]); 
		        else  
		              qvs:=Congre(qvs);
		              rt:=AddQVS(rt,qvs); 
		        fi;
		od;
	fi;
	if nops(rt)=0 then RETURN([[[],[0]]]); fi;	
	rt:=GBsimplify(rt,ord);
end:	        



# return 1 if zero(ps,ds)=empty 
# else return 0
IsEmpty:=proc(ps,ds,ord)
	local jds,cslist,cs,p,ini,qvs,newds,subasc;
	if nops(ps)=0 then RETURN(false);fi;
	jds:=GetProduct(ds);
	cslist:=wsolve(ps,ord);
	#printf("The characteristic sets are:");
	##lprint(cslist);
	if nops(cslist)<>0 then
		cslist:=Newcslist(cslist,jds,ord);  
		if nops(cslist)=0 then RETURN(true);
		fi;
		cslist:=InverseAll(cslist);
		for cs in cslist do
		        
		        #add initials to ds
		        newds:=ds;
		        for p in cs do
				ini:=Initial(p,ord);
				if Class(ini,ord)>0 then
					newds:=[op(ds),ini];
				fi;
			od;
			
			qvs:=ProjASC(cs,newds,ord,ord);
 			subasc:=qvs[1][1];
		        qvs:=Simplify1(qvs,subasc,ord);
		        if QVIsTruth(qvs) then RETURN(false);
		        fi;
		od;
	fi;
	RETURN(true)
end:	       

#return -1 if zero([ ps, [op(ds),p] ])=empty 
#return 1 if zero([ [op(ps),p],ds ])=empty
#else return 0
whichcase:=proc(ps0,ds0,p,ord)
        local ps,ds;
        ps:=[op(ps0)];
        ds:=[op(ds0)];
	if IsEmpty(ps,[op(ds),p],ord,ord) then RETURN(-1) fi;
	if IsEmpty([op(ps),p],ds,ord,ord) then RETURN(1) fi;	        
        RETURN(0);     
end:	   


#---------------- Format1(qvs)-----------------

#when the input is as:["UN",...]
#step1: formated all the branchs of "UN".
#step2: Union all the branchs.   
FormatUN:=proc(qvs)
	local i,temp,rt;
	rt:=[];
	for i from 2 to nops(qvs) do
		temp:=Format1(qvs[i]);
		rt:=ListUnion(rt,temp);
	od;
	rt;
end:               

# when the input is as:[[ASC],pol]
# output [[[ASC],pol]]
FormatList:=proc(qv)
	RETURN([qv]);
end:

# format the result of ProjectASC()
# to the form: [[[ASC],pol1],[[ASC],pol2],...];
Format1:=proc(qvs)
	local rt;
	if type(qvs[1],string) then
		rt:=FormatUN(qvs);
	else 
		rt:=FormatList(qvs);
	fi;
	rt;
end:


#-----------------Simplify1(qvs)---------------
#for every qausi variety in the result of Project() call doRem1
#for empty set , return []; the result form: [[[ASC],[p1,p2,...]],...]
#p1<>0 and p2<>0 and ...
Simplify1:=proc(qvs,subasc,ord)
	local qv,rt,newqv;
	rt:=[];
	for qv in qvs do
		newqv:=doRem1(qv,subasc,ord);
		if newqv<>[] then 
			if member(1,newqv[2]) then RETURN([[subasc,[1]]]);fi;
		fi;
		rt:=[op(rt),newqv];		
	od;
	rt;
end:

# a qausi variety is denoted as: [[asc],pol]
# rem=premas(pol,asc,ord)
# notZero:= all factors of rem of dClass w.r.t ord zero.  
# return [[asc], [notZero]]
doRem1:=proc(qv,subasc,ord)
	local pol,rem,notZero,rt;
	pol:=qv[2];
# modified   2003.3.21
#	if nops(subasc)=0 or Class(pol,ord)=0 then
#		if pol=0 then rt:=[];
#		else rt:=[subasc,[1]];
#		fi;
#		RETURN(rt);
#	fi;
	rem:=Premas(pol,Inverse(subasc),ord);
	if rem=0 then rt:=[];
	else 
		notZero:=Factorlist_chen(rem,ord);
		rt:=[subasc,notZero];
	fi;
	rt;
end:
#-----------------Simplify2(qvs)---------------
#for every qausi variety in the result of Project() call doRem2
#for empty set , return []; the result form: [[[ASC],[p1,p2,...]],...]
#p1<>0 or p2<>0 or ...

#for every qausi variety in the result of Project() call doRem
#for empty set , return []; the result form: [[[ASC],[p1,p2,...]],...]
Simplify2:=proc(qvs,subasc,ord)
	local qv,rt,newqv;
	rt:=[];
	for qv in qvs do
		newqv:=doRem2(qv,subasc,ord);
		if newqv<>[] then 
			if newqv[2]=1 then RETURN([[subasc,1]]);fi;
		fi;
		rt:=[op(rt),newqv];		
	od;
	rt;
end:

# a qausi variety is denoted as: [[asc],pol]
# rem=premas(pol,asc,ord)
# return [[asc], rem]
doRem2:=proc(qv,subasc,ord)
	local pol,rem,notZero,rt;
	pol:=qv[2];

	rem:=Premas(pol,Inverse(subasc),ord);
	if rem=0 then rt:=[];
	else 
	        notZero:=Factorlist_chen(rem,ord);
		rt:=[subasc,GetProduct(notZero)];
	fi;
	rt;
end:


# if 0 return 0 else return 1
Get1or0:=proc(p)
	local rt;
	if p=0 then rt:=0;
	else rt:=1;
	fi;
	rt;
end:


# p=3*(x+y)^2*(x-y)*u; ord=[x,y]; result=[x+y,x-y];
# p=2; result=[1]; p=0; result=[0]
Factorlist_chen:=proc(p,ord)
	local i,j,fl,pair,fact,rt;
	if Class(p,ord)=0 then rt:=[Get1or0(p)];
	else 
		rt:=[];
		fl:=factors(p);
		fl:=fl[2];
		for pair in fl do
			fact:=pair[1];
			if Class(fact,ord)<>0 then 
				rt:=[op(rt),fact];	
			fi;
		od;
	fi;
	rt;
end:

#########----------Simplify----------###########       


###----- computation of QV---------- ############


# judge whether or not Zero(ps/ds) is empty


# judge whether or not Zero(ps1/ds1) is included in Zero(ps2/ds2)
# QVInclude:=proc(ps1,ds1,ps2,ds2)


#------Simplify the output of Project--------# 
# whether or not QV is included in the union of QVS
# output: 1(yes), 0(not included)
QVSInclude:=proc(QV,QVS,ord)
	local D,newQVS,rt,temp,i,ass,proj,ps,ds,newucs;
	#if QVS=[] then return 0;fi;
	D:=GetProduct(QV[2]);
	newQVS:=QVS;
	for i from 1 to nops(QVS) do 
		newQVS[i]:=[op(newQVS[i][1]),GetProduct(newQVS[i][2])];		
	od;
	ass:=AllSorts(newQVS,ord);
	for i from 1 to nops(ass) do
		temp:=ass[i];
		ds:=[D,op(temp[2])];
		if temp[1]<>[] then 
			ps:=[op(QV[1]),op(temp[1])];
			proj:=Project(ps,ds,ord,ord);
			# case :not empty set 
			if proj<>[] and proj[1][2][1]<>0 then RETURN(0);fi;
		else 
			proj:=ProjASC(QV[1],ds,ord,ord); 
			# case: not empty set
		        if proj[1][2]<>0 then RETURN(0);fi;
		fi;
	od;
        RETURN(1);
end:

# if every QV in QVS is included in the union of the others
# then expunge it.
Sproject:=proc(QVS,ord)
	local i,rt,UQV,len;
	rt:=[];
	len:=nops(QVS);
	for i from 1 to len do
	        if i=len then UQV:=[]; fi;
		UQV:=QVS[i+1..len];
		UQV:=[op(rt),op(UQV)];
		if UQV=[] then rt:=[QVS[i]];break ;fi;
		if QVSInclude(QVS[i],UQV,ord)=0 then 
			rt:=[op(rt),QVS[i]];
		fi;
	od;
	rt;
end:

Sproj:=proc(qvs,ord)
	local temprt,rt, tempqvs,qv,nozerop;
	tempqvs:=[];
	#change to old form
	for qv in qvs do 
	   for nozerop in qv[2] do
	      tempqvs:=[op(tempqvs), [ qv[1],[nozerop] ] ];
	   od;
	od;
	temprt:=Sproject(tempqvs,ord);
	rt:=[];
	#return to new form
	for qv in temprt do
	    rt:=AddQVS(rt,qv);
	od;
	rt;
end:
	
#------Simplify the output of wsolve--------# 
#AllSort([[a1,a3],[c1,c2,c3]]);
#output:[ [[],[c1,a1]], [[],[c2,a1]], [[c3],[a1]], [[a3],[c1]],
#          [[a3],[c2]], [[c3,a3],[]] ]
AllSorts:=proc(lists,ord)
	local ls,C,ls_len,p,i,reculist,list,onesort,rt;
	
	rt:=[];
	ls:=lists[1];
	ls_len:=nops(lists[1]);
	
	C:=Class(ls[ls_len],ord);
	
	if nops(lists)=1 then
		for i from 1 to ls_len-1 do
			p:=[[],[ls[i]]];
			rt:=[op(rt),p ];
		od;
		if C<>0 then
			rt:=[op(rt),[[ls[ls_len]],[]]];
		fi;
		RETURN(rt); 
	fi;
	
	reculist:=AllSorts(subsop(1=NULL,lists),ord);
	
	for i from 1 to ls_len-1 do
		for list in reculist do
			onesort:=list;
			onesort[2]:=[op(onesort[2]),ls[i]];
			rt:=[op(rt),onesort];
		od;
	od;
	if C<>0 then
		for list in reculist do
				onesort:=list;
				onesort[1]:=[op(onesort[1]),ls[ls_len]];
				rt:=[op(rt),onesort];
			od;
	fi;	
	rt;
end:

# whether or not cs is included in the union of ucs
# output: 1(yes), 0(not included)
CSSInclude:=proc(cs,ucs,ord)
	local proj,IP,ass,rt,temp,i,ps,ds,newucs;
	if ucs=[] then return 0;fi;
	IP:=GetIP(cs,ord);
	newucs:=ucs;
	for i from 1 to nops(ucs) do 
		newucs[i]:=[op(newucs[i]),GetIP(newucs[i],ord)];		
	od;
	ass:=AllSorts(newucs,ord);
	for i from 1 to nops(ass) do
		temp:=ass[i];
		ds:=[IP,op(temp[2])];
		if temp[1]<>[] then 
			ps:=[op(cs),op(temp[1])];
			proj:=Project(ps,ds,ord,ord);
			# case :not empty set 
			if proj<>[] and proj[1][2][1]<>0 then RETURN(0);fi;
		else 
			proj:=ProjASC(cs,ds,ord,ord); 
			# case: not empty set
		        if proj[1][2]<>0 then RETURN(0);fi;
		fi;
	od;
        RETURN(1);
end:


# if every cs in css is included in the union of the others
# then expunge it.
Swsolve:=proc(css,ord)
	local i,rt,newcss,UCS,len;
	rt:=[];
	newcss:=InverseAll(css);
	len:=nops(newcss);
	for i from 1 to len do
		UCS:=newcss[i+1..len];
		UCS:=[op(rt),op(UCS)];
		if CSSInclude(newcss[i],UCS,ord)=0 then 
			rt:=[op(rt),newcss[i]];
		fi;
	od;
	InverseAll(rt);
end:


然后读入该文件:

read "wsolve.txt"

就可以使用wsolve()函数了


wsolve: A Maple Package for Solving System of Polynomial Equations

 

Please download wsolve if you need it.


help for wsolve :


FUNCTION: wsolve - prepare the given algebraic system for solving

CALLING SEQUENCE:
wsolve(F)
wsolve(F, X)
wsolve(F, X,nonzero)
e_val(F,X,nonzero)
charset(F,X)
od_wsolve(F,X) (zero decomposition for ordinary differential poly system)
pd_wsolve(F,X) (zero decomposition for partial differential poly system)

PARAMETERS:
F - set or list of polynomials in indeterminates X
X - list of indeterminates (not including parameters)
nonzero - set of polynomials in indeterminates X

SYNOPSIS:
- The command wsolve(F,X,nonzero) computes a collection of ascending sets
corresponding to F.

- First the system corresponding to F is subdivided by factorization.

- Then each subsystem is passed to a variant of Wu's algorithm which
factors all intermediate results.

- The result is a set of subsystems whose roots which are not the zeros of
the initials (leading coefficients to the main variable) are those of the 
original system but whose variables have been successively eliminated

- If desired the solveas(asord) function may then be applied to solve 
the subsystems

- If desired the simplifyas(as,ord,nonzero) function may then be applied 
to simplify the ascending set.

- The set nonzero may be used to prevent certain quantities from being con-
sidered in roots; however this may not stop all such solutions.


EXAMPLES:

>currentdir(): #返回当前路径,复制wsolve.txt到当前路径

>read "wsolve.txt": #读入吴方法的代码
> F := [x^2 - 2*x*z + 5, x*y^2 + y*z^3, 3*y^2 - 8*z^3]:
> wsolve(F,[z,y,x]);


{[z, y, x^2 + 5] 

[x^2-2*x*z+5, 3*y+8*x, 3*x^6-64*x^5+45*x^4+225*x^2+375]
}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
假设有如下三元二次方程组: $$ \begin{cases} ax^2+by^2+cz^2+2dxy+2eyz+2fxz+gx+hy+jz=k_1 \\ a'x^2+b'y^2+c'z^2+2d'xy+2e'yz+2f'xz+g'x+h'y+j'z=k_2 \\ a''x^2+b''y^2+c''z^2+2d''xy+2e''yz+2f''xz+g''x+h''y+j''z=k_3 \end{cases} $$ 其中 $a,b,c,d,e,f,g,h,j,k_1,k_2,k_3$ 都是已知数,而 $x,y,z$ 是待定系数,我们需要求 $x,y,z$ 的值。 在Maple中,可以使用`Solve`函数求此类方程组。首先将方程组转化为多项式形式,然后使用`Solve`函数求。具体步骤如下: 1. 将方程组转化为多项式形式,即将每个方程的左右两边分别相减,得到一个多项式。以第一个方程为例,得到多项式: $$ f_1(x,y,z)=ax^2+by^2+cz^2+2dxy+2eyz+2fxz+gx+hy+jz-k_1 $$ 同理,得到多项式 $f_2(x,y,z)$ 和 $f_3(x,y,z)$。 2. 使用 `Solve` 函数求多项式方程组代码如下: ```Maple Solve({f1(x,y,z)=0, f2(x,y,z)=0, f3(x,y,z)=0}, {x,y,z}) ``` 其中,`{f1(x,y,z)=0, f2(x,y,z)=0, f3(x,y,z)=0}` 是一个多项式方程组,`{x,y,z}` 是待求的未知数。执行此代码后,Maple会返回方程组,如果不存在或无法析,则会返回空集。 需要注意的是,如果方程组存在多个,那么Maple只会返回其中一组。如果需要求出所有,可以使用 `Roots` 函数。例如,以下代码可以求出方程组的所有: ```Maple Roots({f1(x,y,z)=0, f2(x,y,z)=0, f3(x,y,z)=0}, {x,y,z}) ``` 其中,`Roots` 函数可以求出多项式方程组的所有根。执行此代码后,Maple会返回一个集合,包含方程组的所有

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值