mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Support all fractional constants.
This commit is contained in:
parent
cd3b7e333d
commit
68bfbdb2a6
@ -411,8 +411,6 @@ void BooleanLPSolver::addLetBindings(Expression const& _let, LetBindings& _letBi
|
||||
|
||||
optional<Literal> BooleanLPSolver::parseLiteral(smtutil::Expression const& _expr, LetBindings _letBindings)
|
||||
{
|
||||
// TODO constanst true/false?
|
||||
|
||||
if (_expr.name == "let")
|
||||
{
|
||||
addLetBindings(_expr, _letBindings);
|
||||
@ -430,6 +428,11 @@ optional<Literal> BooleanLPSolver::parseLiteral(smtutil::Expression const& _expr
|
||||
else
|
||||
varIndex = std::get<size_t>(binding);
|
||||
}
|
||||
else if (_expr.name == "true" || _expr.name == "false")
|
||||
{
|
||||
// TODO handle this better
|
||||
solAssert(false, "True/false literals not implemented");
|
||||
}
|
||||
else
|
||||
varIndex = state().variables.at(_expr.name);
|
||||
solAssert(isBooleanVariable(varIndex));
|
||||
@ -594,7 +597,7 @@ optional<LinearExpression> BooleanLPSolver::parseLinearSum(smtutil::Expression c
|
||||
// This will result in nullopt unless one of them is a constant.
|
||||
return parseLinearSum(_expr.arguments.at(0), _letBindings) * parseLinearSum(_expr.arguments.at(1), _letBindings);
|
||||
}
|
||||
else if (_expr.name == "/")
|
||||
else if (_expr.name == "/" || _expr.name == "div")
|
||||
{
|
||||
solAssert(_expr.arguments.size() == 2);
|
||||
optional<LinearExpression> left = parseLinearSum(_expr.arguments.at(0), _letBindings);
|
||||
@ -614,19 +617,42 @@ optional<LinearExpression> BooleanLPSolver::parseLinearSum(smtutil::Expression c
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << _expr.toString() << endl;
|
||||
cerr << "Invalid operator " << _expr.name << endl;
|
||||
// cerr << _expr.toString() << endl;
|
||||
// cerr << "Invalid operator " << _expr.name << endl;
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool isNumber(string const& _expr)
|
||||
{
|
||||
return !_expr.empty() && (isDigit(_expr.front()) || _expr.front() == '.');
|
||||
}
|
||||
rational parseRational(string const& _atom)
|
||||
{
|
||||
size_t decimal = _atom.find('.');
|
||||
if (decimal == string::npos)
|
||||
return rational(bigint(_atom));
|
||||
|
||||
unsigned shift = static_cast<unsigned>(_atom.size() - decimal - 1);
|
||||
rational r(
|
||||
bigint(string(_atom.substr(0, decimal)) + string(_atom.substr(decimal + 1))),
|
||||
pow(bigint(10), shift)
|
||||
);
|
||||
// cerr << _atom << endl;
|
||||
// cerr << r << endl;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
bool BooleanLPSolver::isLiteral(smtutil::Expression const& _expr) const
|
||||
{
|
||||
if (!_expr.arguments.empty())
|
||||
return false;
|
||||
solAssert(!_expr.name.empty(), "");
|
||||
return
|
||||
('0' <= _expr.name[0] && _expr.name[0] <= '9') ||
|
||||
isNumber(_expr.name) ||
|
||||
_expr.name == "true" ||
|
||||
_expr.name == "false";
|
||||
}
|
||||
@ -635,8 +661,8 @@ optional<LinearExpression> BooleanLPSolver::parseFactor(smtutil::Expression cons
|
||||
{
|
||||
solAssert(_expr.arguments.empty(), "");
|
||||
solAssert(!_expr.name.empty(), "");
|
||||
if ('0' <= _expr.name[0] && _expr.name[0] <= '9')
|
||||
return LinearExpression::constant(rational(bigint(_expr.name)));
|
||||
if (isNumber(_expr.name))
|
||||
return LinearExpression::constant(parseRational(_expr.name));
|
||||
else if (_expr.name == "true")
|
||||
// TODO do we want to do this?
|
||||
return LinearExpression::constant(1);
|
||||
|
@ -129,21 +129,14 @@ string_view command(SMTLib2Expression const& _expr)
|
||||
return get<string_view>(items.front().data);
|
||||
}
|
||||
|
||||
// TODO If we want to return rational here, we need smtutil::Expression to support rationals...
|
||||
u256 parseRational(string_view _atom)
|
||||
{
|
||||
if (_atom.size() >= 3 && _atom.at(_atom.size() - 1) == '0' && _atom.at(_atom.size() - 2) == '.')
|
||||
return parseRational(_atom.substr(0, _atom.size() - 2));
|
||||
else
|
||||
return u256(_atom);
|
||||
}
|
||||
|
||||
smtutil::Expression toSMTUtilExpression(SMTLib2Expression const& _expr, map<string, SortPointer> const& _variableSorts)
|
||||
{
|
||||
return std::visit(GenericVisitor{
|
||||
[&](string_view const& _atom) {
|
||||
if (isDigit(_atom.front()) || _atom.front() == '.')
|
||||
return Expression(parseRational(_atom).str(), {}, SortProvider::realSort);
|
||||
if (_atom == "true" || _atom == "false")
|
||||
return Expression(_atom == "true");
|
||||
else if (isDigit(_atom.front()) || _atom.front() == '.')
|
||||
return Expression(string(_atom), {}, SortProvider::realSort);
|
||||
else
|
||||
return Expression(string(_atom), {}, _variableSorts.at(string(_atom)));
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user