mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
more code
This commit is contained in:
parent
b4dd0420ca
commit
c8c9067c9b
@ -24,6 +24,7 @@
|
|||||||
#include <libsolutil/Common.h>
|
#include <libsolutil/Common.h>
|
||||||
#include <libsolutil/Numeric.h>
|
#include <libsolutil/Numeric.h>
|
||||||
#include <libsolutil/CommonData.h>
|
#include <libsolutil/CommonData.h>
|
||||||
|
#include <libsolutil/StringUtils.h>
|
||||||
|
|
||||||
#include <range/v3/algorithm/all_of.hpp>
|
#include <range/v3/algorithm/all_of.hpp>
|
||||||
#include <range/v3/view.hpp>
|
#include <range/v3/view.hpp>
|
||||||
@ -489,6 +490,15 @@ public:
|
|||||||
std::vector<Expression> arguments;
|
std::vector<Expression> arguments;
|
||||||
SortPointer sort;
|
SortPointer sort;
|
||||||
|
|
||||||
|
std::string toString() const
|
||||||
|
{
|
||||||
|
if (arguments.empty())
|
||||||
|
return name;
|
||||||
|
std::vector<std::string> argsAsString;
|
||||||
|
for (auto const& arg: arguments)
|
||||||
|
argsAsString.emplace_back(arg.toString());
|
||||||
|
return name + "(" + util::joinHumanReadable(argsAsString) + ")";
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
/// Manual constructors, should only be used by SolverInterface and this class itself.
|
/// Manual constructors, should only be used by SolverInterface and this class itself.
|
||||||
Expression(std::string _name, std::vector<Expression> _arguments, Kind _kind):
|
Expression(std::string _name, std::vector<Expression> _arguments, Kind _kind):
|
||||||
|
@ -97,6 +97,7 @@ void BooleanLPSolver::declareVariable(string const& _name, SortPointer const& _s
|
|||||||
|
|
||||||
void BooleanLPSolver::addAssertion(Expression const& _expr)
|
void BooleanLPSolver::addAssertion(Expression const& _expr)
|
||||||
{
|
{
|
||||||
|
cout << " - " << _expr.toString() << endl;
|
||||||
solAssert(_expr.sort->kind == Kind::Bool);
|
solAssert(_expr.sort->kind == Kind::Bool);
|
||||||
if (_expr.arguments.empty())
|
if (_expr.arguments.empty())
|
||||||
{
|
{
|
||||||
@ -137,9 +138,7 @@ void BooleanLPSolver::addAssertion(Expression const& _expr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Expression left = parseLinearSumOrReturnEqualVariable(_expr.arguments.at(0));
|
solAssert(false);
|
||||||
Expression right = parseLinearSumOrReturnEqualVariable(_expr.arguments.at(1));
|
|
||||||
addAssertion(left == right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -184,9 +183,7 @@ void BooleanLPSolver::addAssertion(Expression const& _expr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Expression left = parseLinearSumOrReturnEqualVariable(_expr.arguments.at(0));
|
solAssert(false);
|
||||||
Expression right = parseLinearSumOrReturnEqualVariable(_expr.arguments.at(1));
|
|
||||||
addAssertion(left <= right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_expr.name == ">=")
|
else if (_expr.name == ">=")
|
||||||
@ -202,9 +199,9 @@ void BooleanLPSolver::addAssertion(Expression const& _expr)
|
|||||||
|
|
||||||
pair<CheckResult, vector<string>> BooleanLPSolver::check(vector<Expression> const&)
|
pair<CheckResult, vector<string>> BooleanLPSolver::check(vector<Expression> const&)
|
||||||
{
|
{
|
||||||
//cout << "Solving boolean constraint system" << endl;
|
cout << "Solving boolean constraint system" << endl;
|
||||||
//cout << toString() << endl;
|
cout << toString() << endl;
|
||||||
//cout << "--------------" << endl;
|
cout << "--------------" << endl;
|
||||||
|
|
||||||
if (state().infeasible)
|
if (state().infeasible)
|
||||||
return make_pair(CheckResult::UNSATISFIABLE, vector<string>{});
|
return make_pair(CheckResult::UNSATISFIABLE, vector<string>{});
|
||||||
@ -270,7 +267,8 @@ pair<CheckResult, vector<string>> BooleanLPSolver::check(vector<Expression> cons
|
|||||||
{
|
{
|
||||||
//cout << "==============> CDCL final result: SATisfiable / UNKNOWN." << endl;
|
//cout << "==============> CDCL final result: SATisfiable / UNKNOWN." << endl;
|
||||||
// TODO should be "unknown" later on
|
// TODO should be "unknown" later on
|
||||||
return {CheckResult::SATISFIABLE, {}};
|
//return {CheckResult::SATISFIABLE, {}};
|
||||||
|
return {CheckResult::UNKNOWN, {}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +372,8 @@ Literal BooleanLPSolver::negate(Literal const& _lit)
|
|||||||
|
|
||||||
Literal BooleanLPSolver::parseLiteralOrReturnEqualBoolean(Expression const& _expr)
|
Literal BooleanLPSolver::parseLiteralOrReturnEqualBoolean(Expression const& _expr)
|
||||||
{
|
{
|
||||||
|
if (_expr.sort->kind != Kind::Bool)
|
||||||
|
cout << "expected bool: " << _expr.toString() << endl;
|
||||||
solAssert(_expr.sort->kind == Kind::Bool);
|
solAssert(_expr.sort->kind == Kind::Bool);
|
||||||
// TODO when can this fail?
|
// TODO when can this fail?
|
||||||
if (optional<Literal> literal = parseLiteral(_expr))
|
if (optional<Literal> literal = parseLiteral(_expr))
|
||||||
@ -386,31 +386,7 @@ Literal BooleanLPSolver::parseLiteralOrReturnEqualBoolean(Expression const& _exp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression BooleanLPSolver::parseLinearSumOrReturnEqualVariable(Expression const& _expr)
|
optional<LinearExpression> BooleanLPSolver::parseLinearSum(smtutil::Expression const& _expr)
|
||||||
{
|
|
||||||
solAssert(_expr.sort->kind == Kind::Int);
|
|
||||||
if (_expr.name == "ite")
|
|
||||||
{
|
|
||||||
Literal condition = parseLiteralOrReturnEqualBoolean(_expr.arguments.at(0));
|
|
||||||
// TODO this adds too many variables
|
|
||||||
Expression conditionBoolean = declareInternalVariable(true);
|
|
||||||
addBooleanEquality(condition, conditionBoolean);
|
|
||||||
Expression trueValue = parseLinearSumOrReturnEqualVariable(_expr.arguments.at(1));
|
|
||||||
Expression falseValue = parseLinearSumOrReturnEqualVariable(_expr.arguments.at(2));
|
|
||||||
Expression result = declareInternalVariable(false);
|
|
||||||
addAssertion(conditionBoolean || (result == trueValue));
|
|
||||||
addAssertion(!conditionBoolean || (result == falseValue));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (_expr.arguments.empty())
|
|
||||||
return _expr;
|
|
||||||
solAssert(parseLinearSum(_expr));
|
|
||||||
Expression result = declareInternalVariable(false);
|
|
||||||
addAssertion(result == _expr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<LinearExpression> BooleanLPSolver::parseLinearSum(smtutil::Expression const& _expr) const
|
|
||||||
{
|
{
|
||||||
if (_expr.arguments.empty() || _expr.name == "*")
|
if (_expr.arguments.empty() || _expr.name == "*")
|
||||||
return parseProduct(_expr);
|
return parseProduct(_expr);
|
||||||
@ -422,10 +398,15 @@ optional<LinearExpression> BooleanLPSolver::parseLinearSum(smtutil::Expression c
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
return _expr.name == "+" ? *left + *right : *left - *right;
|
return _expr.name == "+" ? *left + *right : *left - *right;
|
||||||
}
|
}
|
||||||
|
else if (_expr.name == "ite")
|
||||||
|
{
|
||||||
|
Expression result = declareInternalVariable(false);
|
||||||
|
addAssertion(_expr.arguments.at(0) || (result == _expr.arguments.at(1)));
|
||||||
|
addAssertion(!_expr.arguments.at(0) || (result == _expr.arguments.at(2)));
|
||||||
|
return parseLinearSum(result);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TOOD This should just resort to parseLinearSumOrReturn...
|
|
||||||
// and then use that variable
|
|
||||||
cout << "Invalid operator " << _expr.name << endl;
|
cout << "Invalid operator " << _expr.name << endl;
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -87,14 +87,13 @@ private:
|
|||||||
Literal negate(Literal const& _lit);
|
Literal negate(Literal const& _lit);
|
||||||
|
|
||||||
Literal parseLiteralOrReturnEqualBoolean(smtutil::Expression const& _expr);
|
Literal parseLiteralOrReturnEqualBoolean(smtutil::Expression const& _expr);
|
||||||
smtutil::Expression parseLinearSumOrReturnEqualVariable(smtutil::Expression const& _expr);
|
|
||||||
|
|
||||||
/// Parses the expression and expects a linear sum of variables.
|
/// Parses the expression and expects a linear sum of variables.
|
||||||
/// Returns a vector with the first element being the constant and the
|
/// Returns a vector with the first element being the constant and the
|
||||||
/// other elements the factors for the respective variables.
|
/// other elements the factors for the respective variables.
|
||||||
/// If the expression cannot be properly parsed or is not linear,
|
/// If the expression cannot be properly parsed or is not linear,
|
||||||
/// returns an empty vector.
|
/// returns an empty vector.
|
||||||
std::optional<LinearExpression> parseLinearSum(smtutil::Expression const& _expression) const;
|
std::optional<LinearExpression> parseLinearSum(smtutil::Expression const& _expression);
|
||||||
std::optional<LinearExpression> parseProduct(smtutil::Expression const& _expression) const;
|
std::optional<LinearExpression> parseProduct(smtutil::Expression const& _expression) const;
|
||||||
std::optional<LinearExpression> parseFactor(smtutil::Expression const& _expression) const;
|
std::optional<LinearExpression> parseFactor(smtutil::Expression const& _expression) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user