This PR is one part of multiple.
Preliminary support means currently only supports single objective.
It supports queue-ing up objectives and it always optimizes the first.
Multiple-obj optimization algorithm will be up next.
* Refactor optimization result and objective classes
* Add preliminary support for multiple objectives
* The unit tests are now comparing node values instead of node addresses
+ aMod2PlusbMod2Div2));
}
-std::pair<OptResult, Node> OMTOptimizerBitVector::minimize(
- SmtEngine* parentSMTSolver, Node target)
+OptimizationResult OMTOptimizerBitVector::minimize(SmtEngine* parentSMTSolver,
+ TNode target)
{
// the smt engine to which we send intermediate queries
// for the binary search.
Node value;
if (intermediateSatResult.isUnknown())
{
- return std::make_pair(OptResult::OPT_UNKNOWN, value);
+ return OptimizationResult(OptimizationResult::UNKNOWN, value);
}
if (intermediateSatResult.isSat() == Result::UNSAT)
{
- return std::make_pair(OptResult::OPT_UNSAT, value);
+ return OptimizationResult(OptimizationResult::UNSAT, value);
}
// value equals to upperBound
intermediateSatResult = optChecker->checkSat();
if (intermediateSatResult.isUnknown() || intermediateSatResult.isNull())
{
- return std::make_pair(OptResult::OPT_UNKNOWN, value);
+ return OptimizationResult(OptimizationResult::UNKNOWN, value);
}
if (intermediateSatResult.isSat() == Result::SAT)
{
// lowerBound == pivot ==> upperbound = lowerbound + 1
// and lowerbound <= target < upperbound is UNSAT
// return the upperbound
- return std::make_pair(OptResult::OPT_OPTIMAL, value);
+ return OptimizationResult(OptimizationResult::OPTIMAL, value);
}
else
{
}
else
{
- return std::make_pair(OptResult::OPT_UNKNOWN, value);
+ return OptimizationResult(OptimizationResult::UNKNOWN, value);
}
optChecker->pop();
}
- return std::make_pair(OptResult::OPT_OPTIMAL, value);
+ return OptimizationResult(OptimizationResult::OPTIMAL, value);
}
-std::pair<OptResult, Node> OMTOptimizerBitVector::maximize(
- SmtEngine* parentSMTSolver, Node target)
+OptimizationResult OMTOptimizerBitVector::maximize(SmtEngine* parentSMTSolver,
+ TNode target)
{
// the smt engine to which we send intermediate queries
// for the binary search.
Node value;
if (intermediateSatResult.isUnknown())
{
- return std::make_pair(OptResult::OPT_UNKNOWN, value);
+ return OptimizationResult(OptimizationResult::UNKNOWN, value);
}
if (intermediateSatResult.isSat() == Result::UNSAT)
{
- return std::make_pair(OptResult::OPT_UNSAT, value);
+ return OptimizationResult(OptimizationResult::UNSAT, value);
}
// value equals to upperBound
intermediateSatResult = optChecker->checkSat();
if (intermediateSatResult.isUnknown() || intermediateSatResult.isNull())
{
- return std::make_pair(OptResult::OPT_UNKNOWN, value);
+ return OptimizationResult(OptimizationResult::UNKNOWN, value);
}
if (intermediateSatResult.isSat() == Result::SAT)
{
// upperbound = lowerbound + 1
// and lowerbound < target <= upperbound is UNSAT
// return the lowerbound
- return std::make_pair(OptResult::OPT_OPTIMAL, value);
+ return OptimizationResult(OptimizationResult::OPTIMAL, value);
}
else
{
}
else
{
- return std::make_pair(OptResult::OPT_UNKNOWN, value);
+ return OptimizationResult(OptimizationResult::UNKNOWN, value);
}
optChecker->pop();
}
- return std::make_pair(OptResult::OPT_OPTIMAL, value);
+ return OptimizationResult(OptimizationResult::OPTIMAL, value);
}
} // namespace cvc5::omt
public:
OMTOptimizerBitVector(bool isSigned);
virtual ~OMTOptimizerBitVector() = default;
- std::pair<smt::OptResult, Node> minimize(SmtEngine* parentSMTSolver,
- Node target) override;
- std::pair<smt::OptResult, Node> maximize(SmtEngine* parentSMTSolver,
- Node target) override;
+ smt::OptimizationResult minimize(SmtEngine* parentSMTSolver,
+ TNode target) override;
+ smt::OptimizationResult maximize(SmtEngine* parentSMTSolver,
+ TNode target) override;
private:
/**
using namespace cvc5::smt;
namespace cvc5::omt {
-std::pair<OptResult, Node> OMTOptimizerInteger::optimize(
- SmtEngine* parentSMTSolver, Node target, ObjectiveType objType)
+OptimizationResult OMTOptimizerInteger::optimize(
+ SmtEngine* parentSMTSolver,
+ TNode target,
+ OptimizationObjective::ObjectiveType objType)
{
// linear search for integer goal
// the smt engine to which we send intermediate queries
Node value;
if (intermediateSatResult.isUnknown())
{
- return std::make_pair(OptResult::OPT_UNKNOWN, value);
+ return OptimizationResult(OptimizationResult::UNKNOWN, value);
}
if (intermediateSatResult.isSat() == Result::UNSAT)
{
- return std::make_pair(OptResult::OPT_UNSAT, value);
+ return OptimizationResult(OptimizationResult::UNSAT, value);
}
// asserts objective > old_value (used in optimization loop)
Node increment;
Kind incrementalOperator = kind::NULL_EXPR;
- if (objType == ObjectiveType::OBJECTIVE_MINIMIZE)
+ if (objType == OptimizationObjective::MINIMIZE)
{
// if objective is MIN, then assert optimization_target <
// current_model_value
incrementalOperator = kind::LT;
}
- else if (objType == ObjectiveType::OBJECTIVE_MAXIMIZE)
+ else if (objType == OptimizationObjective::MAXIMIZE)
{
// if objective is MAX, then assert optimization_target >
// current_model_value
optChecker->assertFormula(increment);
intermediateSatResult = optChecker->checkSat();
}
- return std::make_pair(OptResult::OPT_OPTIMAL, value);
+ return OptimizationResult(OptimizationResult::OPTIMAL, value);
}
-std::pair<OptResult, Node> OMTOptimizerInteger::minimize(
- SmtEngine* parentSMTSolver, Node target)
+OptimizationResult OMTOptimizerInteger::minimize(
+ SmtEngine* parentSMTSolver, TNode target)
{
return this->optimize(
- parentSMTSolver, target, ObjectiveType::OBJECTIVE_MINIMIZE);
+ parentSMTSolver, target, OptimizationObjective::MINIMIZE);
}
-std::pair<OptResult, Node> OMTOptimizerInteger::maximize(
- SmtEngine* parentSMTSolver, Node target)
+OptimizationResult OMTOptimizerInteger::maximize(
+ SmtEngine* parentSMTSolver, TNode target)
{
return this->optimize(
- parentSMTSolver, target, ObjectiveType::OBJECTIVE_MAXIMIZE);
+ parentSMTSolver, target, OptimizationObjective::MAXIMIZE);
}
} // namespace cvc5::omt
public:
OMTOptimizerInteger() = default;
virtual ~OMTOptimizerInteger() = default;
- std::pair<smt::OptResult, Node> minimize(SmtEngine* parentSMTSolver,
- Node target) override;
- std::pair<smt::OptResult, Node> maximize(SmtEngine* parentSMTSolver,
- Node target) override;
+ smt::OptimizationResult minimize(SmtEngine* parentSMTSolver,
+ TNode target) override;
+ smt::OptimizationResult maximize(SmtEngine* parentSMTSolver,
+ TNode target) override;
private:
/**
* Handles the optimization query specified by objType
- * (objType = OBJECTIVE_MINIMIZE / OBJECTIVE_MAXIMIZE)
+ * (objType = MINIMIZE / MAXIMIZE)
**/
- std::pair<smt::OptResult, Node> optimize(SmtEngine* parentSMTSolver,
- Node target,
- smt::ObjectiveType objType);
+ smt::OptimizationResult optimize(
+ SmtEngine* parentSMTSolver,
+ TNode target,
+ smt::OptimizationObjective::ObjectiveType objType);
};
} // namespace cvc5::omt
using namespace cvc5::smt;
namespace cvc5::omt {
-std::unique_ptr<OMTOptimizer> OMTOptimizer::getOptimizerForNode(Node targetNode,
+std::unique_ptr<OMTOptimizer> OMTOptimizer::getOptimizerForNode(TNode targetNode,
bool isSigned)
{
// the datatype of the target node
* and this is the optimizer for targetNode
**/
static std::unique_ptr<OMTOptimizer> getOptimizerForNode(
- Node targetNode, bool isSigned = false);
+ TNode targetNode, bool isSigned = false);
/**
* Initialize an SMT subsolver for offline optimization purpose
* @param parentSMTSolver an SMT solver encoding the assertions as the
* constraints
* @param target the target expression to optimize
- * @return pair<OptResult, Node>: the result of optimization and the optimized
- * value, if OptResult is OPT_UNKNOWN, value returned could be empty node or
- * something suboptimal.
+ * @return smt::OptimizationResult the result of optimization, containing
+ * whether it's optimal and the optimized value.
**/
- virtual std::pair<smt::OptResult, Node> minimize(SmtEngine* parentSMTSolver,
- Node target) = 0;
+ virtual smt::OptimizationResult minimize(SmtEngine* parentSMTSolver,
+ TNode target) = 0;
/**
* Maximize the target node with constraints encoded in parentSMTSolver
*
* @param parentSMTSolver an SMT solver encoding the assertions as the
* constraints
* @param target the target expression to optimize
- * @return pair<OptResult, Node>: the result of optimization and the optimized
- * value, if OptResult is OPT_UNKNOWN, value returned could be empty node or
- * something suboptimal.
+ * @return smt::OptimizationResult the result of optimization, containing
+ * whether it's optimal and the optimized value.
**/
- virtual std::pair<smt::OptResult, Node> maximize(SmtEngine* parentSMTSolver,
- Node target) = 0;
+ virtual smt::OptimizationResult maximize(SmtEngine* parentSMTSolver,
+ TNode target) = 0;
};
} // namespace cvc5::omt
#include "smt/optimization_solver.h"
#include "omt/omt_optimizer.h"
+#include "smt/assertions.h"
using namespace cvc5::theory;
using namespace cvc5::omt;
namespace cvc5 {
namespace smt {
-/**
- * d_activatedObjective is initialized to a default objective:
- * default objective constructed with Null Node and OBJECTIVE_UNDEFINED
- *
- * d_savedValue is initialized to a default node (Null Node)
- */
-
-OptimizationSolver::OptimizationSolver(SmtEngine* parent)
- : d_parent(parent),
- d_activatedObjective(Node(), ObjectiveType::OBJECTIVE_UNDEFINED),
- d_savedValue()
+OptimizationResult::ResultType OptimizationSolver::checkOpt()
{
-}
-
-OptimizationSolver::~OptimizationSolver() {}
-
-OptResult OptimizationSolver::checkOpt()
-{
- // Make sure that the objective is not the default one
- Assert(d_activatedObjective.getType() != ObjectiveType::OBJECTIVE_UNDEFINED);
- Assert(!d_activatedObjective.getNode().isNull());
-
+ Assert(d_objectives.size() == 1);
+ // NOTE: currently we are only dealing with single obj
std::unique_ptr<OMTOptimizer> optimizer = OMTOptimizer::getOptimizerForNode(
- d_activatedObjective.getNode(), d_activatedObjective.getSigned());
+ d_objectives[0].getTarget(), d_objectives[0].bvIsSigned());
- Assert(optimizer != nullptr);
+ if (!optimizer) return OptimizationResult::UNSUPPORTED;
- std::pair<OptResult, Node> optResult;
- if (d_activatedObjective.getType() == ObjectiveType::OBJECTIVE_MAXIMIZE)
+ OptimizationResult optResult;
+ if (d_objectives[0].getType() == OptimizationObjective::MAXIMIZE)
{
- optResult = optimizer->maximize(this->d_parent,
- this->d_activatedObjective.getNode());
+ optResult = optimizer->maximize(d_parent, d_objectives[0].getTarget());
}
- else if (d_activatedObjective.getType() == ObjectiveType::OBJECTIVE_MINIMIZE)
+ else if (d_objectives[0].getType() == OptimizationObjective::MINIMIZE)
{
- optResult = optimizer->minimize(this->d_parent,
- this->d_activatedObjective.getNode());
+ optResult = optimizer->minimize(d_parent, d_objectives[0].getTarget());
}
- this->d_savedValue = optResult.second;
- return optResult.first;
+ d_results[0] = optResult;
+ return optResult.getType();
}
-void OptimizationSolver::activateObj(const Node& obj,
- const ObjectiveType type,
- bool bvSigned)
+void OptimizationSolver::pushObjective(
+ TNode target, OptimizationObjective::ObjectiveType type, bool bvSigned)
{
- d_activatedObjective = Objective(obj, type, bvSigned);
+ d_objectives.emplace_back(target, type, bvSigned);
+ d_results.emplace_back(OptimizationResult::UNSUPPORTED, Node());
}
-Node OptimizationSolver::objectiveGetValue()
+void OptimizationSolver::popObjective()
{
- Assert(!d_savedValue.isNull());
- return d_savedValue;
+ d_objectives.pop_back();
+ d_results.pop_back();
}
-Objective::Objective(Node obj, ObjectiveType type, bool bvSigned)
- : d_type(type), d_node(obj), d_bvSigned(bvSigned)
+std::vector<OptimizationResult> OptimizationSolver::getValues()
{
+ Assert(d_objectives.size() == d_results.size());
+ return d_results;
}
-ObjectiveType Objective::getType() { return d_type; }
-
-Node Objective::getNode() { return d_node; }
-
-bool Objective::getSigned() { return d_bvSigned; }
-
} // namespace smt
} // namespace cvc5
#include "expr/node.h"
#include "expr/type_node.h"
-#include "smt/assertions.h"
#include "util/result.h"
namespace cvc5 {
namespace smt {
/**
- * An enum for optimization queries.
- *
- * Represents whether an objective should be minimized or maximized
- */
-enum class ObjectiveType
-{
- OBJECTIVE_MINIMIZE,
- OBJECTIVE_MAXIMIZE,
- OBJECTIVE_UNDEFINED
-};
-
-/**
- * An enum for optimization queries.
- *
- * Represents the result of a checkopt query
- * (unimplemented) OPT_OPTIMAL: if value was found
+ * The optimization result of an optimization objective
+ * containing:
+ * - whether it's optimal or not
+ * - if so, the optimal value, otherwise the value might be empty node or
+ * something suboptimal
*/
-enum class OptResult
+class OptimizationResult
{
- // the original set of assertions has result UNKNOWN
- OPT_UNKNOWN,
- // the original set of assertions has result UNSAT
- OPT_UNSAT,
- // the optimization loop finished and optimal
- OPT_OPTIMAL,
+ public:
+ /**
+ * Enum indicating whether the checkOpt result
+ * is optimal or not.
+ **/
+ enum ResultType
+ {
+ // the type of the target is not supported
+ UNSUPPORTED,
+ // whether the value is optimal is UNKNOWN
+ UNKNOWN,
+ // the original set of assertions has result UNSAT
+ UNSAT,
+ // the value is optimal
+ OPTIMAL,
+ // the goal is unbounded,
+ // if objective is maximize, it's +infinity
+ // if objective is minimize, it's -infinity
+ UNBOUNDED,
+ };
- // the goal is unbounded, so it would be -inf or +inf
- OPT_UNBOUNDED,
+ /**
+ * Constructor
+ * @param type the optimization outcome
+ * @param value the optimized value
+ **/
+ OptimizationResult(ResultType type, TNode value)
+ : d_type(type), d_value(value)
+ {
+ }
+ OptimizationResult() : d_type(UNSUPPORTED), d_value() {}
+ ~OptimizationResult() = default;
- // The last value is here as a preparation for future work
- // in which pproximate optimizations will be supported.
+ /**
+ * Returns an enum indicating whether
+ * the result is optimal or not.
+ * @return an enum showing whether the result is optimal, unbounded,
+ * unsat, unknown or unsupported.
+ **/
+ ResultType getType() { return d_type; }
+ /**
+ * Returns the optimal value.
+ * @return Node containing the optimal value,
+ * if getType() is not OPTIMAL, it might return an empty node or a node
+ * containing non-optimal value
+ **/
+ Node getValue() { return d_value; }
- // if the solver halted early and value is only approximate
- OPT_SAT_APPROX
+ private:
+ /** the indicating whether the result is optimal or something else **/
+ ResultType d_type;
+ /** if the result is optimal, this is storing the optimal value **/
+ Node d_value;
};
/**
* - whether it's maximize/minimize
* - and whether it's signed for BitVectors
*/
-class Objective
+class OptimizationObjective
{
public:
+ /**
+ * An enum for optimization queries.
+ * Represents whether an objective should be minimized or maximized
+ */
+ enum ObjectiveType
+ {
+ MINIMIZE,
+ MAXIMIZE,
+ };
+
/**
* Constructor
- * @param n the optimization target node
+ * @param target the optimization target node
* @param type speficies whether it's maximize/minimize
* @param bvSigned specifies whether it's using signed or unsigned comparison
* for BitVectors this parameter is only valid when the type of target node
* is BitVector
**/
- Objective(Node n, ObjectiveType type, bool bvSigned = false);
- ~Objective(){};
+ OptimizationObjective(TNode target, ObjectiveType type, bool bvSigned = false)
+ : d_type(type), d_target(target), d_bvSigned(bvSigned)
+ {
+ }
+ ~OptimizationObjective() = default;
/** A getter for d_type **/
- ObjectiveType getType();
- /** A getter for d_node **/
- Node getNode();
+ ObjectiveType getType() { return d_type; }
+
+ /** A getter for d_target **/
+ Node getTarget() { return d_target; }
+
/** A getter for d_bvSigned **/
- bool getSigned();
+ bool bvIsSigned() { return d_bvSigned; }
private:
- /** The type of objective this is, either OBJECTIVE_MAXIMIZE OR
- * OBJECTIVE_MINIMIZE **/
+ /**
+ * The type of objective,
+ * it's either MAXIMIZE OR MINIMIZE
+ **/
ObjectiveType d_type;
- /** The node associated to the term that was used to construct the objective.
- * **/
- Node d_node;
- /** Specify whether to use signed or unsigned comparison
+ /**
+ * The node associated to the term that was used to construct the objective.
+ **/
+ Node d_target;
+
+ /**
+ * Specify whether to use signed or unsigned comparison
* for BitVectors (only for BitVectors), this variable is defaulted to false
- * **/
+ **/
bool d_bvSigned;
};
* Constructor
* @param parent the smt_solver that the user added their assertions to
**/
- OptimizationSolver(SmtEngine* parent);
- ~OptimizationSolver();
+ OptimizationSolver(SmtEngine* parent)
+ : d_parent(parent), d_objectives(), d_results()
+ {
+ }
+ ~OptimizationSolver() = default;
- /** Runs the optimization loop for the activated objective **/
- OptResult checkOpt();
/**
- * Activates an objective: will be optimized for
- * @param obj the Node representing the expression that will be optimized for
+ * Run the optimization loop for the pushed objective
+ * NOTE: this function currently supports only single objective
+ * for multiple pushed objectives it always optimizes the first one.
+ * Add support for multi-obj later
+ */
+ OptimizationResult::ResultType checkOpt();
+
+ /**
+ * Push an objective.
+ * @param target the Node representing the expression that will be optimized
+ *for
* @param type specifies whether it's maximize or minimize
* @param bvSigned specifies whether we should use signed/unsigned
* comparison for BitVectors (only effective for BitVectors)
* and its default is false
**/
- void activateObj(const Node& obj,
- const ObjectiveType type,
- bool bvSigned = false);
- /** Gets the value of the optimized objective after checkopt is called **/
- Node objectiveGetValue();
+ void pushObjective(TNode target,
+ OptimizationObjective::ObjectiveType type,
+ bool bvSigned = false);
+
+ /**
+ * Pop the most recent objective.
+ **/
+ void popObjective();
+
+ /**
+ * Returns the values of the optimized objective after checkOpt is called
+ * @return a vector of Optimization Result,
+ * each containing the outcome and the value.
+ **/
+ std::vector<OptimizationResult> getValues();
private:
/** The parent SMT engine **/
SmtEngine* d_parent;
+
/** The objectives to optimize for **/
- Objective d_activatedObjective;
- /** A saved value of the objective from the last sat call. **/
- Node d_savedValue;
+ std::vector<OptimizationObjective> d_objectives;
+
+ /** The results of the optimizations from the last checkOpt call **/
+ std::vector<OptimizationResult> d_results;
};
} // namespace smt
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, a, x));
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, x, b));
- const ObjectiveType obj_type = ObjectiveType::OBJECTIVE_MINIMIZE;
- d_optslv->activateObj(x, obj_type, false);
+ d_optslv->pushObjective(x, OptimizationObjective::MINIMIZE, false);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(BitVector(32u, (unsigned)0x3FFFFFA1)));
-
- std::cout << "Passed!" << std::endl;
- std::cout << "Optimized value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
+ BitVector(32u, (uint32_t)0x3FFFFFA1));
+ d_optslv->popObjective();
}
TEST_F(TestTheoryWhiteBVOpt, signed_min)
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, a, x));
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, x, b));
- const ObjectiveType obj_type = ObjectiveType::OBJECTIVE_MINIMIZE;
- d_optslv->activateObj(x, obj_type, true);
+ d_optslv->pushObjective(x, OptimizationObjective::MINIMIZE, true);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
- BitVector val = d_optslv->objectiveGetValue().getConst<BitVector>();
+ BitVector val = d_optslv->getValues()[0].getValue().getConst<BitVector>();
std::cout << "opt value is: " << val << std::endl;
// expect the minimum x = -1
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(BitVector(32u, (unsigned)0x80000000)));
- std::cout << "Passed!" << std::endl;
- std::cout << "Optimized value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ ASSERT_EQ(val, BitVector(32u, (uint32_t)0x80000000));
+ d_optslv->popObjective();
}
TEST_F(TestTheoryWhiteBVOpt, unsigned_max)
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, a, x));
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, x, b));
- const ObjectiveType obj_type = ObjectiveType::OBJECTIVE_MAXIMIZE;
- d_optslv->activateObj(x, obj_type, false);
+ d_optslv->pushObjective(x, OptimizationObjective::MAXIMIZE, false);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
- BitVector val = d_optslv->objectiveGetValue().getConst<BitVector>();
+ BitVector val = d_optslv->getValues()[0].getValue().getConst<BitVector>();
std::cout << "opt value is: " << val << std::endl;
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(BitVector(32u, (unsigned)2)));
- std::cout << "Optimized value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
+ BitVector(32u, 2u));
+ d_optslv->popObjective();
}
TEST_F(TestTheoryWhiteBVOpt, signed_max)
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, a, x));
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, x, b));
- const ObjectiveType obj_type = ObjectiveType::OBJECTIVE_MAXIMIZE;
- d_optslv->activateObj(x, obj_type, true);
+ d_optslv->pushObjective(x, OptimizationObjective::MAXIMIZE, true);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
// expect the maxmum x =
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(BitVector(32u, 10u)));
- std::cout << "Optimized value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
+ BitVector(32u, 10u));
+ d_optslv->popObjective();
}
TEST_F(TestTheoryWhiteBVOpt, min_boundary)
// that existed previously
d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, y, x));
- d_optslv->activateObj(x, ObjectiveType::OBJECTIVE_MINIMIZE, false);
+ d_optslv->pushObjective(x, OptimizationObjective::MINIMIZE, false);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
// expect the maximum x = 18
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(BitVector(32u, 18u)));
- std::cout << "Optimized value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
+ BitVector(32u, 18u));
+ d_optslv->popObjective();
}
} // namespace test
d_smtEngine->assertFormula(upb);
d_smtEngine->assertFormula(lowb);
- const ObjectiveType max_type = ObjectiveType::OBJECTIVE_MAXIMIZE;
// We activate our objective so the subsolver knows to optimize it
- d_optslv->activateObj(max_cost, max_type);
+ d_optslv->pushObjective(max_cost, OptimizationObjective::MAXIMIZE);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
// We expect max_cost == 99
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(Rational("99")));
+ ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<Rational>(),
+ Rational("99"));
- std::cout << "Optimized max value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ d_optslv->popObjective();
}
TEST_F(TestTheoryWhiteIntOpt, min)
d_smtEngine->assertFormula(upb);
d_smtEngine->assertFormula(lowb);
- const ObjectiveType min_type = ObjectiveType::OBJECTIVE_MINIMIZE;
// We activate our objective so the subsolver knows to optimize it
- d_optslv->activateObj(max_cost, min_type);
+ d_optslv->pushObjective(max_cost, OptimizationObjective::MINIMIZE);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
// We expect max_cost == 99
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(Rational("1")));
+ ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<Rational>(),
+ Rational("1"));
- std::cout << "Optimized max value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ d_optslv->popObjective();
}
TEST_F(TestTheoryWhiteIntOpt, result)
d_smtEngine->assertFormula(upb);
d_smtEngine->assertFormula(lowb);
- const ObjectiveType max_type = ObjectiveType::OBJECTIVE_MAXIMIZE;
// We activate our objective so the subsolver knows to optimize it
- d_optslv->activateObj(max_cost, max_type);
+ d_optslv->pushObjective(max_cost, OptimizationObjective::MAXIMIZE);
// This should return OPT_UNSAT since 0 > x > 100 is impossible.
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
// We expect our check to have returned UNSAT
- ASSERT_EQ(r, OptResult::OPT_UNSAT);
+ ASSERT_EQ(r, OptimizationResult::UNSAT);
+ d_optslv->popObjective();
}
TEST_F(TestTheoryWhiteIntOpt, open_interval)
*/
Node cost3 = d_nodeManager->mkNode(kind::PLUS, cost1, cost2);
- const ObjectiveType min_type = ObjectiveType::OBJECTIVE_MINIMIZE;
- d_optslv->activateObj(cost3, min_type);
+ d_optslv->pushObjective(cost3, OptimizationObjective::MINIMIZE);
- OptResult r = d_optslv->checkOpt();
+ OptimizationResult::ResultType r = d_optslv->checkOpt();
- ASSERT_EQ(r, OptResult::OPT_OPTIMAL);
+ ASSERT_EQ(r, OptimizationResult::OPTIMAL);
// expect the minimum result of cost3 = cost1 + cost2 to be 1 + 111 = 112
- ASSERT_EQ(d_optslv->objectiveGetValue(),
- d_nodeManager->mkConst(Rational("112")));
- std::cout << "Optimized min value is: " << d_optslv->objectiveGetValue()
- << std::endl;
+ ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<Rational>(),
+ Rational("112"));
+ d_optslv->popObjective();
}
} // namespace test