001/* 002 * $Id: SGBFactory.java 6010 2020-04-01 10:39:15Z kredel $ 003 */ 004 005package edu.jas.gbufd; 006 007 008import org.apache.logging.log4j.LogManager; 009import org.apache.logging.log4j.Logger; 010 011import edu.jas.arith.BigInteger; 012import edu.jas.arith.BigRational; 013import edu.jas.arith.ModInteger; 014import edu.jas.arith.ModIntegerRing; 015import edu.jas.arith.ModLong; 016import edu.jas.arith.ModLongRing; 017import edu.jas.gb.OrderedMinPairlist; 018import edu.jas.gb.OrderedPairlist; 019import edu.jas.gb.OrderedSyzPairlist; 020import edu.jas.gb.PairList; 021import edu.jas.gb.SGBProxy; 022import edu.jas.gb.SolvableGroebnerBaseAbstract; 023import edu.jas.gb.SolvableGroebnerBaseParallel; 024import edu.jas.gb.SolvableGroebnerBaseSeq; 025import edu.jas.gb.SolvableReductionSeq; 026import edu.jas.kern.ComputerThreads; 027import edu.jas.poly.GenPolynomial; 028import edu.jas.poly.GenPolynomialRing; 029import edu.jas.structure.GcdRingElem; 030import edu.jas.structure.QuotPairFactory; 031import edu.jas.structure.RingFactory; 032import edu.jas.structure.ValueFactory; 033import edu.jas.ufd.Quotient; 034import edu.jas.ufd.QuotientRing; 035 036 037// import edu.jas.application.SolvableResidueRing; // package cycle 038 039 040/** 041 * Solvable Groebner bases algorithms factory. Select appropriate Solvable 042 * Groebner bases engine based on the coefficient types. 043 * <p> 044 * <b>Usage:</b> To create objects that implement the 045 * <code>SolvableGroebnerBase</code> interface use the <code>SGBFactory</code>. 046 * It will select an appropriate implementation based on the types of polynomial 047 * coefficients C. The method to obtain an implementation is 048 * <code>getImplementation()</code>. It returns an object of a class which 049 * implements the <code>SolvableGroebnerBase</code> interface, more precisely an 050 * object of abstract class <code>SolvableGroebnerBaseAbstract</code>. 051 * 052 * <pre> 053 * SolvableGroebnerBase<CT> engine; 054 * engine = SGBFactory.<CT> getImplementation(cofac); 055 * c = engine.GB(A); 056 * </pre> 057 * <p> 058 * For example, if the coefficient type is BigInteger, the usage looks like 059 * 060 * <pre> 061 * BigInteger cofac = new BigInteger(); 062 * SolvableGroebnerBase<BigInteger> engine; 063 * engine = SGBFactory.getImplementation(cofac); 064 * c = engine.GB(A); 065 * </pre> 066 * 067 * @author Heinz Kredel 068 * 069 * @see edu.jas.gb.GroebnerBase 070 * @see edu.jas.gb.SolvableGroebnerBase 071 * @see edu.jas.application.GBAlgorithmBuilder 072 */ 073 074public class SGBFactory { 075 076 077 private static final Logger logger = LogManager.getLogger(SGBFactory.class); 078 079 080 private static final boolean debug = logger.isDebugEnabled(); 081 082 083 /** 084 * Protected factory constructor. 085 */ 086 protected SGBFactory() { 087 } 088 089 090 /** 091 * Determine suitable implementation of GB algorithms, no factory case. 092 * @return GB algorithm implementation for field coefficients. 093 */ 094 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<C> getImplementation() { 095 logger.warn("no coefficent factory given, assuming field coeffcients"); 096 SolvableGroebnerBaseAbstract<C> bba = new SolvableGroebnerBaseSeq<C>(); 097 return bba; 098 } 099 100 101 /** 102 * Determine suitable implementation of GB algorithms, case ModLong. 103 * @param fac ModLongRing. 104 * @return GB algorithm implementation. 105 */ 106 public static SolvableGroebnerBaseAbstract<ModLong> getImplementation(ModLongRing fac) { 107 return getImplementation(fac, new OrderedPairlist<ModLong>()); 108 } 109 110 111 /** 112 * Determine suitable implementation of GB algorithms, case ModLong. 113 * @param fac ModLongRing. 114 * @param pl pair selection strategy 115 * @return GB algorithm implementation. 116 */ 117 public static SolvableGroebnerBaseAbstract<ModLong> getImplementation(ModLongRing fac, 118 PairList<ModLong> pl) { 119 SolvableGroebnerBaseAbstract<ModLong> bba; 120 if (fac.isField()) { 121 bba = new SolvableGroebnerBaseSeq<ModLong>(pl); 122 } else { 123 bba = new SolvableGroebnerBasePseudoSeq<ModLong>(fac, pl); 124 } 125 return bba; 126 } 127 128 129 /** 130 * Determine suitable implementation of GB algorithms, case ModInteger. 131 * @param fac ModIntegerRing. 132 * @return GB algorithm implementation. 133 */ 134 public static SolvableGroebnerBaseAbstract<ModInteger> getImplementation(ModIntegerRing fac) { 135 return getImplementation(fac, new OrderedPairlist<ModInteger>()); 136 } 137 138 139 /** 140 * Determine suitable implementation of GB algorithms, case ModInteger. 141 * @param fac ModIntegerRing. 142 * @param pl pair selection strategy 143 * @return GB algorithm implementation. 144 */ 145 public static SolvableGroebnerBaseAbstract<ModInteger> getImplementation(ModIntegerRing fac, 146 PairList<ModInteger> pl) { 147 SolvableGroebnerBaseAbstract<ModInteger> bba; 148 if (fac.isField()) { 149 bba = new SolvableGroebnerBaseSeq<ModInteger>(pl); 150 } else { 151 bba = new SolvableGroebnerBasePseudoSeq<ModInteger>(fac, pl); 152 } 153 return bba; 154 } 155 156 157 /** 158 * Determine suitable implementation of GB algorithms, case BigInteger. 159 * @param fac BigInteger. 160 * @return GB algorithm implementation. 161 */ 162 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac) { 163 return getImplementation(fac, GBFactory.Algo.igb); 164 } 165 166 167 /** 168 * Determine suitable implementation of GB algorithms, case BigInteger. 169 * @param fac BigInteger. 170 * @param a algorithm, a = igb, egb, dgb. 171 * @return GB algorithm implementation. 172 */ 173 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, 174 GBFactory.Algo a) { 175 return getImplementation(fac, a, new OrderedPairlist<BigInteger>()); 176 } 177 178 179 /** 180 * Determine suitable implementation of GB algorithms, case BigInteger. 181 * @param fac BigInteger. 182 * @param pl pair selection strategy 183 * @return GB algorithm implementation. 184 */ 185 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, 186 PairList<BigInteger> pl) { 187 return getImplementation(fac, GBFactory.Algo.igb, pl); 188 } 189 190 191 /** 192 * Determine suitable implementation of GB algorithms, case BigInteger. 193 * @param fac BigInteger. 194 * @param a algorithm, a = igb, egb, dgb. 195 * @param pl pair selection strategy 196 * @return GB algorithm implementation. 197 */ 198 public static SolvableGroebnerBaseAbstract<BigInteger> getImplementation(BigInteger fac, GBFactory.Algo a, 199 PairList<BigInteger> pl) { 200 SolvableGroebnerBaseAbstract<BigInteger> bba; 201 switch (a) { 202 case igb: 203 bba = new SolvableGroebnerBasePseudoSeq<BigInteger>(fac, pl); 204 break; 205 case egb: 206 throw new UnsupportedOperationException("egb algorithm not available for BigInteger " + a); 207 case dgb: 208 throw new UnsupportedOperationException("dgb algorithm not available for BigInteger " + a); 209 default: 210 throw new IllegalArgumentException("algorithm not available for BigInteger " + a); 211 } 212 return bba; 213 } 214 215 216 /** 217 * Determine suitable implementation of GB algorithms, case BigRational. 218 * @param fac BigRational. 219 * @return GB algorithm implementation. 220 */ 221 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac) { 222 return getImplementation(fac, GBFactory.Algo.qgb); 223 } 224 225 226 /** 227 * Determine suitable implementation of GB algorithms, case BigRational. 228 * @param fac BigRational. 229 * @param a algorithm, a = qgb, ffgb. 230 * @return GB algorithm implementation. 231 */ 232 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac, 233 GBFactory.Algo a) { 234 return getImplementation(fac, a, new OrderedPairlist<BigRational>()); 235 } 236 237 238 /** 239 * Determine suitable implementation of GB algorithms, case BigRational. 240 * @param fac BigRational. 241 * @param pl pair selection strategy 242 * @return GB algorithm implementation. 243 */ 244 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac, 245 PairList<BigRational> pl) { 246 return getImplementation(fac, GBFactory.Algo.qgb, pl); 247 } 248 249 250 /** 251 * Determine suitable implementation of GB algorithms, case BigRational. 252 * @param fac BigRational. 253 * @param a algorithm, a = qgb, ffgb. 254 * @param pl pair selection strategy 255 * @return GB algorithm implementation. 256 */ 257 public static SolvableGroebnerBaseAbstract<BigRational> getImplementation(BigRational fac, 258 GBFactory.Algo a, PairList<BigRational> pl) { 259 SolvableGroebnerBaseAbstract<BigRational> bba; 260 switch (a) { 261 case qgb: 262 bba = new SolvableGroebnerBaseSeq<BigRational>(pl); 263 break; 264 case ffgb: 265 throw new UnsupportedOperationException("ffgb algorithm not available for BigRational " + a); 266 //PairList<BigInteger> pli; 267 //if (pl instanceof OrderedMinPairlist) { 268 // pli = new OrderedMinPairlist<BigInteger>(); 269 //} else if (pl instanceof OrderedSyzPairlist) { 270 // pli = new OrderedSyzPairlist<BigInteger>(); 271 //} else { 272 // pli = new OrderedPairlist<BigInteger>(); 273 //} 274 //bba = new SolvableGroebnerBaseRational<BigRational>(pli); // pl not possible 275 //break; 276 default: 277 throw new IllegalArgumentException( 278 "algorithm not available for " + fac.toScriptFactory() + ", Algo = " + a); 279 } 280 return bba; 281 } 282 283 284 /** 285 * Determine suitable implementation of GB algorithms, case Quotient 286 * coefficients. 287 * @param fac QuotientRing. 288 * @return GB algorithm implementation. 289 */ 290 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 291 QuotientRing<C> fac) { 292 return getImplementation(fac, GBFactory.Algo.qgb); 293 } 294 295 296 /** 297 * Determine suitable implementation of GB algorithms, case Quotient 298 * coefficients. 299 * @param fac QuotientRing. 300 * @param a algorithm, a = qgb, ffgb. 301 * @return GB algorithm implementation. 302 */ 303 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 304 QuotientRing<C> fac, GBFactory.Algo a) { 305 return getImplementation(fac, a, new OrderedPairlist<Quotient<C>>()); 306 } 307 308 309 /** 310 * Determine suitable implementation of GB algorithms, case Quotient 311 * coefficients. 312 * @param fac QuotientRing. 313 * @param pl pair selection strategy 314 * @return GB algorithm implementation. 315 */ 316 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 317 QuotientRing<C> fac, PairList<Quotient<C>> pl) { 318 return getImplementation(fac, GBFactory.Algo.qgb, pl); 319 } 320 321 322 /** 323 * Determine suitable implementation of GB algorithms, case Quotient 324 * coefficients. 325 * @param fac QuotientRing. 326 * @param a algorithm, a = qgb, ffgb. 327 * @param pl pair selection strategy 328 * @return GB algorithm implementation. 329 */ 330 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<Quotient<C>> getImplementation( 331 QuotientRing<C> fac, GBFactory.Algo a, PairList<Quotient<C>> pl) { 332 SolvableGroebnerBaseAbstract<Quotient<C>> bba; 333 if (logger.isInfoEnabled()) { 334 logger.info("QuotientRing, fac = " + fac); 335 } 336 switch (a) { 337 case qgb: 338 bba = new SolvableGroebnerBaseSeq<Quotient<C>>(new SolvableReductionSeq<Quotient<C>>(), pl); 339 break; 340 case ffgb: 341 throw new UnsupportedOperationException("ffgb algorithm not available for " + a); 342 //PairList<GenPolynomial<C>> pli; 343 //if (pl instanceof OrderedMinPairlist) { 344 // pli = new OrderedMinPairlist<GenPolynomial<C>>(); 345 //} else if (pl instanceof OrderedSyzPairlist) { 346 // pli = new OrderedSyzPairlist<GenPolynomial<C>>(); 347 //} else { 348 // pli = new OrderedPairlist<GenPolynomial<C>>(); 349 //} 350 //bba = new SolvableGroebnerBaseQuotient<C>(fac, pli); // pl not possible 351 //break; 352 default: 353 throw new IllegalArgumentException("algorithm not available for Quotient " + a); 354 } 355 return bba; 356 } 357 358 359 /** 360 * Determine suitable implementation of GB algorithms, case (recursive) 361 * polynomial. 362 * @param fac GenPolynomialRing<C>. 363 * @return GB algorithm implementation. 364 */ 365 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 366 GenPolynomialRing<C> fac) { 367 return getImplementation(fac, GBFactory.Algo.igb); 368 } 369 370 371 /** 372 * Determine suitable implementation of GB algorithms, case (recursive) 373 * polynomial. 374 * @param fac GenPolynomialRing<C>. 375 * @param a algorithm, a = igb or egb, dgb if fac is univariate over a 376 * field. 377 * @return GB algorithm implementation. 378 */ 379 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 380 GenPolynomialRing<C> fac, GBFactory.Algo a) { 381 return getImplementation(fac, a, new OrderedPairlist<GenPolynomial<C>>()); 382 } 383 384 385 /** 386 * Determine suitable implementation of GB algorithms, case (recursive) 387 * polynomial. 388 * @param fac GenPolynomialRing<C>. 389 * @param pl pair selection strategy 390 * @return GB algorithm implementation. 391 */ 392 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 393 GenPolynomialRing<C> fac, PairList<GenPolynomial<C>> pl) { 394 return getImplementation(fac, GBFactory.Algo.igb, pl); 395 } 396 397 398 /** 399 * Determine suitable implementation of GB algorithms, case (recursive) 400 * polynomial. 401 * @param fac GenPolynomialRing<C>. 402 * @param a algorithm, a = igb or egb, dgb if fac is univariate over a 403 * field. 404 * @param pl pair selection strategy 405 * @return GB algorithm implementation. 406 */ 407 public static <C extends GcdRingElem<C>> SolvableGroebnerBaseAbstract<GenPolynomial<C>> getImplementation( 408 GenPolynomialRing<C> fac, GBFactory.Algo a, PairList<GenPolynomial<C>> pl) { 409 SolvableGroebnerBaseAbstract<GenPolynomial<C>> bba; 410 switch (a) { 411 case igb: 412 bba = new SolvableGroebnerBasePseudoRecSeq<C>(fac, pl); 413 break; 414 case egb: 415 throw new UnsupportedOperationException("egb algorithm not available for " + a); 416 //if (fac.nvar > 1 || !fac.coFac.isField()) { 417 // throw new IllegalArgumentException("coefficients not univariate or not over a field" + fac); 418 //} 419 //bba = new ESolvableGroebnerBaseSeq<GenPolynomial<C>>(); // pl not suitable 420 //break; 421 case dgb: 422 throw new UnsupportedOperationException("dgb algorithm not available for " + a); 423 //if (fac.nvar > 1 || !fac.coFac.isField()) { 424 // throw new IllegalArgumentException("coefficients not univariate or not over a field" + fac); 425 //} 426 //bba = new DSolvableGroebnerBaseSeq<GenPolynomial<C>>(); // pl not suitable 427 //break; 428 default: 429 throw new IllegalArgumentException("algorithm not available for GenPolynomial<C> " + a); 430 } 431 return bba; 432 } 433 434 435 /* 436 * Determine suitable implementation of GB algorithms, case regular rings. 437 * @param fac RegularRing. 438 * @return GB algorithm implementation. 439 public static <C extends RingElem<C>> SolvableGroebnerBaseAbstract<Product<C>> getImplementation( 440 ProductRing<C> fac) { 441 SolvableGroebnerBaseAbstract<Product<C>> bba; 442 if (fac.onlyFields()) { 443 bba = new RSolvableGroebnerBaseSeq<Product<C>>(); 444 } else { 445 bba = new RSolvableGroebnerBasePseudoSeq<Product<C>>(fac); 446 } 447 return bba; 448 } 449 */ 450 451 452 /** 453 * Determine suitable implementation of GB algorithms, other cases. 454 * @param fac RingFactory<C>. 455 * @return GB algorithm implementation. 456 */ 457 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 458 SolvableGroebnerBaseAbstract<C> getImplementation(RingFactory<C> fac) { 459 return getImplementation(fac, new OrderedPairlist<C>()); 460 } 461 462 463 /** 464 * Determine suitable implementation of GB algorithms, other cases. 465 * @param fac RingFactory<C>. 466 * @param pl pair selection strategy 467 * @return GB algorithm implementation. 468 */ 469 @SuppressWarnings({ "cast", "unchecked" }) 470 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 471 SolvableGroebnerBaseAbstract<C> getImplementation(RingFactory<C> fac, PairList<C> pl) { 472 if (debug) { 473 logger.debug("fac = " + fac.getClass().getName()); // + ", fac = " + fac.toScript()); 474 } 475 if (fac.isField()) { 476 return new SolvableGroebnerBaseSeq<C>(pl); 477 } 478 if (fac instanceof ValueFactory) { 479 return new SolvableGroebnerBasePseudoSeq<C>(fac, pl); 480 } 481 if (fac instanceof QuotPairFactory) { 482 return new SolvableGroebnerBaseSeq<C>(pl); 483 } 484 SolvableGroebnerBaseAbstract bba = null; 485 Object ofac = fac; 486 if (ofac instanceof GenPolynomialRing) { 487 PairList<GenPolynomial<C>> pli; 488 if (pl instanceof OrderedMinPairlist) { 489 pli = new OrderedMinPairlist<GenPolynomial<C>>(); 490 } else if (pl instanceof OrderedSyzPairlist) { 491 pli = new OrderedSyzPairlist<GenPolynomial<C>>(); 492 } else { 493 pli = new OrderedPairlist<GenPolynomial<C>>(); 494 } 495 GenPolynomialRing<C> rofac = (GenPolynomialRing<C>) ofac; 496 SolvableGroebnerBaseAbstract<GenPolynomial<C>> bbr = new SolvableGroebnerBasePseudoRecSeq<C>( 497 rofac, pli); // not pl 498 bba = (SolvableGroebnerBaseAbstract) bbr; 499 //} else if (ofac instanceof ProductRing) { 500 // ProductRing pfac = (ProductRing) ofac; 501 // if (pfac.onlyFields()) { 502 // bba = new RSolvableGroebnerBaseSeq<Product<C>>(); 503 // } else { 504 // bba = new RSolvableGroebnerBasePseudoSeq<Product<C>>(pfac); 505 // } 506 } else { 507 bba = new SolvableGroebnerBasePseudoSeq<C>(fac, pl); 508 } 509 logger.info("bba = " + bba.getClass().getName()); 510 return bba; 511 } 512 513 514 /** 515 * Determine suitable parallel/concurrent implementation of GB algorithms if 516 * possible. 517 * @param fac RingFactory<C>. 518 * @return GB proxy algorithm implementation. 519 */ 520 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 521 SolvableGroebnerBaseAbstract<C> getProxy(RingFactory<C> fac) { 522 return getProxy(fac, new OrderedPairlist<C>()); 523 } 524 525 526 /** 527 * Determine suitable parallel/concurrent implementation of GB algorithms if 528 * possible. 529 * @param fac RingFactory<C>. 530 * @param pl pair selection strategy 531 * @return GB proxy algorithm implementation. 532 */ 533 @SuppressWarnings({ "unchecked" }) 534 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 535 SolvableGroebnerBaseAbstract<C> getProxy(RingFactory<C> fac, PairList<C> pl) { 536 if (ComputerThreads.NO_THREADS) { 537 return SGBFactory.<C> getImplementation(fac, pl); 538 } 539 if (debug) { 540 logger.debug("proxy fac = " + fac.getClass().getName()); 541 } 542 int th = (ComputerThreads.N_CPUS > 2 ? ComputerThreads.N_CPUS - 1 : 2); 543 if (fac.isField()) { 544 SolvableGroebnerBaseAbstract<C> e1 = new SolvableGroebnerBaseSeq<C>(pl); 545 SolvableGroebnerBaseAbstract<C> e2 = new SolvableGroebnerBaseParallel<C>(th, pl); 546 return new SGBProxy<C>(e1, e2); 547 } else if (fac.characteristic().signum() == 0) { 548 if (fac instanceof GenPolynomialRing) { 549 GenPolynomialRing pfac = (GenPolynomialRing) fac; 550 OrderedPairlist ppl = new OrderedPairlist<GenPolynomial<C>>(); 551 SolvableGroebnerBaseAbstract e1 = new SolvableGroebnerBasePseudoRecSeq<C>(pfac, ppl); 552 logger.warn("no parallel version available, returning sequential version"); 553 return e1; 554 //SolvableGroebnerBaseAbstract e2 = new SolvableGroebnerBasePseudoRecParallel<C>(th, pfac, ppl); 555 //return new SGBProxy<C>(e1, e2); 556 } 557 SolvableGroebnerBaseAbstract<C> e1 = new SolvableGroebnerBasePseudoSeq<C>(fac, pl); 558 logger.warn("no parallel version available, returning sequential version"); 559 return e1; 560 //SolvableGroebnerBaseAbstract<C> e2 = new SolvableGroebnerBasePseudoParallel<C>(th, fac, pl); 561 //return new SGBProxy<C>(e1, e2); 562 } 563 return getImplementation(fac, pl); 564 } 565 566 567 /** 568 * Determine suitable parallel/concurrent implementation of GB algorithms if 569 * possible. 570 * @param fac RingFactory<C>. 571 * @return GB proxy algorithm implementation. 572 */ 573 public static <C extends GcdRingElem<C>> // interface RingElem not sufficient 574 SolvableGroebnerBaseAbstract<GenPolynomial<C>> getProxy(GenPolynomialRing<C> fac) { 575 if (ComputerThreads.NO_THREADS) { 576 //return SGBFactory.<GenPolynomial<C>> getImplementation(fac); 577 return SGBFactory.getImplementation(fac); 578 } 579 if (debug) { 580 logger.debug("fac = " + fac.getClass().getName()); 581 } 582 //int th = (ComputerThreads.N_CPUS > 2 ? ComputerThreads.N_CPUS - 1 : 2); 583 OrderedPairlist<GenPolynomial<C>> ppl = new OrderedPairlist<GenPolynomial<C>>(); 584 SolvableGroebnerBaseAbstract<GenPolynomial<C>> e1 = new SolvableGroebnerBasePseudoRecSeq<C>(fac, ppl); 585 logger.warn("no parallel version available, returning sequential version"); 586 return e1; 587 //SolvableGroebnerBaseAbstract<GenPolynomial<C>> e2 = new SolvableGroebnerBasePseudoRecParallel<C>(th, fac, ppl); 588 //return new SGBProxy<GenPolynomial<C>>(e1, e2); 589 //return new SGBProxy(e1, e2); 590 } 591 592}