mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add equality constraints.
This commit is contained in:
parent
33f0e0d4b2
commit
2108580df6
@ -330,7 +330,7 @@ optional<Literal> BooleanLPSolver::parseLiteral(smtutil::Expression const& _expr
|
||||
}
|
||||
else if (_expr.name == "not")
|
||||
return negate(parseLiteralOrReturnEqualBoolean(_expr.arguments.at(0)));
|
||||
else if (_expr.name == "<=")
|
||||
else if (_expr.name == "<=" || _expr.name == "=")
|
||||
{
|
||||
optional<LinearExpression> left = parseLinearSum(_expr.arguments.at(0));
|
||||
optional<LinearExpression> right = parseLinearSum(_expr.arguments.at(1));
|
||||
@ -340,7 +340,7 @@ optional<Literal> BooleanLPSolver::parseLiteral(smtutil::Expression const& _expr
|
||||
LinearExpression data = *left - *right;
|
||||
data[0] *= -1;
|
||||
|
||||
return Literal{true, addConditionalConstraint(Constraint{move(data), false, {}})};
|
||||
return Literal{true, addConditionalConstraint(Constraint{move(data), _expr.name == "=", {}})};
|
||||
}
|
||||
else if (_expr.name == ">=")
|
||||
return parseLiteral(_expr.arguments.at(1) <= _expr.arguments.at(0));
|
||||
@ -357,8 +357,36 @@ Literal BooleanLPSolver::negate(Literal const& _lit)
|
||||
if (isConditionalConstraint(_lit.variable))
|
||||
{
|
||||
Constraint const& c = conditionalConstraint(_lit.variable);
|
||||
solAssert(!c.equality, "");
|
||||
if (c.equality)
|
||||
{
|
||||
// X = b
|
||||
|
||||
// X <= b - 1
|
||||
Constraint le = c;
|
||||
le.equality = false;
|
||||
le.data[0] -= 1;
|
||||
le.reasons.clear();
|
||||
Literal leL{true, addConditionalConstraint(le)};
|
||||
|
||||
// X >= b + 1
|
||||
// -X <= -b - 1
|
||||
Constraint ge = c;
|
||||
ge.equality = false;
|
||||
ge.data *= -1;
|
||||
ge.data[0] -= 1;
|
||||
ge.reasons.clear();
|
||||
Literal geL{true, addConditionalConstraint(ge)};
|
||||
|
||||
|
||||
Literal equalBoolean = *parseLiteral(declareInternalVariable(true));
|
||||
// a = or(x, y) <=> (-a \/ x \/ y) /\ (a \/ -x) /\ (a \/ -y)
|
||||
state().clauses.emplace_back(Clause{vector<Literal>{negate(equalBoolean), leL, geL}});
|
||||
state().clauses.emplace_back(Clause{vector<Literal>{equalBoolean, negate(leL)}});
|
||||
state().clauses.emplace_back(Clause{vector<Literal>{equalBoolean, negate(geL)}});
|
||||
return equalBoolean;
|
||||
}
|
||||
else
|
||||
{
|
||||
// X > b
|
||||
// -x < -b
|
||||
// -x <= -b - 1
|
||||
@ -369,6 +397,7 @@ Literal BooleanLPSolver::negate(Literal const& _lit)
|
||||
negated.reasons.clear();
|
||||
return Literal{true, addConditionalConstraint(negated)};
|
||||
}
|
||||
}
|
||||
else
|
||||
return ~_lit;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user