001/*
002 * $Id: GroebnerSystem.java 5120 2015-02-16 22:46:51Z kredel $
003 */
004
005package edu.jas.application;
006
007
008import java.util.ArrayList;
009import java.util.HashSet;
010import java.util.List;
011import java.util.Set;
012
013import org.apache.log4j.Logger;
014
015import edu.jas.poly.PolynomialList;
016import edu.jas.poly.OrderedPolynomialList;
017import edu.jas.poly.GenPolynomial;
018import edu.jas.poly.GenPolynomialRing;
019import edu.jas.structure.GcdRingElem;
020
021
022/**
023 * Container for a Groebner system. 
024 * It contains a list of colored systems and a
025 * list of parametric polynomials representing the 
026 * corresponding comprehensive Groebner base.
027 * @param <C> coefficient type
028 */
029public class GroebnerSystem<C extends GcdRingElem<C>> {
030
031
032    private static final Logger logger = Logger.getLogger(GroebnerSystem.class);
033
034
035    private final boolean debug = logger.isDebugEnabled();
036
037
038    /**
039     * List of colored systems.
040     */
041    public final List<ColoredSystem<C>> list;
042
043
044    /**
045     * List of conditions for this Groebner system.
046     */
047    protected List<Condition<C>> conds;
048
049
050    /**
051     * Comprehensive Groebner base for this Groebner system.
052     */
053    protected PolynomialList<GenPolynomial<C>> cgb;
054
055
056    /**
057     * Constructor for a Groebner system.
058     * @param S a list of colored systems.
059     */
060    public GroebnerSystem(List<ColoredSystem<C>> S) {
061        this.list = S;
062        this.conds = null;
063        this.cgb = null;
064    }
065
066
067    /**
068     * Get the String representation.
069     * @see java.lang.Object#toString()
070     */
071    @Override
072    public String toString() {
073        StringBuffer sb = new StringBuffer("GroebnerSystem: \n");
074        boolean first = true;
075        for (ColoredSystem<C> cs : list) {
076            if ( first ) {
077               first = false;
078            } else {
079               sb.append("\n");
080            }
081            sb.append( cs.toString() );
082        }
083        sb.append("Conditions:\n");
084        first = true;
085        for ( Condition<C> cond : getConditions() ) {
086            if ( first ) {
087                first = false;
088            } else {
089                sb.append("\n");
090            }
091            sb.append( cond.toString() );
092        }
093        sb.append("\n");
094        if ( cgb == null ) {
095           sb.append("Comprehensive Groebner Base not jet computed\n");
096        } else {
097           sb.append("Comprehensive Groebner Base:\n");
098           first = true;
099           for ( GenPolynomial<GenPolynomial<C>> p : getCGB() ) {
100               if ( first ) {
101                  first = false;
102               } else {
103                  sb.append(",\n");
104               }
105               sb.append( p.toString() );
106           }
107           sb.append("\n");
108        }
109        return sb.toString();
110    }
111
112
113    /**
114     * Get the Script representation.
115     * @see edu.jas.structure.Element#toScript()
116     */
117    public String toScript() {
118        StringBuffer sb = new StringBuffer("GroebnerSystem: \n");
119        boolean first = true;
120        for (ColoredSystem<C> cs : list) {
121            if ( first ) {
122               first = false;
123            } else {
124               sb.append("\n");
125            }
126            sb.append( cs.toScript() );
127        }
128        sb.append("Conditions:\n");
129        first = true;
130        for ( Condition<C> cond : getConditions() ) {
131            if ( first ) {
132                first = false;
133            } else {
134                sb.append("\n");
135            }
136            sb.append( cond.toScript() );
137        }
138        sb.append("\n");
139        if ( cgb == null ) {
140           sb.append("Comprehensive Groebner Base not jet computed\n");
141        } else {
142           sb.append("Comprehensive Groebner Base:\n");
143           first = true;
144           for ( GenPolynomial<GenPolynomial<C>> p : getCGB() ) {
145               if ( first ) {
146                  first = false;
147               } else {
148                  sb.append(",\n");
149               }
150               sb.append( p.toScript() );
151           }
152           sb.append("\n");
153        }
154        return sb.toString();
155    }
156
157
158    /**
159     * Is this Groebner system equal to other.
160     * @param c other Groebner system.
161     * @return true, if this is equal to other, else false.
162     */
163    @Override
164    @SuppressWarnings("unchecked")
165    public boolean equals(Object c) {
166        GroebnerSystem<C> cs = null;
167        try {
168            cs = (GroebnerSystem<C>) c;
169        } catch (ClassCastException e) {
170            return false;
171        }
172        if (cs == null) {
173            return false;
174        }
175        boolean t = list.equals(cs.list);
176        return t;
177    }
178
179
180    /**
181     * Hash code for this colored system.
182     * @see java.lang.Object#hashCode()
183     */
184    @Override
185    public int hashCode() {
186        int h;
187        h = list.hashCode();
188        return h;
189    }
190
191
192    /**
193     * Check invariants. Check if all colored systems are determined and 
194     * all invariants are met.
195     * @return true, if all invariants are met, else false.
196     */
197    public boolean checkInvariant() {
198        for (ColoredSystem<C> s : list) {
199            if (!s.checkInvariant()) {
200                return false;
201            }
202        }
203        return true;
204    }
205
206
207    /**
208     * Is each colored system completely determined.
209     * @return true, if each ColoredSystem is determined, else false.
210     */
211    public boolean isDetermined() {
212        for (ColoredSystem<C> s : list) {
213            if (!s.isDetermined()) {
214                return false;
215            }
216        }
217        return true;
218    }
219
220
221    /**
222     * Get list of conditions determining this Groebner system. 
223     * @return list of determining conditions.
224     */
225    public List<Condition<C>> getConditions() {
226        if ( conds != null ) {
227           return conds;
228        }
229        List<Condition<C>> cd = new ArrayList<Condition<C>>( list.size() );
230        for (ColoredSystem<C> cs : list) {
231            cd.add(cs.condition);
232        }
233        conds = cd;
234        return conds;
235    }
236
237
238    /**
239     * Get comprehensive Groebner base. 
240     * @return the comprehensive Groebner base for this Groebner system.
241     */
242    public List<GenPolynomial<GenPolynomial<C>>> getCGB() {
243        if ( cgb != null ) {
244           return cgb.list;
245        }
246        // assure conditions are collected
247        List<Condition<C>> unused = getConditions();
248        if ( unused.isEmpty() ) { // use for findbugs
249            logger.info("unused is empty");
250        }
251        //System.out.println("unused ");
252        // combine for CGB
253        Set<GenPolynomial<GenPolynomial<C>>> Gs 
254           = new HashSet<GenPolynomial<GenPolynomial<C>>>();
255        for (ColoredSystem<C> cs : list) {
256            if (debug) {
257                if (!cs.isDetermined()) {
258                    System.out.println("not determined, cs = " + cs);
259                }
260                if (!cs.checkInvariant()) {
261                    System.out.println("not invariant, cs = " + cs);
262                }
263            }
264            for (ColorPolynomial<C> p : cs.list) {
265                GenPolynomial<GenPolynomial<C>> f = p.getPolynomial();
266                Gs.add(f);
267            }
268        }
269        List<GenPolynomial<GenPolynomial<C>>> G 
270            = new ArrayList<GenPolynomial<GenPolynomial<C>>>(Gs);
271        GenPolynomialRing<GenPolynomial<C>> ring = null;
272        if ( G.size() > 0 ) {
273           ring = G.get(0).ring;
274        }
275        cgb = new OrderedPolynomialList<GenPolynomial<C>>(ring,G);
276        return G;
277    }
278
279}