mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
remove couts
This commit is contained in:
parent
a3a0f1d95b
commit
6b7c200891
@ -178,9 +178,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>{});
|
||||||
@ -200,8 +200,8 @@ pair<CheckResult, vector<string>> BooleanLPSolver::check(vector<Expression> cons
|
|||||||
else
|
else
|
||||||
resizeAndSet(lpState.variableNames, index, name);
|
resizeAndSet(lpState.variableNames, index, name);
|
||||||
|
|
||||||
cout << "Boolean variables:" << joinHumanReadable(booleanVariables) << endl;
|
//cout << "Boolean variables:" << joinHumanReadable(booleanVariables) << endl;
|
||||||
cout << "Running LP solver on fixed constraints." << endl;
|
//cout << "Running LP solver on fixed constraints." << endl;
|
||||||
if (m_lpSolver.check(lpState).first == LPResult::Infeasible)
|
if (m_lpSolver.check(lpState).first == LPResult::Infeasible)
|
||||||
return {CheckResult::UNSATISFIABLE, {}};
|
return {CheckResult::UNSATISFIABLE, {}};
|
||||||
|
|
||||||
@ -239,12 +239,12 @@ pair<CheckResult, vector<string>> BooleanLPSolver::check(vector<Expression> cons
|
|||||||
auto optionalModel = CDCL{move(booleanVariables), clauses, theorySolver}.solve();
|
auto optionalModel = CDCL{move(booleanVariables), clauses, theorySolver}.solve();
|
||||||
if (!optionalModel)
|
if (!optionalModel)
|
||||||
{
|
{
|
||||||
cout << "==============> CDCL final result: unsatisfiable." << endl;
|
//cout << "==============> CDCL final result: unsatisfiable." << endl;
|
||||||
return {CheckResult::UNSATISFIABLE, {}};
|
return {CheckResult::UNSATISFIABLE, {}};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "==============> CDCL final result: SATisfiable / UNKNON." << endl;
|
//cout << "==============> CDCL final result: SATisfiable / UNKNON." << endl;
|
||||||
// TODO should be "unknown" later on
|
// TODO should be "unknown" later on
|
||||||
return {CheckResult::SATISFIABLE, {}};
|
return {CheckResult::SATISFIABLE, {}};
|
||||||
}
|
}
|
||||||
|
@ -45,24 +45,24 @@ CDCL::CDCL(
|
|||||||
|
|
||||||
optional<CDCL::Model> CDCL::solve()
|
optional<CDCL::Model> CDCL::solve()
|
||||||
{
|
{
|
||||||
cout << "====" << endl;
|
// cout << "====" << endl;
|
||||||
for (unique_ptr<Clause> const& c: m_clauses)
|
// for (unique_ptr<Clause> const& c: m_clauses)
|
||||||
cout << toString(*c) << endl;
|
// cout << toString(*c) << endl;
|
||||||
cout << "====" << endl;
|
// cout << "====" << endl;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
optional<Clause> conflictClause = propagate();
|
optional<Clause> conflictClause = propagate();
|
||||||
if (!conflictClause && m_theorySolver)
|
if (!conflictClause && m_theorySolver)
|
||||||
{
|
{
|
||||||
conflictClause = m_theorySolver(m_assignments);
|
conflictClause = m_theorySolver(m_assignments);
|
||||||
if (conflictClause)
|
// if (conflictClause)
|
||||||
cout << "Theory gave us conflict: " << toString(*conflictClause) << endl;
|
// cout << "Theory gave us conflict: " << toString(*conflictClause) << endl;
|
||||||
}
|
}
|
||||||
if (conflictClause)
|
if (conflictClause)
|
||||||
{
|
{
|
||||||
if (currentDecisionLevel() == 0)
|
if (currentDecisionLevel() == 0)
|
||||||
{
|
{
|
||||||
cout << "Unsatisfiable" << endl;
|
// cout << "Unsatisfiable" << endl;
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
auto&& [learntClause, backtrackLevel] = analyze(move(*conflictClause));
|
auto&& [learntClause, backtrackLevel] = analyze(move(*conflictClause));
|
||||||
@ -80,14 +80,14 @@ optional<CDCL::Model> CDCL::solve()
|
|||||||
if (auto variable = nextDecisionVariable())
|
if (auto variable = nextDecisionVariable())
|
||||||
{
|
{
|
||||||
m_decisionPoints.emplace_back(m_assignmentTrail.size());
|
m_decisionPoints.emplace_back(m_assignmentTrail.size());
|
||||||
cout << "Deciding on " << m_variables.at(*variable) << " @" << currentDecisionLevel() << endl;
|
// cout << "Deciding on " << m_variables.at(*variable) << " @" << currentDecisionLevel() << endl;
|
||||||
enqueue(Literal{false, *variable}, nullptr);
|
enqueue(Literal{false, *variable}, nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "satisfiable." << endl;
|
//cout << "satisfiable." << endl;
|
||||||
for (auto&& [var, value]: m_assignments)
|
//for (auto&& [i, value]: m_assignments | ranges::view::enumerate())
|
||||||
cout << " " << m_variables.at(var) << ": " << (value ? "true" : "false") << endl;
|
// cout << " " << m_variables.at(i) << ": " << value.toString() << endl;
|
||||||
return m_assignments;
|
return m_assignments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,12 +102,12 @@ void CDCL::setupWatches(Clause& _clause)
|
|||||||
|
|
||||||
optional<Clause> CDCL::propagate()
|
optional<Clause> CDCL::propagate()
|
||||||
{
|
{
|
||||||
cout << "Propagating." << endl;
|
//cout << "Propagating." << endl;
|
||||||
for (; m_assignmentQueuePointer < m_assignmentTrail.size(); m_assignmentQueuePointer++)
|
for (; m_assignmentQueuePointer < m_assignmentTrail.size(); m_assignmentQueuePointer++)
|
||||||
{
|
{
|
||||||
Literal toPropagate = m_assignmentTrail.at(m_assignmentQueuePointer);
|
Literal toPropagate = m_assignmentTrail.at(m_assignmentQueuePointer);
|
||||||
Literal falseLiteral = ~toPropagate;
|
Literal falseLiteral = ~toPropagate;
|
||||||
cout << "Propagating " << toString(toPropagate) << endl;
|
//cout << "Propagating " << toString(toPropagate) << endl;
|
||||||
// Go through all watched clauses where this assignment makes the literal false.
|
// Go through all watched clauses where this assignment makes the literal false.
|
||||||
vector<Clause*> watchReplacement;
|
vector<Clause*> watchReplacement;
|
||||||
auto it = m_watches[falseLiteral].begin();
|
auto it = m_watches[falseLiteral].begin();
|
||||||
@ -115,7 +115,7 @@ optional<Clause> CDCL::propagate()
|
|||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
{
|
{
|
||||||
Clause& clause = **it;
|
Clause& clause = **it;
|
||||||
cout << " watch clause: " << toString(clause) << endl;
|
//cout << " watch clause: " << toString(clause) << endl;
|
||||||
|
|
||||||
solAssert(!clause.empty());
|
solAssert(!clause.empty());
|
||||||
if (clause.front() != falseLiteral)
|
if (clause.front() != falseLiteral)
|
||||||
@ -124,7 +124,7 @@ optional<Clause> CDCL::propagate()
|
|||||||
if (clause.size() >= 2 && isAssignedTrue(clause[1]))
|
if (clause.size() >= 2 && isAssignedTrue(clause[1]))
|
||||||
{
|
{
|
||||||
// Clause is already satisfied, keezp the watch.
|
// Clause is already satisfied, keezp the watch.
|
||||||
cout << " -> already satisfied by " << toString(clause[1]) << endl;
|
//cout << " -> already satisfied by " << toString(clause[1]) << endl;
|
||||||
watchReplacement.emplace_back(&clause);
|
watchReplacement.emplace_back(&clause);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ optional<Clause> CDCL::propagate()
|
|||||||
for (size_t i = 2; i < clause.size(); i++)
|
for (size_t i = 2; i < clause.size(); i++)
|
||||||
if (isUnknownOrAssignedTrue(clause[i]))
|
if (isUnknownOrAssignedTrue(clause[i]))
|
||||||
{
|
{
|
||||||
cout << " -> swapping " << toString(clause.front()) << " with " << toString(clause[i]) << endl;
|
//cout << " -> swapping " << toString(clause.front()) << " with " << toString(clause[i]) << endl;
|
||||||
swap(clause.front(), clause[i]);
|
swap(clause.front(), clause[i]);
|
||||||
m_watches[clause.front()].emplace_back(&clause);
|
m_watches[clause.front()].emplace_back(&clause);
|
||||||
break;
|
break;
|
||||||
@ -145,10 +145,10 @@ optional<Clause> CDCL::propagate()
|
|||||||
// are false, thus clause[1] has to be true (if it exists)
|
// are false, thus clause[1] has to be true (if it exists)
|
||||||
if (clause.size() == 1 || isAssignedFalse(clause[1]))
|
if (clause.size() == 1 || isAssignedFalse(clause[1]))
|
||||||
{
|
{
|
||||||
if (clause.size() >= 2)
|
// if (clause.size() >= 2)
|
||||||
cout << " - Propagate resulted in conflict because " << toString(clause[1]) << " is also false." << endl;
|
// cout << " - Propagate resulted in conflict because " << toString(clause[1]) << " is also false." << endl;
|
||||||
else
|
// else
|
||||||
cout << " - Propagate resulted in conflict since clause is single-literal." << endl;
|
// cout << " - Propagate resulted in conflict since clause is single-literal." << endl;
|
||||||
// Copy over the remaining watches and replace.
|
// Copy over the remaining watches and replace.
|
||||||
while (it != end) watchReplacement.emplace_back(move(*it++));
|
while (it != end) watchReplacement.emplace_back(move(*it++));
|
||||||
m_watches[falseLiteral] = move(watchReplacement);
|
m_watches[falseLiteral] = move(watchReplacement);
|
||||||
@ -158,7 +158,7 @@ optional<Clause> CDCL::propagate()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << " - resulted in new assignment: " << toString(clause[1]) << endl;
|
// cout << " - resulted in new assignment: " << toString(clause[1]) << endl;
|
||||||
watchReplacement.emplace_back(&clause);
|
watchReplacement.emplace_back(&clause);
|
||||||
enqueue(clause[1], &clause);
|
enqueue(clause[1], &clause);
|
||||||
}
|
}
|
||||||
@ -172,7 +172,7 @@ optional<Clause> CDCL::propagate()
|
|||||||
std::pair<Clause, size_t> CDCL::analyze(Clause _conflictClause)
|
std::pair<Clause, size_t> CDCL::analyze(Clause _conflictClause)
|
||||||
{
|
{
|
||||||
solAssert(!_conflictClause.empty());
|
solAssert(!_conflictClause.empty());
|
||||||
cout << "Analyzing conflict." << endl;
|
//cout << "Analyzing conflict." << endl;
|
||||||
Clause learntClause;
|
Clause learntClause;
|
||||||
size_t backtrackLevel = 0;
|
size_t backtrackLevel = 0;
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ std::pair<Clause, size_t> CDCL::analyze(Clause _conflictClause)
|
|||||||
optional<Literal> resolvingLiteral;
|
optional<Literal> resolvingLiteral;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
cout << " conflict clause: " << toString(_conflictClause) << endl;
|
//cout << " conflict clause: " << toString(_conflictClause) << endl;
|
||||||
for (Literal literal: _conflictClause)
|
for (Literal literal: _conflictClause)
|
||||||
if ((!resolvingLiteral || literal != *resolvingLiteral) && !seenVariables.count(literal.variable))
|
if ((!resolvingLiteral || literal != *resolvingLiteral) && !seenVariables.count(literal.variable))
|
||||||
{
|
{
|
||||||
@ -191,31 +191,31 @@ std::pair<Clause, size_t> CDCL::analyze(Clause _conflictClause)
|
|||||||
size_t variableLevel = m_levelForVariable.at(literal.variable);
|
size_t variableLevel = m_levelForVariable.at(literal.variable);
|
||||||
if (variableLevel == currentDecisionLevel())
|
if (variableLevel == currentDecisionLevel())
|
||||||
{
|
{
|
||||||
cout << " ignoring " << toString(literal) << " at current decision level." << endl;
|
//cout << " ignoring " << toString(literal) << " at current decision level." << endl;
|
||||||
// ignore variable, we will apply resolution with its reason.
|
// ignore variable, we will apply resolution with its reason.
|
||||||
pathCount++;
|
pathCount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << " adding " << toString(literal) << " @" << variableLevel << " to learnt clause." << endl;
|
//cout << " adding " << toString(literal) << " @" << variableLevel << " to learnt clause." << endl;
|
||||||
learntClause.push_back(literal);
|
learntClause.push_back(literal);
|
||||||
backtrackLevel = max(backtrackLevel, variableLevel);
|
backtrackLevel = max(backtrackLevel, variableLevel);
|
||||||
}
|
}
|
||||||
}
|
}/*
|
||||||
else
|
else
|
||||||
cout << " already seen " << toString(literal) << endl;
|
cout << " already seen " << toString(literal) << endl;*/
|
||||||
|
|
||||||
solAssert(pathCount > 0);
|
solAssert(pathCount > 0);
|
||||||
pathCount--;
|
pathCount--;
|
||||||
while (!seenVariables.count(m_assignmentTrail[trailIndex--].variable));
|
while (!seenVariables.count(m_assignmentTrail[trailIndex--].variable));
|
||||||
resolvingLiteral = m_assignmentTrail[trailIndex + 1];
|
resolvingLiteral = m_assignmentTrail[trailIndex + 1];
|
||||||
cout << " resolving literal: " << toString(*resolvingLiteral) << endl;
|
//cout << " resolving literal: " << toString(*resolvingLiteral) << endl;
|
||||||
seenVariables.erase(resolvingLiteral->variable);
|
seenVariables.erase(resolvingLiteral->variable);
|
||||||
// TODO Is there always a reason? Not if it's a decision variable.
|
// TODO Is there always a reason? Not if it's a decision variable.
|
||||||
if (pathCount > 0)
|
if (pathCount > 0)
|
||||||
{
|
{
|
||||||
_conflictClause = *m_reason.at(*resolvingLiteral);
|
_conflictClause = *m_reason.at(*resolvingLiteral);
|
||||||
cout << " reason: " << toString(_conflictClause) << endl;
|
//cout << " reason: " << toString(_conflictClause) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (pathCount > 0);
|
while (pathCount > 0);
|
||||||
@ -224,7 +224,7 @@ std::pair<Clause, size_t> CDCL::analyze(Clause _conflictClause)
|
|||||||
// Move to front so we can directly propagate.
|
// Move to front so we can directly propagate.
|
||||||
swap(learntClause.front(), learntClause.back());
|
swap(learntClause.front(), learntClause.back());
|
||||||
|
|
||||||
cout << "-> learnt clause: " << toString(learntClause) << " backtrack to " << backtrackLevel << endl;
|
//cout << "-> learnt clause: " << toString(learntClause) << " backtrack to " << backtrackLevel << endl;
|
||||||
|
|
||||||
|
|
||||||
return {move(learntClause), backtrackLevel};
|
return {move(learntClause), backtrackLevel};
|
||||||
@ -238,9 +238,11 @@ void CDCL::addClause(Clause _clause)
|
|||||||
|
|
||||||
void CDCL::enqueue(Literal const& _literal, Clause const* _reason)
|
void CDCL::enqueue(Literal const& _literal, Clause const* _reason)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
cout << "Enqueueing " << toString(_literal) << " @" << currentDecisionLevel() << endl;
|
cout << "Enqueueing " << toString(_literal) << " @" << currentDecisionLevel() << endl;
|
||||||
if (_reason)
|
if (_reason)
|
||||||
cout << " because of " << toString(*_reason) << endl;
|
cout << " because of " << toString(*_reason) << endl;
|
||||||
|
*/
|
||||||
// TODO assert that assignmnets was unknown
|
// TODO assert that assignmnets was unknown
|
||||||
m_assignments[_literal.variable] = _literal.positive;
|
m_assignments[_literal.variable] = _literal.positive;
|
||||||
m_levelForVariable[_literal.variable] = currentDecisionLevel();
|
m_levelForVariable[_literal.variable] = currentDecisionLevel();
|
||||||
@ -252,13 +254,13 @@ void CDCL::enqueue(Literal const& _literal, Clause const* _reason)
|
|||||||
void CDCL::cancelUntil(size_t _backtrackLevel)
|
void CDCL::cancelUntil(size_t _backtrackLevel)
|
||||||
{
|
{
|
||||||
// TODO what if we backtrack to zero?
|
// TODO what if we backtrack to zero?
|
||||||
cout << "Canceling until " << _backtrackLevel << endl;
|
//cout << "Canceling until " << _backtrackLevel << endl;
|
||||||
solAssert(m_assignmentQueuePointer == m_assignmentTrail.size());
|
solAssert(m_assignmentQueuePointer == m_assignmentTrail.size());
|
||||||
size_t assignmentsToUndo = m_assignmentTrail.size() - m_decisionPoints.at(_backtrackLevel);
|
size_t assignmentsToUndo = m_assignmentTrail.size() - m_decisionPoints.at(_backtrackLevel);
|
||||||
for (size_t i = 0; i < assignmentsToUndo; i++)
|
for (size_t i = 0; i < assignmentsToUndo; i++)
|
||||||
{
|
{
|
||||||
Literal l = m_assignmentTrail.back();
|
Literal l = m_assignmentTrail.back();
|
||||||
cout << " undoing " << toString(l) << endl;
|
//cout << " undoing " << toString(l) << endl;
|
||||||
m_assignmentTrail.pop_back();
|
m_assignmentTrail.pop_back();
|
||||||
m_assignments.erase(l.variable);
|
m_assignments.erase(l.variable);
|
||||||
m_reason.erase(l);
|
m_reason.erase(l);
|
||||||
|
@ -778,13 +778,13 @@ LPSolver::LPSolver(bool _supportModels):
|
|||||||
pair<LPResult, variant<Model, ReasonSet>> LPSolver::check(SolvingState _state)
|
pair<LPResult, variant<Model, ReasonSet>> LPSolver::check(SolvingState _state)
|
||||||
{
|
{
|
||||||
normalizeRowLengths(_state);
|
normalizeRowLengths(_state);
|
||||||
cout << "Running LP on:\n" << _state.toString() << endl;
|
//cout << "Running LP on:\n" << _state.toString() << endl;
|
||||||
|
|
||||||
auto&& [simplificationResult, modelOrReasonSet] = SolvingStateSimplifier{_state}.simplify();
|
auto&& [simplificationResult, modelOrReasonSet] = SolvingStateSimplifier{_state}.simplify();
|
||||||
switch (simplificationResult)
|
switch (simplificationResult)
|
||||||
{
|
{
|
||||||
case LPResult::Infeasible:
|
case LPResult::Infeasible:
|
||||||
cout << "-> LP infeasible." << endl;
|
//cout << "-> LP infeasible." << endl;
|
||||||
return {LPResult::Infeasible, modelOrReasonSet};
|
return {LPResult::Infeasible, modelOrReasonSet};
|
||||||
case LPResult::Feasible:
|
case LPResult::Feasible:
|
||||||
case LPResult::Unbounded:
|
case LPResult::Unbounded:
|
||||||
@ -808,7 +808,7 @@ pair<LPResult, variant<Model, ReasonSet>> LPSolver::check(SolvingState _state)
|
|||||||
|
|
||||||
if (auto conflict = boundsToConstraints(split))
|
if (auto conflict = boundsToConstraints(split))
|
||||||
{
|
{
|
||||||
cout << "-> LP infeasible." << endl;
|
//cout << "-> LP infeasible." << endl;
|
||||||
return {LPResult::Infeasible, move(*conflict)};
|
return {LPResult::Infeasible, move(*conflict)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,7 +839,7 @@ pair<LPResult, variant<Model, ReasonSet>> LPSolver::check(SolvingState _state)
|
|||||||
set<size_t> reasons;
|
set<size_t> reasons;
|
||||||
for (auto const& constraint: split.constraints)
|
for (auto const& constraint: split.constraints)
|
||||||
reasons += constraint.reasons;
|
reasons += constraint.reasons;
|
||||||
cout << "-> LP infeasible." << endl;
|
//cout << "-> LP infeasible." << endl;
|
||||||
return {LPResult::Infeasible, move(reasons)};
|
return {LPResult::Infeasible, move(reasons)};
|
||||||
}
|
}
|
||||||
case LPResult::Unknown:
|
case LPResult::Unknown:
|
||||||
@ -854,11 +854,11 @@ pair<LPResult, variant<Model, ReasonSet>> LPSolver::check(SolvingState _state)
|
|||||||
|
|
||||||
if (canOnlyBeUnknown)
|
if (canOnlyBeUnknown)
|
||||||
{
|
{
|
||||||
cout << "-> LP unknown." << endl;
|
//cout << "-> LP unknown." << endl;
|
||||||
return {LPResult::Unknown, Model{}};
|
return {LPResult::Unknown, Model{}};
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "-> LP feasible." << endl;
|
//cout << "-> LP feasible." << endl;
|
||||||
return {LPResult::Feasible, move(model)};
|
return {LPResult::Feasible, move(model)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user