001 /* 002 * $Id: CriticalPairList.java 3420 2010-12-19 21:34:25Z kredel $ 003 */ 004 005 package edu.jas.gb; 006 007 import java.util.ArrayList; 008 import java.util.BitSet; 009 import java.util.Comparator; 010 import java.util.Iterator; 011 import java.util.List; 012 import java.util.SortedSet; 013 import java.util.TreeSet; 014 015 import org.apache.log4j.Logger; 016 017 import edu.jas.poly.ExpVector; 018 import edu.jas.poly.GenPolynomial; 019 import edu.jas.poly.GenPolynomialRing; 020 import edu.jas.poly.GenSolvablePolynomialRing; 021 import edu.jas.structure.RingElem; 022 023 /** 024 * Critical pair list management. 025 * Makes some effort to produce the same sequence of critical pairs 026 * as in the sequential case, when used in parallel. 027 * However already reduced pairs are not re-reduced if new 028 * polynomials appear. 029 * Implemented using GenPolynomial, SortedSet / TreeSet and BitSet. 030 * @author Heinz Kredel 031 */ 032 033 public class CriticalPairList<C extends RingElem<C>> extends OrderedPairlist<C> { 034 035 protected final SortedSet< CriticalPair<C> > pairlist; // hide super 036 037 protected int recordCount; 038 039 private static final Logger logger = Logger.getLogger(CriticalPairList.class); 040 041 042 /** 043 * Constructor for CriticalPairList. 044 */ 045 public CriticalPairList() { 046 super(); 047 pairlist = null; 048 } 049 050 051 /** 052 * Constructor for CriticalPairList. 053 * @param r polynomial factory. 054 */ 055 public CriticalPairList(GenPolynomialRing<C> r) { 056 this(0,r); 057 } 058 059 060 /** 061 * Constructor for CriticalPairList. 062 * @param m number of module variables. 063 * @param r polynomial factory. 064 */ 065 public CriticalPairList(int m, GenPolynomialRing<C> r) { 066 super(m,r); 067 Comparator< AbstractPair<C> > cpc; 068 cpc = new CriticalPairComparator<C>( ring.tord ); 069 pairlist = new TreeSet< CriticalPair<C> >( cpc ); 070 recordCount = 0; 071 } 072 073 074 /** 075 * Create a new PairList. 076 * @param r polynomial ring. 077 */ 078 public PairList<C> create(GenPolynomialRing<C> r) { 079 return new CriticalPairList<C>(r); 080 } 081 082 083 /** 084 * Create a new PairList. 085 * @param m number of module variables. 086 * @param r polynomial ring. 087 */ 088 public PairList<C> create(int m, GenPolynomialRing<C> r) { 089 return new CriticalPairList<C>(m,r); 090 } 091 092 093 /** 094 * Put a polynomial to the pairlist and reduction matrix. 095 * @param p polynomial. 096 * @return the index of the added polynomial. 097 */ 098 public synchronized int put(GenPolynomial<C> p) { 099 putCount++; 100 if ( oneInGB ) { 101 return P.size()-1; 102 } 103 ExpVector e = p.leadingExpVector(); 104 int len = P.size(); 105 for ( int j = 0; j < len; j++ ) { 106 GenPolynomial<C> pj = P.get(j); 107 ExpVector f = pj.leadingExpVector(); 108 if ( moduleVars > 0 ) { // test moduleCriterion 109 if ( !reduction.moduleCriterion( moduleVars, e, f) ) { 110 continue; // skip pair 111 } 112 } 113 ExpVector g = e.lcm( f ); 114 CriticalPair<C> pair = new CriticalPair<C>( g, pj, p, j, len ); 115 //System.out.println("put pair = " + pair ); 116 pairlist.add( pair ); 117 } 118 P.add( p ); 119 BitSet redi = new BitSet(); 120 redi.set( 0, len ); // >= jdk 1.4 121 red.add( redi ); 122 if ( recordCount < len ) { 123 recordCount = len; 124 } 125 return len; 126 } 127 128 129 /** 130 * Test if there is possibly a pair in the list. 131 * @return true if a next pair could exist, otherwise false. 132 */ 133 public synchronized boolean hasNext() { 134 return pairlist.size() > 0; 135 } 136 137 138 /** 139 * Get and remove the next required pair from the pairlist. 140 * Appy the criterions 3 and 4 to see if the S-polynomial is required. 141 * The pair is not removed from the pair list. 142 * @return the next pair if one exists, otherwise null. 143 */ 144 public Pair<C> removeNext() { 145 CriticalPair<C> cp = getNext(); 146 if ( cp == null ) { 147 return null; 148 } 149 return new Pair<C>(cp.pi,cp.pj,cp.i,cp.j); 150 } 151 152 153 /** 154 * Get the next required pair from the pairlist. 155 * Appy the criterions 3 and 4 to see if the S-polynomial is required. 156 * The pair is not removed from the pair list. 157 * @return the next pair if one exists, otherwise null. 158 */ 159 public synchronized CriticalPair<C> getNext() { 160 if ( oneInGB ) { 161 return null; 162 } 163 CriticalPair<C> pair = null; 164 Iterator< CriticalPair<C> > ip = pairlist.iterator(); 165 boolean c = false; 166 while ( !c & ip.hasNext() ) { 167 pair = ip.next(); 168 if ( pair.getInReduction() ) { 169 continue; 170 } 171 if ( pair.getReductum() != null ) { 172 continue; 173 } 174 if ( logger.isInfoEnabled() ) { 175 logger.info("" + pair); 176 } 177 if ( useCriterion4 ) { 178 c = reduction.criterion4( pair.pi, pair.pj, pair.e ); 179 // System.out.println("c4 = " + c); 180 } else { 181 c = true; 182 } 183 if ( c ) { 184 c = criterion3( pair.i, pair.j, pair.e ); 185 // System.out.println("c3 = " + c); 186 } 187 red.get( pair.j ).clear( pair.i ); // set(i,false) jdk1.4 188 if ( ! c ) { // set done 189 pair.setReductum( ring.getZERO() ); 190 } 191 } 192 if ( ! c ) { 193 pair = null; 194 } else { 195 remCount++; // count only real pairs 196 pair.setInReduction(); // set to work 197 } 198 return pair; 199 } 200 201 202 /** 203 * Record reduced polynomial. 204 * @param pair the corresponding critical pair. 205 * @param p polynomial. 206 * @return index of recorded polynomial, or -1 if not added. 207 */ 208 public int record(CriticalPair<C> pair, GenPolynomial<C> p) { 209 if ( p == null ) { 210 p = ring.getZERO(); 211 } 212 pair.setReductum(p); 213 // trigger thread 214 if ( ! p.isZERO() && ! p.isONE() ) { 215 recordCount++; 216 return recordCount; 217 } 218 return -1; 219 } 220 221 222 /** 223 * Record reduced polynomial and update critical pair list. 224 * Note: it is better to use record and uptate separately. 225 * @param pair the corresponding critical pair. 226 * @param p polynomial. 227 * @return index of recorded polynomial 228 */ 229 public int update(CriticalPair<C> pair, GenPolynomial<C> p) { 230 if ( p == null ) { 231 p = ring.getZERO(); 232 } 233 pair.setReductum(p); 234 if ( ! p.isZERO() && ! p.isONE() ) { 235 recordCount++; 236 } 237 int c = update(); 238 if ( ! p.isZERO() && ! p.isONE() ) { 239 return recordCount; 240 } 241 return -1; 242 } 243 244 245 /** 246 * Update pairlist. 247 * Preserve the sequential pair sequence. 248 * Remove pairs with completed reductions. 249 * @return the number of added polynomials. 250 */ 251 public synchronized int update() { 252 int num = 0; 253 if ( oneInGB ) { 254 return num; 255 } 256 while ( pairlist.size() > 0 ) { 257 CriticalPair<C> pair = pairlist.first(); 258 GenPolynomial<C> p = pair.getReductum(); 259 if ( p != null ) { 260 pairlist.remove( pair ); 261 num++; 262 if ( ! p.isZERO() ) { 263 if ( p.isONE() ) { 264 putOne(); // sets size = 1 265 } else { 266 put( p ); // changes pair list 267 } 268 } 269 } else { 270 break; 271 } 272 } 273 return num; 274 } 275 276 277 /** 278 * In work pairs. List pairs which are currently reduced. 279 * @return list of critical pairs which are in reduction. 280 */ 281 public synchronized List<CriticalPair<C>> inWork() { 282 List<CriticalPair<C>> iw; 283 iw = new ArrayList<CriticalPair<C>>(); 284 if ( oneInGB ) { 285 return iw; 286 } 287 for ( CriticalPair<C> pair : pairlist ) { 288 if ( pair.getInReduction() ) { 289 iw.add( pair ); 290 } 291 } 292 return iw; 293 } 294 295 296 /** 297 * Update pairlist, several pairs at once. 298 * This version does not preserve the sequential pair sequence. 299 * Remove pairs with completed reductions. 300 * @return the number of added polynomials. 301 */ 302 public synchronized int updateMany() { 303 int num = 0; 304 if ( oneInGB ) { 305 return num; 306 } 307 List<CriticalPair<C>> rem = new ArrayList<CriticalPair<C>>(); 308 for ( CriticalPair<C> pair : pairlist ) { 309 if ( pair.getReductum() != null ) { 310 rem.add( pair ); 311 num++; 312 } else { 313 break; 314 } 315 } 316 // must work on a copy to avoid concurrent modification 317 for ( CriticalPair<C> pair : rem ) { 318 // System.out.println("update = " + pair); 319 pairlist.remove( pair ); 320 GenPolynomial<C> p = pair.getReductum(); 321 if ( ! p.isZERO() ) { 322 if ( p.isONE() ) { 323 putOne(); 324 } else { 325 put( p ); 326 } 327 } 328 } 329 return num; 330 } 331 332 333 /** 334 * Put the ONE-Polynomial to the pairlist. 335 * @return the index of the last polynomial. 336 */ 337 public synchronized int putOne() { 338 super.putOne(); 339 pairlist.clear(); 340 return 0; 341 } 342 343 }