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.GenPolynomial;
017import edu.jas.structure.GcdRingElem;
018
019
020/**
021 * Container for a condition, a corresponding colored polynomial list and a
022 * Groebner base pair list.
023 * @param <C> coefficient type
024 */
025public class ColoredSystem<C extends GcdRingElem<C>> {
026
027
028    private static final Logger logger = LogManager.getLogger(ColoredSystem.class);
029
030
031    private static final boolean debug = logger.isDebugEnabled();
032
033
034    /**
035     * Condition determinig this colored system.
036     */
037    public final Condition<C> condition;
038
039
040    /**
041     * Colored polynomials of this system.
042     */
043    public final List<ColorPolynomial<C>> list;
044
045
046    /**
047     * Groebner base pair list of this system.
048     */
049    public final OrderedCPairlist<C> pairlist;
050
051
052    /**
053     * Constructor for a colored polynomial system.
054     * @param cond a condition.
055     * @param S a list of colored polynomials.
056     */
057    public ColoredSystem(Condition<C> cond, List<ColorPolynomial<C>> S) {
058        this(cond, S, null);
059    }
060
061
062    /**
063     * Constructor for a colored polynomial system.
064     * @param cond a condition.
065     * @param S a list of colored polynomials.
066     * @param pl a ordered pair list.
067     */
068    public ColoredSystem(Condition<C> cond, List<ColorPolynomial<C>> S, OrderedCPairlist<C> pl) {
069        this.condition = cond;
070        this.list = S;
071        this.pairlist = pl;
072    }
073
074
075    /**
076     * Copy this colored polynomial system.
077     * @return a clone of this.
078     */
079    public ColoredSystem<C> copy() {
080        return new ColoredSystem<C>(condition, list, pairlist.copy());
081    }
082
083
084    /**
085     * Add to list of colored systems. This is added to the list of colored
086     * systems, if a system with the same condition is not already contained.
087     * @param L a list of colored systems.
088     * @return L.add(this) if this not in L, else L.
089     */
090    public List<ColoredSystem<C>> addToList(List<ColoredSystem<C>> L) {
091        List<ColoredSystem<C>> S = new ArrayList<ColoredSystem<C>>(L.size() + 1);
092        boolean contained = false;
093        for (ColoredSystem<C> x : L) {
094            if (condition.equals(x.condition) && list.equals(x.list)) {
095                logger.info("replaced system = {}", x.condition);
096                S.add(this);
097                contained = true;
098            } else { // copy existing
099                // System.out.println("kept system = " + x);
100                S.add(x);
101            }
102        }
103        if (!contained) {
104            S.add(this);
105        }
106        return S;
107    }
108
109
110    /**
111     * Get the String representation.
112     * @see java.lang.Object#toString()
113     */
114    @Override
115    public String toString() {
116        StringBuffer s = new StringBuffer("ColoredSystem: \n");
117        if (list.size() > 0) {
118            s.append("polynomial ring : " + list.get(0).green.ring + "\n");
119        } else {
120            s.append("parameter polynomial ring : " + condition.zero.getRing() + "\n");
121        }
122        s.append("conditions == 0 : " + getConditionZero() + "\n");
123        s.append("conditions != 0 : " + getConditionNonZero() + "\n");
124        if (debug) {
125            s.append("green coefficients:\n" + getGreenCoefficients() + "\n");
126            s.append("red coefficients:\n" + getRedCoefficients() + "\n");
127        }
128        s.append("colored polynomials:\n" + list + "\n");
129        s.append("uncolored polynomials:\n" + getPolynomialList() + "\n");
130        if (debug) {
131            s.append("essential polynomials:\n" + getEssentialPolynomialList() + "\n");
132        }
133        if (pairlist != null) {
134            s.append(pairlist.toString() + "\n");
135        }
136        return s.toString();
137    }
138
139
140    /**
141     * Get the Script representation.
142     * @see edu.jas.structure.Element#toScript()
143     */
144    public String toScript() {
145        StringBuffer s = new StringBuffer("ColoredSystem: \n");
146        if (list.size() > 0) {
147            s.append("polynomial ring : " + list.get(0).green.ring.toScript() + "\n");
148        } else {
149            s.append("parameter polynomial ring : " + condition.zero.getRing().toScript() + "\n");
150        }
151        s.append("conditions == 0 : " + getConditionZero().toString() + "\n");
152        s.append("conditions != 0 : " + getConditionNonZero().toString() + "\n");
153        if (debug) {
154            s.append("green coefficients:\n" + getGreenCoefficients().toString() + "\n");
155            s.append("red coefficients:\n" + getRedCoefficients().toString() + "\n");
156        }
157        s.append("colored polynomials:\n" + list + "\n");
158        s.append("uncolored polynomials:\n" + getPolynomialList() + "\n");
159        if (debug) {
160            s.append("essential polynomials:\n" + getEssentialPolynomialList() + "\n");
161        }
162        if (pairlist != null) {
163            s.append(pairlist.toString() + "\n");
164        }
165        return s.toString();
166    }
167
168
169    /**
170     * Is this colored system equal to other.
171     * @param c other colored system.
172     * @return true, if this is equal to other, else false.
173     */
174    @Override
175    @SuppressWarnings("unchecked")
176    public boolean equals(Object c) {
177        ColoredSystem<C> cs = null;
178        try {
179            cs = (ColoredSystem<C>) c;
180        } catch (ClassCastException e) {
181            return false;
182        }
183        if (cs == null) {
184            return false;
185        }
186        boolean t = (condition.equals(cs.condition) && list.equals(cs.list));
187        if (!t) {
188            return t;
189        }
190        // now t == true
191        t = pairlist.equals(cs.pairlist);
192        if (!t) {
193            System.out.println("pairlists not equal " + pairlist + ", " + cs.pairlist);
194        }
195        return true; // if lists are equal ignore pairlists
196    }
197
198
199    /**
200     * Hash code for this colored system.
201     * @see java.lang.Object#hashCode()
202     */
203    @Override
204    public int hashCode() {
205        int h;
206        h = condition.hashCode();
207        h = h << 17;
208        h += list.hashCode();
209        // h = h << 11;
210        // h += pairlist.hashCode();
211        return h;
212    }
213
214
215    /**
216     * Get zero condition.
217     * @return condition.zero.
218     */
219    public List<GenPolynomial<C>> getConditionZero() {
220        return condition.zero.getList();
221    }
222
223
224    /**
225     * Get non zero condition.
226     * @return condition.nonZero.
227     */
228    public List<GenPolynomial<C>> getConditionNonZero() {
229        return condition.nonZero.mset;
230    }
231
232
233    /**
234     * Get list of red coefficients of polynomials.
235     * @return list of all red coefficients of polynomials.
236     */
237    public List<GenPolynomial<C>> getRedCoefficients() {
238        Set<GenPolynomial<C>> F = new HashSet<GenPolynomial<C>>();
239        for (ColorPolynomial<C> s : list) {
240            F.addAll(s.red.getMap().values());
241        }
242        List<GenPolynomial<C>> M = new ArrayList<GenPolynomial<C>>(F);
243        return M;
244    }
245
246
247    /**
248     * Get list of green coefficients of polynomials.
249     * @return list of all green coefficients of polynomials.
250     */
251    public List<GenPolynomial<C>> getGreenCoefficients() {
252        Set<GenPolynomial<C>> F = new HashSet<GenPolynomial<C>>();
253        for (ColorPolynomial<C> s : list) {
254            F.addAll(s.green.getMap().values());
255        }
256        List<GenPolynomial<C>> M = new ArrayList<GenPolynomial<C>>(F);
257        return M;
258    }
259
260
261    /**
262     * Get list of full polynomials.
263     * @return list of all full polynomials.
264     */
265    public List<GenPolynomial<GenPolynomial<C>>> getPolynomialList() {
266        List<GenPolynomial<GenPolynomial<C>>> F = new ArrayList<GenPolynomial<GenPolynomial<C>>>();
267        for (ColorPolynomial<C> s : list) {
268            F.add(s.getPolynomial());
269        }
270        return F;
271    }
272
273
274    /**
275     * Get list of essential polynomials.
276     * @return list of all essential polynomials.
277     */
278    public List<GenPolynomial<GenPolynomial<C>>> getEssentialPolynomialList() {
279        List<GenPolynomial<GenPolynomial<C>>> F = new ArrayList<GenPolynomial<GenPolynomial<C>>>();
280        for (ColorPolynomial<C> s : list) {
281            F.add(s.getEssentialPolynomial());
282        }
283        return F;
284    }
285
286
287    /**
288     * Check invariants. Check if all polynomials are determined and if the
289     * color of all coefficients is correct with respect to the condition.
290     * @return true, if all invariants are met, else false.
291     */
292    public boolean checkInvariant() {
293        if (!isDetermined()) {
294            return false;
295        }
296        if (!condition.isDetermined(list)) {
297            return false;
298        }
299        // Condition<C> cond = condition;
300        for (ColorPolynomial<C> s : list) {
301            if (!s.checkInvariant()) {
302                System.out.println("notInvariant " + s);
303                System.out.println("condition:   " + condition);
304                return false;
305            }
306            for (GenPolynomial<C> g : s.green.getMap().values()) {
307                if (condition.color(g) != Condition.Color.GREEN) {
308                    System.out.println("notGreen   " + g);
309                    System.out.println("condition: " + condition);
310                    System.out.println("colors:    " + s);
311                    return false;
312                }
313            }
314            for (GenPolynomial<C> r : s.red.getMap().values()) {
315                if (condition.color(r) != Condition.Color.RED) {
316                    System.out.println("notRed     " + r);
317                    System.out.println("condition: " + condition);
318                    System.out.println("colors:    " + s);
319                    return false;
320                }
321            }
322            for (GenPolynomial<C> w : s.white.getMap().values()) {
323                if (condition.color(w) != Condition.Color.WHITE) {
324                    // System.out.println("notWhite " + w);
325                    // System.out.println("condition: " + condition);
326                    // System.out.println("colors: " + s);
327                    continue; // no error
328                    // return false;
329                }
330            }
331        }
332        return true;
333    }
334
335
336    /**
337     * Is this colored system completely determined.
338     * @return true, if each ColorPolynomial is determined, else false.
339     */
340    public boolean isDetermined() {
341        for (ColorPolynomial<C> s : list) {
342            if (s.isZERO()) {
343                continue;
344            }
345            if (!s.isDetermined()) {
346                System.out.println("not simple determined " + s);
347                System.out.println("condition:            " + condition);
348                return false;
349            }
350            if (!condition.isDetermined(s)) {
351                return false;
352            }
353        }
354        return true;
355    }
356
357
358    /**
359     * Re determine colorings of polynomials.
360     * @return colored system with re determined colored polynomials.
361     */
362    public ColoredSystem<C> reDetermine() {
363        if (condition == null || condition.zero.isONE()) {
364            return this;
365        }
366        List<ColorPolynomial<C>> Sn = new ArrayList<ColorPolynomial<C>>(list.size());
367        for (ColorPolynomial<C> c : list) {
368            ColorPolynomial<C> a = condition.reDetermine(c);
369            // if ( !a.isZERO() ) {
370            Sn.add(a); // must also add zeros
371            // }
372        }
373        return new ColoredSystem<C>(condition, Sn, pairlist);
374    }
375
376}