bool TheoryArith::isSyntacticRational(const Expr& e, Rational& r) { if (e.getKind() == REAL_CONST) { r = e[0].getRational(); return true; } else if (e.isRational()) { r = e.getRational(); return true; } else if (isUMinus(e)) { if (isSyntacticRational(e[0], r)) { r = -r; return true; } } else if (isDivide(e)) { Rational num; if (isSyntacticRational(e[0], num)) { Rational den; if (isSyntacticRational(e[1], den)) { if (den != 0) { r = num / den; return true; } } } } return false; }
bool TheoryArith::leavesAreNumConst(const Expr& e) { DebugAssert(e.isTerm() || (e.isPropAtom() && theoryOf(e) == this), "Expected term or arith prop atom"); if (e.validTerminalsConstFlag()) { return e.getTerminalsConstFlag(); } if (e.isRational()) { e.setTerminalsConstFlag(true); return true; } if (e.isAtomic() && isLeaf(e)) { e.setTerminalsConstFlag(false); return false; } DebugAssert(e.arity() > 0, "Expected non-zero arity"); int k = 0; if (e.isITE()) { k = 1; } for (; k < e.arity(); ++k) { if (!leavesAreNumConst(e[k])) { e.setTerminalsConstFlag(false); return false; } } e.setTerminalsConstFlag(true); return true; }