Skip to content

Commit 32f3743

Browse files
committed
NonlinWork: moved and updated the Nonlin checks, tests rework, exception upd
1 parent 8d8657a commit 32f3743

24 files changed

+61
-81
lines changed

src/itehandler/IteToSwitch.cc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,6 @@ ite::Dag IteToSwitch::constructIteDag(PTRef root, Logic const & logic) {
233233

234234
} else { // not Ite
235235
for (PTRef child : t) {
236-
if (logic.hasIntegers() || logic.hasReals()) {
237-
if (logic.isNonlin(child)) {
238-
auto termStr = logic.pp(child);
239-
throw ApiException("Nonlinear operations in the formula: " + termStr);
240-
}
241-
}
242236
if (logic.isIte(child) and !dag.isTopLevelIte(child)) {
243237
// Term child is an ite which appears as a child of a non-ite.
244238
// We store this term for an expansion into a switch.

src/logics/ArithLogic.cc

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,25 @@ bool ArithLogic::isLinearTerm(PTRef tr) const {
195195
}
196196

197197
bool ArithLogic::isNonlin(PTRef tr) const {
198+
if (isPlus(tr)) {
199+
Pterm const & term = getPterm(tr);
200+
for (auto subterm : term) {
201+
if (isNonlin(subterm)) return true;
202+
}
203+
}
198204
if (isTimes(tr)) {
199205
Pterm const & term = getPterm(tr);
200-
return (not isConstant(term[0]) && not isConstant(term[1]));
206+
if (not isConstant(term[0]) && not isConstant(term[1])) return true;
207+
for (auto subterm : term) {
208+
if (isNonlin(subterm)) return true;
209+
}
201210
}
202211
if (isRealDiv(tr) || isIntDiv(tr) || isMod(getPterm(tr).symb())) {
203212
Pterm const & term = getPterm(tr);
204-
return (not isConstant(term[1]));
213+
if (not isConstant(term[1])) return true;
214+
for (auto subterm : term) {
215+
if (isNonlin(subterm)) return true;
216+
}
205217
}
206218
return false;
207219
};
@@ -419,13 +431,12 @@ lbool ArithLogic::arithmeticElimination(vec<PTRef> const & top_level_arith, Subs
419431
PTRef lhs = logic.getPterm(eq)[0];
420432
PTRef rhs = logic.getPterm(eq)[1];
421433
PTRef polyTerm = lhs == logic.getZeroForSort(logic.getSortRef(lhs)) ? rhs : logic.mkMinus(rhs, lhs);
422-
assert(logic.isLinearTerm(polyTerm));
423434
if (logic.isLinearFactor(polyTerm)) {
424435
auto [var, c] = logic.splitTermToVarAndConst(polyTerm);
425436
auto coeff = logic.getNumConst(c);
426437
poly.addTerm(var, std::move(coeff));
427438
} else {
428-
assert(logic.isPlus(polyTerm));
439+
assert(logic.isPlus(polyTerm) || logic.isTimes(polyTerm));
429440
for (PTRef factor : logic.getPterm(polyTerm)) {
430441
auto [var, c] = logic.splitTermToVarAndConst(factor);
431442
auto coeff = logic.getNumConst(c);

src/logics/ArithLogic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ class ArithLogic : public Logic {
235235

236236
// Real terms are of form c, a, or (* c a) where c is a constant and a is a variable or Ite.
237237
bool isNumTerm(PTRef tr) const;
238-
bool isNonlin(PTRef tr) const override;
238+
bool isNonlin(PTRef tr) const;
239239

240240
PTRef getTerm_IntZero() const { return term_Int_ZERO; }
241241
PTRef getTerm_RealZero() const { return term_Real_ZERO; }

src/logics/Logic.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ class Logic {
251251
bool isDisequality(PTRef tr) const; // { return disequalities.has(term_store[tr].symb()); }
252252
bool isIte(SymRef tr) const; // { return ites.has(tr); }
253253
bool isIte(PTRef tr) const; // { return ites.has(term_store[tr].symb()); }
254-
virtual bool isNonlin(PTRef) const { return false; }
255254
bool isNonBoolIte(SymRef sr) const { return isIte(sr) and getSortRef(sr) != sort_BOOL; }
256255
bool isNonBoolIte(PTRef tr) const { return isNonBoolIte(getPterm(tr).symb()); }
257256

src/rewriters/DivModRewriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class DivModConfig : public DefaultRewriterConfig {
3636
PTRef modVar = divMod.mod;
3737
PTRef rewritten = logic.isIntDiv(symRef) ? divVar : modVar;
3838
if (not inCache) {
39+
if (logic.isNonlin(term)) { return term; }
3940
// collect the definitions to add
4041
assert(logic.isConstant(divisor));
4142
auto divisorVal = logic.getNumConst(divisor);

src/tsolvers/lasolver/LASolver.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ void LASolver::isProperLeq(PTRef tr)
9191
assert(logic.isLeq(tr));
9292
auto [cons, sum] = logic.leqToConstantAndTerm(tr);
9393
assert(logic.isConstant(cons));
94-
assert(logic.isNumVar(sum) || logic.isPlus(sum) || logic.isTimes(sum));
95-
assert(!logic.isTimes(sum) || ((logic.isNumVar(logic.getPterm(sum)[0]) && logic.isOne(logic.mkNeg(logic.getPterm(sum)[1]))) ||
96-
(logic.isNumVar(logic.getPterm(sum)[1]) && logic.isOne(logic.mkNeg(logic.getPterm(sum)[0])))));
94+
assert(logic.isNumVar(sum) || logic.isPlus(sum) || logic.isTimes(sum) || logic.isMod(logic.getPterm(sum).symb()) ||
95+
logic.isRealDiv(sum) || logic.isIntDiv(sum));
9796
(void) cons; (void)sum;
9897
}
9998

@@ -288,6 +287,10 @@ std::unique_ptr<Tableau::Polynomial> LASolver::expressionToLVarPoly(PTRef term)
288287
//
289288
// Returns internalized reference for the term
290289
LVRef LASolver::registerArithmeticTerm(PTRef expr) {
290+
if (logic.isNonlin(expr)) {
291+
auto termStr = logic.pp(expr);
292+
throw LANonLinearException(termStr.c_str());
293+
}
291294
LVRef x = LVRef::Undef;
292295
if (laVarMapper.hasVar(expr)){
293296
x = getVarForTerm(expr);

src/tsolvers/lasolver/LASolver.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@
2323
#include <unordered_set>
2424

2525
namespace opensmt {
26+
class LANonLinearException : public std::runtime_error {
27+
public:
28+
LANonLinearException(char const * reason_) : runtime_error(reason_) {
29+
msg = "Term " + std::string(reason_) + " is non-linear";
30+
}
31+
virtual char const * what() const noexcept override { return msg.c_str(); }
32+
33+
private:
34+
std::string msg;
35+
};
36+
2637
class LAVarStore;
2738
class Delta;
2839
class PartitionManager;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
terminate called after throwing an instance of 'opensmt::LANonLinearException'
2+
what(): Term (* -1 (* x y)) is non-linear
3+
Aborted
Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +0,0 @@
1-
(error "Nonlinear operations in the formula: (* x y)")
2-
3-
sat
4-
(
5-
(define-fun x () Int
6-
0)
7-
(define-fun y () Int
8-
0)
9-
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
terminate called after throwing an instance of 'opensmt::LANonLinearException'
2+
what(): Term (* -1 (/ y x)) is non-linear
3+
Aborted

0 commit comments

Comments
 (0)