Пример #1
0
 public Rational getGcd() {
   assert (!mSummands.isEmpty());
   Iterator<Rational> it = mSummands.values().iterator();
   Rational gcd = it.next().abs();
   while (it.hasNext()) {
     gcd = gcd.gcd(it.next().abs());
   }
   return gcd;
 }
Пример #2
0
 /**
  * Add a sub-annotation to the current LAAnnotation and explain it.
  *
  * @param reason The reason for which a sub-annotation is created.
  * @param coeff The Farkas coefficient of the sub-annotation.
  */
 public void addAnnotation(LAReason reason, Rational coeff) {
   assert ((coeff.signum() > 0) == reason.isUpper());
   Rational sign = Rational.valueOf(coeff.signum(), 1);
   LAAnnotation annot = mSubReasons.get(reason);
   if (annot == null) {
     annot = new LAAnnotation(reason);
     mSubReasons.put(reason, annot);
     if (mAnnotationStack != null) mAnnotationStack.addLast(annot);
     reason.explain(this, reason.getVar().getEpsilon(), sign);
     if (mAnnotationStack != null) mAnnotationStack.removeLast();
   }
   if (mAnnotationStack != null) mAnnotationStack.getLast().addFarkas(annot, coeff);
 }
Пример #3
0
 private boolean isAllInt() {
   for (Map.Entry<Term, Rational> me : mSummands.entrySet()) {
     if (!me.getKey().getSort().getName().equals("Int")) return false;
     if (!me.getValue().isIntegral()) return false;
   }
   return mConstant.isIntegral();
 }
Пример #4
0
 /**
  * Convert the affine term to plain SMTLib term. Note that this is does not convert terms inside
  * this term. Instead use the static method cleanup() for this, which works on arbitrary terms.
  *
  * @see SMTAffineTerm.cleanup
  */
 private static Term toPlainTerm(Map<Term, Rational> summands, Rational constant, Sort sort) {
   assert sort.isNumericSort();
   Theory t = sort.getTheory();
   int size = summands.size();
   if (size == 0 || !constant.equals(Rational.ZERO)) size++;
   Term[] sum = new Term[size];
   int i = 0;
   for (Map.Entry<Term, Rational> factor : summands.entrySet()) {
     Term convTerm = factor.getKey();
     if (!convTerm.getSort().equals(sort)) {
       convTerm = t.term("to_real", convTerm);
     }
     if (factor.getValue().equals(Rational.MONE)) {
       convTerm = t.term("-", convTerm);
     } else if (!factor.getValue().equals(Rational.ONE)) {
       Term convfac = t.rational(factor.getValue(), sort);
       convTerm = t.term("*", convfac, convTerm);
     }
     sum[i++] = convTerm;
   }
   if (i < size) {
     sum[i++] = t.rational(constant, sort);
   }
   return size == 1 ? sum[0] : t.term("+", sum);
 }
Пример #5
0
 private boolean validClause() {
   if (mAnnotationStack == null) return true;
   assert (mAnnotationStack.size() == 1);
   MutableAffinTerm mat = mAnnotationStack.getFirst().addLiterals();
   assert (mat.isConstant() && InfinitNumber.ZERO.less(mat.getConstant()));
   for (Map.Entry<LAReason, LAAnnotation> reasonEntry : mSubReasons.entrySet()) {
     LAReason reason = reasonEntry.getKey();
     mat = reasonEntry.getValue().addLiterals();
     Rational coeff = reason.isUpper() ? Rational.MONE : Rational.ONE;
     mat.add(coeff, reason.getVar());
     mat.add(reason.getBound().mul(coeff.negate()));
     mat.add(reason.getVar().getEpsilon());
     assert (mat.isConstant() && InfinitNumber.ZERO.less(mat.getConstant()));
   }
   return true;
 }
Пример #6
0
 public void addEQAnnotation(LiteralReason reason, Rational coeff) {
   // FIXME: make a special annotation for disequalities
   assert ((coeff.signum() > 0) == reason.isUpper());
   Rational sign = Rational.valueOf(coeff.signum(), 1);
   LAAnnotation annot = mSubReasons.get(reason);
   if (annot == null) {
     annot = new LAAnnotation(reason);
     mSubReasons.put(reason, annot);
     mAnnotationStack.addLast(annot);
     if (reason.getOldReason() instanceof LiteralReason)
       reason.getOldReason().explain(this, reason.getVar().getEpsilon(), sign);
     else addAnnotation(reason.getOldReason(), sign);
     addLiteral(reason.getLiteral().negate(), sign);
     mAnnotationStack.removeLast();
   }
   mAnnotationStack.getLast().addFarkas(annot, coeff);
 }
Пример #7
0
 /**
  * Normalize this term. If this term corresponds to a singleton sum with coefficient 1 and
  * constant 0, it will return the singleton term. Otherwise, it will return this.
  *
  * @param compiler TermCompiler used to unify SMTAffineTerms
  * @return this or the singleton term corresponding to this.
  */
 public Term normalize(TermCompiler compiler) {
   if (mConstant.equals(Rational.ZERO) && mSummands.size() == 1) {
     Map.Entry<Term, Rational> me = mSummands.entrySet().iterator().next();
     if (me.getValue().equals(Rational.ONE)
         // Fixes bug for to_real
         && me.getKey().getSort() == mSort) return me.getKey();
   }
   return compiler.unify(this);
 }
