// Reference : Henning Meyer, my boolean problem ( http://groups.google.com/group/sci.math.symbolic/browse_frm/thread/318369ef90df4358/ )

import jscl.math.Debug;
import jscl.math.Generic;
import jscl.math.Variable;
import jscl.math.polynomial.Basis;
import jscl.math.polynomial.Monomial;
static import jscl.math.Predef.*;

Debug.setOutputStream(System.out);

nlen=2;
int len=1<<(nlen-1);
n=vector("n",nlen);
a_=vector("a",1,len);
b_=vector("b",1,len);
m=vector("m",len);
a=vector("a",len);
b=vector("b",len);
t=vector("t",len);
v=new Vector();
for(i=0;i<nlen;i++) v.addElement(n[i].variableValue());
for(i=0;i<len;i++) v.addElement(a_[i].variableValue());
for(i=0;i<len;i++) v.addElement(b_[i].variableValue());
for(i=0;i<len;i++) v.addElement(m[i].variableValue());
for(i=0;i<len;i++) v.addElement(a[i].variableValue());
for(i=0;i<len;i++) v.addElement(b[i].variableValue());
for(i=0;i<len;i++) v.addElement(t[i].variableValue());
vars=new Variable[v.size()];
v.copyInto(vars);

nconstraint(n) {
        n_=vector("n",len);
        nc=integer("1");
        for(int i=0;i<nlen;i++) {
                int c=1-((n&(1<<i))>>i);
                nc=nc.multiply(n_[i].add(integer(String.valueOf(c))));
        }
        return nc;
}

ni=new Generic[len];
for(n=0;n<len;n++) ni[n]=nconstraint(n);

rightShift(a,i) {
        s=integer("0");
        for(int n=0;n<len;n++) {
                if(i<a.length-n) s=s.add(a[i+n].multiply(ni[n]));
        }
        return s;
}

leftShift(a,i) {
        s=integer("0");
        for(int n=0;n<len;n++) {
                if(i>=n) s=s.add(a[i-n].multiply(ni[n]));
        }
        return s;
}

v=new Vector();
for(i=0;i<len;i++) v.addElement(t[i].add(rightShift(a,i).add(b[i]).multiply(m[i])));
for(i=0;i<len;i++) v.addElement(a_[i].add(a[i].add(leftShift(t,i))));
for(i=0;i<len;i++) v.addElement(b_[i].add(b[i].add(t[i])));
eqs=new Generic[v.size()];
v.copyInto(eqs);
t=System.currentTimeMillis();
basis=Basis.compute(eqs,vars,Monomial.lexicographic,2,Basis.DEFINING_EQS);
t=System.currentTimeMillis()-t;
print(basis);
print(t);