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