001/* 002 * $Id: WordGroebnerBaseAbstract.java 4150 2012-09-01 09:18:23Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007import java.util.ArrayList; 008import java.util.List; 009import java.util.Map; 010import java.util.TreeMap; 011import java.util.ListIterator; 012import java.util.Set; 013import java.util.HashSet; 014import java.util.Collections; 015 016import org.apache.log4j.Logger; 017 018import edu.jas.poly.GenWordPolynomial; 019import edu.jas.poly.GenWordPolynomialRing; 020import edu.jas.poly.TermOrder; 021import edu.jas.poly.PolyUtil; 022import edu.jas.structure.RingElem; 023import edu.jas.structure.RingFactory; 024import edu.jas.poly.Word; 025 026 027/** 028 * Non-commutative Groebner Bases abstract class. 029 * Implements common Groebner bases and GB test methods. 030 * @param <C> coefficient type 031 * @author Heinz Kredel 032 */ 033 034public abstract class WordGroebnerBaseAbstract<C extends RingElem<C>> 035 implements WordGroebnerBase<C> { 036 037 private static final Logger logger = Logger.getLogger(WordGroebnerBaseAbstract.class); 038 private final boolean debug = logger.isDebugEnabled(); 039 040 041 /** 042 * Reduction engine. 043 */ 044 public final WordReduction<C> red; 045 046 047 /** 048 * Strategy for pair selection. 049 */ 050 public final WordPairList<C> strategy; 051 052 053 /** 054 * Constructor. 055 */ 056 public WordGroebnerBaseAbstract() { 057 this( new WordReductionSeq<C>() ); 058 } 059 060 061 /** 062 * Constructor. 063 * @param red Word Reduction engine 064 */ 065 public WordGroebnerBaseAbstract(WordReduction<C> red) { 066 this(red, new OrderedWordPairlist<C>() ); 067 } 068 069 070 /** 071 * Constructor. 072 * @param red Word Reduction engine 073 * @param pl Word pair selection strategy 074 */ 075 public WordGroebnerBaseAbstract(WordReduction<C> red, WordPairList<C> pl) { 076 this.red = red; 077 this.strategy = pl; 078 } 079 080 081 /** 082 * Word Groebner base test. 083 * @param F Word polynomial list. 084 * @return true, if F is a Groebner base, else false. 085 */ 086 public boolean isGB(List<GenWordPolynomial<C>> F) { 087 if ( F == null || F.isEmpty() ) { 088 return true; 089 } 090 for ( int i = 0; i < F.size(); i++ ) { 091 GenWordPolynomial<C> pi = F.get(i); 092 for ( int j = i+1; j < F.size(); j++ ) { 093 GenWordPolynomial<C> pj = F.get(j); 094 List<GenWordPolynomial<C>> S = red.SPolynomials( pi, pj ); 095 if ( S.isEmpty() ) { 096 continue; 097 } 098 for ( GenWordPolynomial<C> s : S ) { 099 GenWordPolynomial<C> h = red.normalform( F, s ); 100 if ( ! h.isZERO() ) { 101 logger.info("no GB: pi = " + pi + ", pj = " + pj); 102 logger.info("s = " + s + ", h = " + h); 103 return false; 104 } 105 } 106 } 107 } 108 return true; 109 } 110 111 112 /** 113 * Groebner base using pairlist class. 114 * @param F polynomial list. 115 * @return GB(F) a Groebner base of F. 116 */ 117 public abstract List<GenWordPolynomial<C>> GB( List<GenWordPolynomial<C>> F ); 118 119 120 /** 121 * Minimal ordered Groebner basis. 122 * @param Gp a Groebner base. 123 * @return a reduced Groebner base of Gp. 124 */ 125 public List<GenWordPolynomial<C>> minimalGB(List<GenWordPolynomial<C>> Gp) { 126 if ( Gp == null || Gp.size() <= 1 ) { 127 return Gp; 128 } 129 // remove zero polynomials 130 List<GenWordPolynomial<C>> G 131 = new ArrayList<GenWordPolynomial<C>>( Gp.size() ); 132 for ( GenWordPolynomial<C> a : Gp ) { 133 if ( a != null && !a.isZERO() ) { // always true in GB() 134 // already positive a = a.abs(); 135 G.add( a ); 136 } 137 } 138 if ( G.size() <= 1 ) { 139 return G; 140 } 141 // remove top reducible polynomials 142 GenWordPolynomial<C> a; 143 List<GenWordPolynomial<C>> F; 144 F = new ArrayList<GenWordPolynomial<C>>( G.size() ); 145 while ( G.size() > 0 ) { 146 a = G.remove(0); 147 if ( red.isTopReducible(G,a) || red.isTopReducible(F,a) ) { 148 // drop polynomial 149 if ( debug ) { 150 System.out.println("dropped " + a); 151 List<GenWordPolynomial<C>> ff; 152 ff = new ArrayList<GenWordPolynomial<C>>( G ); 153 ff.addAll(F); 154 a = red.normalform( ff, a ); 155 if ( !a.isZERO() ) { 156 System.out.println("error, nf(a) " + a); 157 } 158 } 159 } else { 160 F.add(a); 161 } 162 } 163 G = F; 164 if ( G.size() <= 1 ) { 165 return G; 166 } 167 // reduce remaining polynomials 168 Collections.reverse(G); // important for lex GB 169 int len = G.size(); 170 if ( debug ) { 171 System.out.println("#G " + len); 172 for (GenWordPolynomial<C> aa : G) { 173 System.out.println("aa = " + aa.length() + ", lt = " + aa.getMap().keySet()); 174 } 175 } 176 int i = 0; 177 while ( i < len ) { 178 a = G.remove(0); 179 if ( debug ) { 180 System.out.println("doing " + a.length() + ", lt = " + a.leadingWord()); 181 } 182 a = red.normalform( G, a ); 183 G.add( a ); // adds as last 184 i++; 185 } 186 return G; 187 } 188 189 190 /** 191 * Test for minimal ordered Groebner basis. 192 * @param Gp an ideal base. 193 * @return true, if Gp is a reduced minimal Groebner base. 194 */ 195 public boolean isMinimalGB(List<GenWordPolynomial<C>> Gp) { 196 if ( Gp == null || Gp.size() == 0 ) { 197 return true; 198 } 199 // test for zero polynomials 200 for ( GenWordPolynomial<C> a : Gp ) { 201 if ( a == null || a.isZERO() ) { 202 if (debug) { 203 logger.debug("zero polynomial " + a); 204 } 205 return false; 206 } 207 } 208 // test for top reducible polynomials 209 List<GenWordPolynomial<C>> G = new ArrayList<GenWordPolynomial<C>>( Gp ); 210 List<GenWordPolynomial<C>> F = new ArrayList<GenWordPolynomial<C>>( G.size() ); 211 while ( G.size() > 0 ) { 212 GenWordPolynomial<C> a = G.remove(0); 213 if ( red.isTopReducible(G,a) || red.isTopReducible(F,a) ) { 214 if (debug) { 215 logger.debug("top reducible polynomial " + a); 216 } 217 return false; 218 } else { 219 F.add(a); 220 } 221 } 222 G = F; 223 if ( G.size() <= 1 ) { 224 return true; 225 } 226 // test reducibility of polynomials 227 int len = G.size(); 228 int i = 0; 229 while ( i < len ) { 230 GenWordPolynomial<C> a = G.remove(0); 231 if ( ! red.isNormalform( G, a ) ) { 232 if (debug) { 233 logger.debug("reducible polynomial " + a); 234 } 235 return false; 236 } 237 G.add( a ); // re-adds as last 238 i++; 239 } 240 return true; 241 } 242 243 244 /** 245 * Cleanup and terminate ThreadPool. 246 */ 247 public void terminate() { 248 logger.info("terminate not implemented"); 249 } 250 251 252 /** 253 * Cancel ThreadPool. 254 */ 255 public int cancel() { 256 logger.info("cancel not implemented"); 257 return 0; 258 } 259 260}