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