001/* 002 * $Id: OrderedWordPairlist.java 5869 2018-07-20 15:53:10Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.util.ArrayList; 009import java.util.BitSet; 010import java.util.Iterator; 011import java.util.LinkedList; 012import java.util.List; 013import java.util.Map; 014import java.util.SortedMap; 015import java.util.TreeMap; 016 017import org.apache.logging.log4j.Logger; 018import org.apache.logging.log4j.LogManager; 019 020import edu.jas.poly.GenWordPolynomial; 021import edu.jas.poly.GenWordPolynomialRing; 022import edu.jas.poly.Word; 023import edu.jas.structure.RingElem; 024 025 026/** 027 * Pair list management of word polynomials. Implemented using 028 * GenWordPolynomial, TreeMap and BitSet. 029 * @author Heinz Kredel 030 */ 031 032public class OrderedWordPairlist<C extends RingElem<C>> implements WordPairList<C> { 033 034 035 protected final List<GenWordPolynomial<C>> P; 036 037 038 protected final SortedMap<Word, LinkedList<WordPair<C>>> pairlist; 039 040 041 protected final List<BitSet> red; 042 043 044 protected final GenWordPolynomialRing<C> ring; 045 046 047 protected final WordReduction<C> reduction; 048 049 050 protected boolean oneInGB = false; 051 052 053 protected int putCount; 054 055 056 protected int remCount; 057 058 059 private static final Logger logger = LogManager.getLogger(OrderedWordPairlist.class); 060 061 062 /** 063 * Constructor. 064 */ 065 public OrderedWordPairlist() { 066 ring = null; 067 P = null; 068 pairlist = null; 069 red = null; 070 reduction = null; 071 putCount = 0; 072 remCount = 0; 073 } 074 075 076 /** 077 * Constructor. 078 * @param r word polynomial factory. 079 */ 080 public OrderedWordPairlist(GenWordPolynomialRing<C> r) { 081 ring = r; 082 P = new ArrayList<GenWordPolynomial<C>>(); 083 pairlist = new TreeMap<Word, LinkedList<WordPair<C>>>(ring.alphabet.getAscendComparator()); 084 red = new ArrayList<BitSet>(); 085 putCount = 0; 086 remCount = 0; 087 reduction = new WordReductionSeq<C>(); 088 } 089 090 091 /** 092 * Create a new WordPairList. 093 * @param r word polynomial ring. 094 */ 095 public WordPairList<C> create(GenWordPolynomialRing<C> r) { 096 return new OrderedWordPairlist<C>(r); 097 } 098 099 100 /** 101 * toString. 102 */ 103 @Override 104 public String toString() { 105 StringBuffer s = new StringBuffer(this.getClass().getSimpleName() + "("); 106 //s.append("polys="+P.size()); 107 s.append("#put=" + putCount); 108 s.append(", #rem=" + remCount); 109 if (pairlist != null && pairlist.size() != 0) { 110 s.append(", size=" + pairlist.size()); 111 } 112 //if (red != null ) { 113 // s.append(", bitmask=" + red); 114 //} 115 s.append(")"); 116 return s.toString(); 117 } 118 119 120 /** 121 * Put one Polynomial to the pairlist and reduction matrix. 122 * @param p polynomial. 123 * @return the index of the added polynomial. 124 */ 125 public synchronized int put(GenWordPolynomial<C> p) { 126 putCount++; 127 if (oneInGB) { 128 return P.size() - 1; 129 } 130 if (p.isONE()) { 131 return putOne(); 132 } 133 Word e = p.leadingWord(); 134 Word g; 135 int l = P.size(); 136 BitSet redi = new BitSet(); 137 //redi.set(0, l); // from -- to 138 for (int j = 0; j < l; j++) { 139 GenWordPolynomial<C> pj = P.get(j); 140 Word f = pj.leadingWord(); 141 142 // pj, p 143 g = f.lcm(e); 144 //System.out.println("g(f,g) = " + g); 145 if (g != null) { 146 WordPair<C> pair = new WordPair<C>(pj, p, j, l); 147 //System.out.println("pair.new = " + pair); 148 //multiple pairs under same keys -> list of pairs 149 LinkedList<WordPair<C>> xl = pairlist.get(g); 150 if (xl == null) { 151 xl = new LinkedList<WordPair<C>>(); 152 } 153 //xl.addLast( pair ); // first or last ? 154 xl.addFirst(pair); // first or last ? better for d- e-GBs 155 pairlist.put(g, xl); 156 redi.set(j); // = red.get(l).set(j); 157 } 158 159 // p, pj 160 g = e.lcm(f); 161 //System.out.println("g(e,f) = " + g); 162 if (g != null) { 163 WordPair<C> pair = new WordPair<C>(p, pj, l, j); 164 //System.out.println("pair.new = " + pair); 165 //multiple pairs under same keys -> list of pairs 166 LinkedList<WordPair<C>> xl = pairlist.get(g); 167 if (xl == null) { 168 xl = new LinkedList<WordPair<C>>(); 169 } 170 //xl.addLast( pair ); // first or last ? 171 xl.addFirst(pair); // first or last ? better for d- e-GBs 172 pairlist.put(g, xl); 173 red.get(j).set(l); 174 } 175 } 176 red.add(redi); 177 //System.out.println("pairlist.keys@put = " + pairlist.keySet() ); 178 //System.out.println("#pairlist = " + pairlist.size() ); 179 P.add(p); 180 //System.out.println("pairlist.key = " + pairlist.keySet() ); 181 return l; //P.size() - 1; 182 } 183 184 185 /** 186 * Put all word polynomials in F to the pairlist and reduction matrix. 187 * @param F word polynomial list. 188 * @return the index of the last added word polynomial. 189 */ 190 public int put(List<GenWordPolynomial<C>> F) { 191 //System.out.println("pairlist.F = " + F ); 192 int i = 0; 193 for (GenWordPolynomial<C> p : F) { 194 i = put(p); 195 } 196 return i; 197 } 198 199 200 /** 201 * Remove the next required pair from the pairlist and reduction matrix. 202 * Appy the criterion 3 to see if the S-polynomial is required. 203 * @return the next pair if one exists, otherwise null. 204 */ 205 public synchronized WordPair<C> removeNext() { 206 if (oneInGB) { 207 return null; 208 } 209 Iterator<Map.Entry<Word, LinkedList<WordPair<C>>>> ip = pairlist.entrySet().iterator(); 210 211 WordPair<C> pair = null; 212 //boolean c = false; 213 int i, j; 214 215 //while (!c && ip.hasNext()) { 216 if (ip.hasNext()) { 217 Map.Entry<Word, LinkedList<WordPair<C>>> me = ip.next(); 218 Word g = me.getKey(); 219 LinkedList<WordPair<C>> xl = me.getValue(); 220 if (logger.isInfoEnabled()) { 221 logger.info("g = " + g); 222 } 223 pair = null; 224 //while (!c && xl.size() > 0) { 225 if (xl.size() > 0) { 226 pair = xl.removeFirst(); 227 // xl is also modified in pairlist 228 i = pair.i; 229 j = pair.j; 230 // System.out.println("pair(" + j + "," +i+") "); 231 //c = criterion3(i, j, g); // to check 232 //if ( !c ) { 233 // System.out.println("criterion 3"); 234 //} 235 red.get(j).clear(i); 236 } 237 if (xl.size() == 0) { 238 ip.remove(); 239 } 240 } 241 //if (!c) { 242 // pair = null; 243 //} else { 244 remCount++; // count only real pairs 245 //} 246 return pair; 247 } 248 249 250 /** 251 * Test if there is possibly a pair in the list. 252 * @return true if a next pair could exist, otherwise false. 253 */ 254 public synchronized boolean hasNext() { 255 return pairlist.size() > 0; 256 } 257 258 259 /** 260 * Get the list of polynomials. 261 * @return the polynomial list. 262 */ 263 public List<GenWordPolynomial<C>> getList() { 264 return P; 265 } 266 267 268 /** 269 * Get the number of polynomials put to the pairlist. 270 * @return the number of calls to put. 271 */ 272 public synchronized int putCount() { 273 return putCount; 274 } 275 276 277 /** 278 * Get the number of required pairs removed from the pairlist. 279 * @return the number of non null pairs delivered. 280 */ 281 public synchronized int remCount() { 282 return remCount; 283 } 284 285 286 /** 287 * Put the ONE-Polynomial to the pairlist. 288 * @param one polynomial. (no more required) 289 * @return the index of the last polynomial. 290 */ 291 public synchronized int putOne(GenWordPolynomial<C> one) { 292 if (one == null) { 293 return P.size() - 1; 294 } 295 if (!one.isONE()) { 296 return P.size() - 1; 297 } 298 return putOne(); 299 } 300 301 302 /** 303 * Put the ONE-Polynomial to the pairlist. 304 * @return the index of the last polynomial. 305 */ 306 public synchronized int putOne() { 307 putCount++; 308 oneInGB = true; 309 pairlist.clear(); 310 P.clear(); 311 P.add(ring.getONE()); 312 red.clear(); 313 return P.size() - 1; 314 } 315 316 317 /** 318 * GB criterium 3. 319 * @return true if the S-polynomial(i,j) is required. 320 */ 321 public boolean criterion3(int i, int j, Word eij) { 322 boolean s = red.get(j).get(i); 323 //if (s) { 324 // logger.warn("c3.s true for " + i + " " + j); 325 // //return s; 326 //} 327 for (int k = 0; k < P.size(); k++) { 328 // System.out.println("i , k , j "+i+" "+k+" "+j); 329 if (i != k && j != k) { 330 GenWordPolynomial<C> A = P.get(k); 331 Word ek = A.leadingWord(); 332 boolean m = eij.multipleOf(ek); 333 if (m) { 334 if (i < j) { 335 if (k < i) { 336 // System.out.println("k < i "+k+" "+i); 337 s = red.get(i).get(k) || red.get(j).get(k); 338 } else if (i < k && k < j) { 339 // System.out.println("i < k < j "+i+" "+k+" "+j); 340 s = red.get(k).get(i) || red.get(j).get(k); 341 } else if (j < k) { 342 //System.out.println("j < k "+j+" "+k); 343 s = red.get(k).get(i) || red.get(k).get(j); 344 } 345 } else { // j < i 346 if (k < j) { 347 //System.out.println("k < j "+k+" "+j); 348 s = red.get(k).get(j) || red.get(k).get(i); 349 } else if (j < k && k < i) { 350 //System.out.println("j < k < i "+j+" "+k+" "+i); 351 s = red.get(j).get(k) || red.get(k).get(i); 352 } else if (i < k) { 353 //System.out.println("i < k "+i+" "+k); 354 s = red.get(j).get(k) || red.get(i).get(k); 355 } 356 } 357 //System.out.println("s."+k+" = " + s); 358 if (!s) { 359 return s; 360 } 361 } 362 } 363 } 364 return true; 365 } 366 367}