Пример #8
0
 public static SMTAffineTerm create(Rational factor, Term subterm) {
   Sort sort = subterm.getSort();
   Map<Term, Rational> summands;
   Rational constant;
   if (factor.equals(Rational.ZERO)) {
     summands = Collections.emptyMap();
     constant = Rational.ZERO;
   } else if (subterm instanceof SMTAffineTerm) {
     SMTAffineTerm a = (SMTAffineTerm) subterm;
     constant = a.mConstant.mul(factor);
     summands = new HashMap<Term, Rational>();
     for (Map.Entry<Term, Rational> me : a.mSummands.entrySet()) {
       summands.put(me.getKey(), me.getValue().mul(factor));
     }
   } else if (subterm instanceof ConstantTerm) {
     Object value = ((ConstantTerm) subterm).getValue();
     if (value instanceof BigInteger) {
       constant = Rational.valueOf((BigInteger) value, BigInteger.ONE).mul(factor);
       summands = Collections.emptyMap();
     } else if (value instanceof BigDecimal) {
       BigDecimal decimal = (BigDecimal) value;
       if (decimal.scale() <= 0) {
         BigInteger num = decimal.toBigInteger();
         constant = Rational.valueOf(num, BigInteger.ONE).mul(factor);
       } else {
         BigInteger num = decimal.unscaledValue();
         BigInteger denom = BigInteger.TEN.pow(decimal.scale());
         constant = Rational.valueOf(num, denom).mul(factor);
       }
       summands = Collections.emptyMap();
     } else if (value instanceof Rational) {
       constant = (Rational) value;
       summands = Collections.emptyMap();
     } else {
       summands = Collections.singletonMap(subterm, factor);
       constant = Rational.ZERO;
     }
   } else {
     summands = Collections.singletonMap(subterm, factor);
     constant = Rational.ZERO;
   }
   return create(summands, constant, sort);
 }
Пример #9
0
  /**
   * Multiply a rational constant with this affine term.
   *
   * @param c the constant to multiply.
   * @return the product of this and the constant.
   */
  public SMTAffineTerm mul(Rational factor) {
    if (factor.equals(Rational.ZERO)) return create(Rational.ZERO, mSort);

    Rational constant = this.mConstant.mul(factor);
    HashMap<Term, Rational> summands = new HashMap<Term, Rational>();
    for (Map.Entry<Term, Rational> me : this.mSummands.entrySet()) {
      summands.put(me.getKey(), me.getValue().mul(factor));
    }
    return create(summands, constant, mSort);
  }
Пример #10
0
 public SMTAffineTerm addUnchecked(SMTAffineTerm a2, boolean sortCorrect) {
   Map<Term, Rational> summands = new HashMap<Term, Rational>();
   summands.putAll(this.mSummands);
   for (Map.Entry<Term, Rational> entry : a2.mSummands.entrySet()) {
     Term var = entry.getKey();
     if (summands.containsKey(var)) {
       Rational r = summands.get(var).add(entry.getValue());
       if (r.equals(Rational.ZERO)) summands.remove(var);
       else {
         summands.put(var, r);
       }
     } else {
       summands.put(var, entry.getValue());
     }
   }
   return create(
       summands,
       mConstant.add(a2.mConstant),
       sortCorrect ? mSort : a2.getSort().getName().equals("Real") ? a2.getSort() : mSort);
 }
 @Override
 protected void convert(Term term) {
   if (term instanceof ConstantTerm) {
     ConstantTerm ct = (ConstantTerm) term;
     if (ct.getValue() instanceof BigInteger) {
       Rational rat = Rational.valueOf((BigInteger) ct.getValue(), BigInteger.ONE);
       setResult(rat.toTerm(term.getSort()));
     } else if (ct.getValue() instanceof BigDecimal) {
       BigDecimal decimal = (BigDecimal) ct.getValue();
       Rational rat;
       if (decimal.scale() <= 0) {
         BigInteger num = decimal.toBigInteger();
         rat = Rational.valueOf(num, BigInteger.ONE);
       } else {
         BigInteger num = decimal.unscaledValue();
         BigInteger denom = BigInteger.TEN.pow(decimal.scale());
         rat = Rational.valueOf(num, denom);
       }
       setResult(rat.toTerm(term.getSort()));
     } else if (ct.getValue() instanceof Rational) setResult(ct);
     else setResult(term);
   } else super.convert(term);
 }
Пример #12
0
 private SMTAffineTerm(Map<Term, Rational> summands, Rational constant, Sort sort) {
   super(constant.hashCode() * 11 + summands.hashCode() + 1423 * sort.hashCode());
   mSort = sort;
   mSummands = summands;
   mConstant = constant;
 }
Пример #13
0
 public boolean equals(Object o) { // NOCHECKSTYLE
   if (!(o instanceof SMTAffineTerm)) return false;
   SMTAffineTerm l = (SMTAffineTerm) o;
   return mSort == l.mSort && mConstant.equals(l.mConstant) && mSummands.equals(l.mSummands);
 }
Пример #14
0
 public SMTAffineTerm div(Rational c) {
   return mul(c.inverse());
 }
Пример #15
0
 /**
  * Add a rational constant to this affine term.
  *
  * @param c the constant to add.
  * @return the sum of this and the constant.
  */
 public SMTAffineTerm add(Rational c) {
   return create(mSummands, mConstant.add(c), mSort);
 }