mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
implemert strict comparisons
This commit is contained in:
parent
b76d3a6a0d
commit
074969b5d9
@ -342,7 +342,7 @@ void BooleanLPSolver::addLetBindings(Expression const& _let, map<string, size_t>
|
|||||||
bool isBool = binding.arguments.at(0).sort->kind == Kind::Bool;
|
bool isBool = binding.arguments.at(0).sort->kind == Kind::Bool;
|
||||||
Expression var = declareInternalVariable(isBool);
|
Expression var = declareInternalVariable(isBool);
|
||||||
newBindings.insert({binding.name, state().variables.at(var.name)});
|
newBindings.insert({binding.name, state().variables.at(var.name)});
|
||||||
addAssertion(var == binding.arguments.at(0));
|
addAssertion(var == binding.arguments.at(0), _letBindings);
|
||||||
}
|
}
|
||||||
for (auto&& [name, varIndex]: newBindings)
|
for (auto&& [name, varIndex]: newBindings)
|
||||||
_letBindings.insert({name, varIndex});
|
_letBindings.insert({name, varIndex});
|
||||||
@ -429,6 +429,7 @@ Literal BooleanLPSolver::negate(Literal const& _lit)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// TODO We can only do this if we know it is an integer!
|
||||||
// X > b
|
// X > b
|
||||||
// -x < -b
|
// -x < -b
|
||||||
// -x <= -b - 1
|
// -x <= -b - 1
|
||||||
|
@ -47,6 +47,56 @@ struct Constraint
|
|||||||
bool operator==(Constraint const& _other) const;
|
bool operator==(Constraint const& _other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A two-dimensional rational number "a + b*delta" that can be used to perform strict comparisons:
|
||||||
|
* x > 0 is transformed into x >= 1*delta, where delta is assumed to be "small". Its value
|
||||||
|
* is never explicitly computed / set, it is just a symbolic parameter.
|
||||||
|
*/
|
||||||
|
class RationalWithDelta
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RationalWithDelta(rational _x): m_main(move(_x)) {}
|
||||||
|
static RationalWithDelta delta()
|
||||||
|
{
|
||||||
|
RationalWithDelta x(0);
|
||||||
|
x.m_delta = 1;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
RationalWithDelta& operator+=(RationalWithDelta const& _other)
|
||||||
|
{
|
||||||
|
m_main += _other.m_main;
|
||||||
|
m_delta += _other.m_delta;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
RationalWithDelta& operator*=(rational const& _factor)
|
||||||
|
{
|
||||||
|
m_main *= _factor;
|
||||||
|
m_delta *= _factor;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator<=(RationalWithDelta const& _other)
|
||||||
|
{
|
||||||
|
return std::tie(m_main, m_delta) <= std::tie(_other.m_main, _other.m_delta);
|
||||||
|
}
|
||||||
|
bool operator<(RationalWithDelta const& _other)
|
||||||
|
{
|
||||||
|
return std::tie(m_main, m_delta) < std::tie(_other.m_main, _other.m_delta);
|
||||||
|
}
|
||||||
|
bool operator==(RationalWithDelta const& _other)
|
||||||
|
{
|
||||||
|
return std::tie(m_main, m_delta) == std::tie(_other.m_main, _other.m_delta);
|
||||||
|
}
|
||||||
|
bool operator!=(RationalWithDelta const& _other)
|
||||||
|
{
|
||||||
|
return std::tie(m_main, m_delta) != std::tie(_other.m_main, _other.m_delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
rational m_main;
|
||||||
|
rational m_delta;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State used when solving an LP problem.
|
* State used when solving an LP problem.
|
||||||
*/
|
*/
|
||||||
|
@ -249,15 +249,19 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin(
|
|||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
case evmasm::Instruction::LT:
|
case evmasm::Instruction::LT:
|
||||||
|
// TODO use x <= y - 1 directly?
|
||||||
return booleanValue(arguments.at(0) < arguments.at(1));
|
return booleanValue(arguments.at(0) < arguments.at(1));
|
||||||
case evmasm::Instruction::SLT:
|
case evmasm::Instruction::SLT:
|
||||||
|
// TODO use x <= y - 1 directly?
|
||||||
return booleanValue(
|
return booleanValue(
|
||||||
twosComplementToUpscaledUnsigned(arguments.at(0)) + smtutil::Expression(bigint(1) << 256) <
|
twosComplementToUpscaledUnsigned(arguments.at(0)) + smtutil::Expression(bigint(1) << 256) <
|
||||||
twosComplementToUpscaledUnsigned(arguments.at(1)) + smtutil::Expression(bigint(1) << 256)
|
twosComplementToUpscaledUnsigned(arguments.at(1)) + smtutil::Expression(bigint(1) << 256)
|
||||||
);
|
);
|
||||||
case evmasm::Instruction::GT:
|
case evmasm::Instruction::GT:
|
||||||
|
// TODO use x >= y + 1 directly!
|
||||||
return booleanValue(arguments.at(0) > arguments.at(1));
|
return booleanValue(arguments.at(0) > arguments.at(1));
|
||||||
case evmasm::Instruction::SGT:
|
case evmasm::Instruction::SGT:
|
||||||
|
// TODO use x >= y + 1 directly!
|
||||||
return booleanValue(
|
return booleanValue(
|
||||||
twosComplementToUpscaledUnsigned(arguments.at(0)) + smtutil::Expression(bigint(1) << 256) >
|
twosComplementToUpscaledUnsigned(arguments.at(0)) + smtutil::Expression(bigint(1) << 256) >
|
||||||
twosComplementToUpscaledUnsigned(arguments.at(1)) + smtutil::Expression(bigint(1) << 256)
|
twosComplementToUpscaledUnsigned(arguments.at(1)) + smtutil::Expression(bigint(1) << 256)
|
||||||
|
Loading…
Reference in New Issue
Block a user