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; }
/** * 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); }
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(); }
/** * 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); }
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; }
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); }
/** * 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); }
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); }
/** * 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); }
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); }
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; }
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); }
public SMTAffineTerm div(Rational c) { return mul(c.inverse()); }
/** * 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); }