### Check the parameter space of CGS （1-4）###

with(PolynomialIdeals):

### 1.  CheckCGS:  to check the output of the CGS algorithm (i.e., Checkspace: verify whether the union of the partition for the parameter space by CGS algorithm is a whole parameter space) ##
## Input:  C --- a finite set of 3-tuples [E_i, N_i, G_i] such that {(V(E_i)\V(N_i), G_i)} constitutes a minimal comprehensive Groebner system (the output of the CGS algorithm)##
## Output:  false/true (if the union of all V(E_i)\V(N_i) are the whole parameter space, it is true)##

CheckCGS:=proc(C)  
 local Set,r; 

 Set:={seq([C[i][1],C[i][2]],i=1..nops(C))};
 r:=Checkspace(Set);
 
 return r;
 end proc:

### 2.  Checkspace: verify whether the union of the partition for the parameter space by CGS algorithm is a whole parameter space ##
## Input:  Set --- a set of 2-tuples [E_i, N_i] ( equality constraints E_i and inequality constraints N_i, where E_i and N_i are the sets of polynomials in the parameters) ##
## Output:  false/true (if the union of all V(E_i)\V(N_i) are the whole parameter space, it is true)##

Checkspace:=proc(Set)  
 local n,S1,Newset,r,p,t; 
 n:=nops(Set);
 S1:=Set;
 Newset:={};
 r:=false;

 for p in Set do  
     if op(p[2])=1 then 
        if p[1]={} then
           r:=true;
           return r;
        else
           S1:=S1 minus {p};
           Newset:={p[1]};  ## extrct the first branch satisfying that N_i is {1} ##
        fi;
        break;
     fi;
 od;
 
 t:=nops(S1)+1;

 while S1<>{} and t>nops(S1) do
       t:=nops(S1);
       Newset,S1,r:=ConUnion(Newset,S1);
       if r then 
          return r;
       fi;
 od;

 return r;
 end proc:


### 3. Iscontain: check whether a parameter branch [E_j, N_j] (the constructible set) can be merged with an algebraic set E_i or algebraic sets E_i,..,E_k, the idea is to compute the quotient of the radical ideal generated by E_j,N_j and the ideal generated by E_i ####
## Input:  q --- a 2-tuples [E_j, N_j] ##
##             Newset --- a set of  algebraic sets E_i##
## Output:  false/true ( if the quotient is 1, it is true, then V(E_j)\V(N_j) union V(E_i) union V(E_k) ....=V(E_j) union V(E_i) union V(E_k) ....##

Iscontain:=proc(q,Newset) 
local J,r1,i,K,G;
J := `<,>`(op(q[1]),op(q[2]));
J:=Simplify(PolynomialIdeals[Radical](J));
r1:=false;

for i in Newset do
    K := `<,>`(op(i));
    J:=Quotient(J, K);
    if 1 in J then 
       r1:=true;
       break;
    fi;
od;

return r1;
end proc:


### 4. ConUnion: find a parameter branch in a set of parameter branches {[E_j, N_j]} can be merged with some algebraic set and extract it as an algebraic set E_i ##
## Input:  A --- a set of  algebraic sets E_i  ##
##             B --- a set of parameter branches [E_j, N_j](the constructible set}) ##
## Output:  a set of algebraic sets, a set of parameter branches, and false/true ##

ConUnion:=proc(A,B)  
local Newset,S1,r,q,r1;
Newset:=A;
S1:=B;
r:=false;

for q in S1 do
    r1:=Iscontain(q,Newset);
    if r1 then
       if q[1]={} then 
          r:=true;
          return {},{},r;
       else
          S1:=S1 minus {q};
          Newset:=Newset union {q[1]};
       fi;
       break;
    fi;
od;

return Newset,S1,r;
end proc:

