001 /* 002 * $Id: Condition.java 3426 2010-12-24 13:17:58Z kredel $ 003 */ 004 005 package edu.jas.application; 006 007 008 import java.io.Serializable; 009 import java.util.ArrayList; 010 import java.util.List; 011 import java.util.Map; 012 013 import org.apache.log4j.Logger; 014 015 import edu.jas.gbufd.MultiplicativeSet; 016 import edu.jas.gbufd.MultiplicativeSetSquarefree; 017 import edu.jas.poly.ExpVector; 018 import edu.jas.poly.GenPolynomial; 019 import edu.jas.poly.GenPolynomialRing; 020 import edu.jas.structure.GcdRingElem; 021 022 023 /** 024 * Condition. An ideal of polynomials considered to be zero and a multiplicative 025 * set of polynomials considered to be non-zero. 026 * @param <C> coefficient type 027 * @author Heinz Kredel. 028 */ 029 public class Condition<C extends GcdRingElem<C>> implements Serializable { 030 031 032 private static final Logger logger = Logger.getLogger(Condition.class); 033 034 035 private final boolean debug = logger.isDebugEnabled(); 036 037 038 /** 039 * Colors. 040 */ 041 public static enum Color { 042 GREEN, RED, WHITE 043 }; 044 045 046 /** 047 * Data structure for condition zero. 048 */ 049 public final Ideal<C> zero; 050 051 052 /** 053 * Data structure for condition non-zero. 054 */ 055 public final MultiplicativeSet<C> nonZero; 056 057 058 /** 059 * Condition constructor. Constructs an empty condition with squarefree 060 * multiplicative set. 061 * @param ring polynomial ring factory for coefficients. 062 */ 063 public Condition(GenPolynomialRing<C> ring) { 064 this(new Ideal<C>(ring), new MultiplicativeSetSquarefree<C>(ring)); 065 //this(new Ideal<C>(ring),new MultiplicativeSetFactors<C>(ring)); 066 if (ring == null) { 067 throw new IllegalArgumentException("only for non null rings"); 068 } 069 } 070 071 072 /** 073 * Condition constructor. Constructs a condition with squarefree 074 * multiplicative set. 075 * @param z an ideal of zero polynomials. 076 */ 077 public Condition(Ideal<C> z) { 078 this(z, new MultiplicativeSetSquarefree<C>(z.getRing())); 079 //this(z,new MultiplicativeSetFactors<C>(z.list.ring)); 080 } 081 082 083 /** 084 * Condition constructor. 085 * @param nz a list of non-zero polynomials. 086 */ 087 public Condition(MultiplicativeSet<C> nz) { 088 this(new Ideal<C>(nz.ring), nz); 089 } 090 091 092 /** 093 * Condition constructor. 094 * @param z an ideal of zero polynomials. 095 * @param nz a list of non-zero polynomials. 096 */ 097 public Condition(Ideal<C> z, MultiplicativeSet<C> nz) { 098 if (z == null || nz == null) { 099 throw new IllegalArgumentException("only for non null condition parts"); 100 } 101 zero = z; 102 nonZero = nz; 103 } 104 105 106 /** 107 * toString. 108 * @see java.lang.Object#toString() 109 */ 110 @Override 111 public String toString() { 112 return "Condition[ 0 == " + zero.getList().toString() + ", 0 != " + nonZero.mset.toString() + " ]"; 113 } 114 115 116 /** 117 * equals. 118 * @param ob an Object. 119 * @return true if this is equal to o, else false. 120 */ 121 @Override 122 @SuppressWarnings("unchecked") 123 public boolean equals(Object ob) { 124 Condition<C> c = null; 125 try { 126 c = (Condition<C>) ob; 127 } catch (ClassCastException e) { 128 return false; 129 } 130 if (c == null) { 131 return false; 132 } 133 if (!zero.equals(c.zero)) { 134 return false; 135 } 136 if (!nonZero.equals(c.nonZero)) { 137 return false; 138 } 139 // better: 140 //if ( nonZero.removeFactors(c.nonZero).size() != 0 ) { 141 // return false; 142 //} 143 //if ( c.nonZero.removeFactors(nonZero).size() != 0 ) { 144 // return false; 145 //} 146 return true; 147 } 148 149 150 /** 151 * Hash code for this condition. 152 * @see java.lang.Object#hashCode() 153 */ 154 @Override 155 public int hashCode() { 156 int h; 157 h = zero.getList().hashCode(); 158 h = h << 17; 159 h += nonZero.hashCode(); 160 // h = h << 11; 161 // h += pairlist.hashCode(); 162 return h; 163 } 164 165 166 /** 167 * Is empty condition. 168 * @return true if this is the empty condition, else false. 169 */ 170 public boolean isEmpty() { 171 return (zero.isZERO() && nonZero.isEmpty()); 172 } 173 174 175 /** 176 * Is contradictory. 177 * @return true if this condition is contradictory, else false. 178 */ 179 public boolean isContradictory() { 180 if (zero.isZERO()) { 181 return false; 182 } 183 boolean t = zero.isONE(); 184 if (t) { 185 logger.info("contradiction zero.isONE(): " + this); 186 return t; 187 } 188 for (GenPolynomial<C> p : zero.getList()) { 189 t = nonZero.contains(p); 190 if (t) { 191 logger.info("contradiction nonZero.contains(zero): " + this + ", pol = " + p); 192 return t; 193 } 194 } 195 for (GenPolynomial<C> p : nonZero.mset) { 196 t = zero.contains(p); 197 if (t) { 198 logger.info("contradiction zero.contains(nonZero): " + this + ", pol = " + p); 199 return t; 200 } 201 } 202 return false; 203 } 204 205 206 /** 207 * Extend condition with zero polynomial. 208 * @param z a polynomial to be treated as zero. 209 * @return new condition. 210 */ 211 public Condition<C> extendZero(GenPolynomial<C> z) { 212 // assert color(z) == white 213 z = z.monic(); 214 Ideal<C> idz = zero.sum(z); 215 logger.info("added to ideal: " + z); 216 217 Condition<C> nc = new Condition<C>(idz, nonZero); 218 if (true) { 219 return nc.simplify(); 220 } 221 return nc; 222 } 223 224 225 /** 226 * Extend condition with non-zero polynomial. 227 * @param nz a polynomial to be treated as non-zero. 228 * @return new condition. 229 */ 230 public Condition<C> extendNonZero(GenPolynomial<C> nz) { 231 // assert color(nz) == white 232 GenPolynomial<C> n = zero.normalform(nz).monic(); 233 if (n == null || n.isZERO()) { 234 return this; 235 } 236 MultiplicativeSet<C> ms = nonZero.add(n); 237 logger.info("added to non zero: " + n); 238 239 Condition<C> nc = new Condition<C>(zero, ms); 240 if (true) { 241 return nc.simplify(); 242 } 243 return nc; 244 } 245 246 247 /** 248 * Simplify zero and non-zero polynomial conditions. 249 * @return new simplified condition. 250 */ 251 public Condition<C> simplify() { 252 if (false) { // no simplification 253 return this; 254 } 255 Ideal<C> idz = zero.squarefree(); 256 if (!idz.getList().equals(zero.getList())) { 257 logger.info("simplify squarefree: " + zero.getList() + " to " + idz.getList()); 258 } 259 List<GenPolynomial<C>> ml = idz.normalform(nonZero.mset); 260 MultiplicativeSet<C> ms = nonZero; 261 if (!ml.equals(nonZero.mset)) { 262 if (ml.size() != nonZero.mset.size()) { 263 logger.info("contradiction(==0):"); 264 logger.info("simplify normalform contradiction: " + nonZero.mset + " to " + ml); 265 return null; 266 } 267 logger.info("simplify normalform: " + nonZero.mset + " to " + ml); 268 ms = nonZero.replace(ml); 269 } 270 List<GenPolynomial<C>> Z = ms.removeFactors(idz.getList()); 271 if (!Z.equals(idz.getList())) { 272 if (Z.size() != idz.getList().size()) { // never true 273 logger.info("contradiction(!=0):"); 274 logger.info("simplify removeFactors contradiction: " + idz.getList() + " to " + Z); 275 return null; 276 } 277 logger.info("simplify removeFactors: " + idz.getList() + " to " + Z); 278 idz = new Ideal<C>(zero.getRing(), Z); // changes ideal 279 } 280 Condition<C> nc = new Condition<C>(idz, ms); 281 if (nc.isContradictory()) { // evenatually a factor became 1 282 //logger.info("simplify contradiction: " + nc); 283 return null; 284 } 285 if (idz.equals(zero) && ms.equals(nonZero)) { 286 return this; 287 } 288 logger.info("condition simplified: " + this + " to " + nc); 289 if (false) { // no further simplification 290 return nc; 291 } 292 return nc.simplify(); 293 } 294 295 296 /** 297 * Determine color of polynomial. 298 * @param c polynomial to be colored. 299 * @return color of c. 300 */ 301 public Color color(GenPolynomial<C> c) { 302 GenPolynomial<C> m = zero.normalform(c).monic(); 303 //non-sense: m = nonZero.removeFactors(m); 304 if (m.isZERO()) { // zero.contains(m) 305 // System.out.println("m in id = " + m); 306 return Color.GREEN; 307 } 308 if (m.isConstant()) { 309 // System.out.println("m constant " + m); 310 return Color.RED; 311 } 312 if (nonZero.contains(m) || nonZero.contains(c)) { 313 // System.out.println("m or c in nonzero " + m); 314 return Color.RED; 315 } 316 //System.out.println("m white " + m + ", c = " + c); 317 return Color.WHITE; 318 } 319 320 321 /** 322 * Determine polynomial. If this condition does not determine the 323 * polynomial, then a run-time exception is thrown. 324 * @param A polynomial. 325 * @return new determined colored polynomial. 326 */ 327 public ColorPolynomial<C> determine(GenPolynomial<GenPolynomial<C>> A) { 328 ColorPolynomial<C> cp = null; 329 if (A == null) { 330 return cp; 331 } 332 GenPolynomial<GenPolynomial<C>> zero = A.ring.getZERO(); 333 GenPolynomial<GenPolynomial<C>> green = zero; 334 GenPolynomial<GenPolynomial<C>> red = zero; 335 GenPolynomial<GenPolynomial<C>> white = zero; 336 if (A.isZERO()) { 337 cp = new ColorPolynomial<C>(green, red, white); 338 return cp; 339 } 340 GenPolynomial<GenPolynomial<C>> Ap = A; 341 GenPolynomial<GenPolynomial<C>> Bp; 342 while (!Ap.isZERO()) { 343 Map.Entry<ExpVector, GenPolynomial<C>> m = Ap.leadingMonomial(); 344 ExpVector e = m.getKey(); 345 GenPolynomial<C> c = m.getValue(); 346 Bp = Ap.reductum(); 347 // System.out.println( "color(" + c + ") = " + color(c) ); 348 switch (color(c)) { 349 case GREEN: 350 green = green.sum(c, e); 351 Ap = Bp; 352 continue; 353 case RED: 354 red = red.sum(c, e); 355 white = Bp; 356 return new ColorPolynomial<C>(green, red, white); 357 // since break is not possible 358 default: 359 System.out.println("error cond = " + this); 360 System.out.println("error poly A = " + A); 361 System.out.println("error poly green = " + green); 362 System.out.println("error poly red = " + red); 363 System.out.println("error poly Ap = " + Ap); 364 System.out.println("error coeff c = " + c); 365 throw new RuntimeException("error, c is white = " + c); 366 // is catched in minimalGB 367 } 368 } 369 cp = new ColorPolynomial<C>(green, red, white); 370 // System.out.println("determined = " + cp); 371 return cp; 372 } 373 374 375 /** 376 * Determine list of polynomials. If this condition does not determine all 377 * polynomials, then a run-time exception is thrown. The returned list does 378 * not contain polynomials with all green terms. 379 * @param L list of polynomial. 380 * @return new determined list of colored polynomials. 381 */ 382 public List<ColorPolynomial<C>> determine(List<GenPolynomial<GenPolynomial<C>>> L) { 383 List<ColorPolynomial<C>> cl = null; 384 if (L == null) { 385 return cl; 386 } 387 cl = new ArrayList<ColorPolynomial<C>>(L.size()); 388 for (GenPolynomial<GenPolynomial<C>> A : L) { 389 ColorPolynomial<C> c = determine(A); 390 if (c != null && !c.isZERO()) { 391 cl.add(c); 392 } 393 } 394 return cl; 395 } 396 397 398 /** 399 * Re determine colored polynomial. 400 * @param s colored polynomial. 401 * @return determined colored polynomial wrt. this.conditions. 402 */ 403 public ColorPolynomial<C> reDetermine(ColorPolynomial<C> s) { 404 ColorPolynomial<C> p = determine(s.getEssentialPolynomial()); 405 // assume green terms stay green wrt. this condition 406 GenPolynomial<GenPolynomial<C>> g = s.green.sum(p.green); 407 p = new ColorPolynomial<C>(g, p.red, p.white); 408 return p; 409 } 410 411 412 /** 413 * Re determine list of colored polynomials. 414 * @param S list of colored polynomials. 415 * @return list of determined colored polynomials wrt. this.conditions. 416 */ 417 public List<ColorPolynomial<C>> reDetermine(List<ColorPolynomial<C>> S) { 418 if (S == null || S.isEmpty()) { 419 return S; 420 } 421 List<ColorPolynomial<C>> P = new ArrayList<ColorPolynomial<C>>(); 422 for (ColorPolynomial<C> s : S) { 423 ColorPolynomial<C> p = reDetermine(s); 424 P.add(p); 425 } 426 return P; 427 } 428 429 430 /** 431 * Is determined colored polynomial. 432 * @param s colored polynomial. 433 * @return true if the colored polynomial is correctly determined wrt. 434 * this.condition. 435 */ 436 public boolean isDetermined(ColorPolynomial<C> s) { 437 ColorPolynomial<C> p = determine(s.getPolynomial()); 438 boolean t = p.equals(s); 439 if (!t) { 440 System.out.println("not determined s = " + s); 441 System.out.println("not determined p = " + p); 442 System.out.println("not determined cond = " + this); 443 } 444 return t; 445 } 446 447 448 /** 449 * Is determined list of colored polynomial. 450 * @param S list of colored polynomials. 451 * @return true if the colored polynomials in S are correctly determined 452 * wrt. this.condition. 453 */ 454 public boolean isDetermined(List<ColorPolynomial<C>> S) { 455 if (S == null) { 456 return true; 457 } 458 for (ColorPolynomial<C> p : S) { 459 if (!isDetermined(p)) { 460 return false; 461 } 462 } 463 return true; 464 } 465 466 }