GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/optimization_solver.cpp Lines: 35 35 100.0 %
Date: 2021-05-22 Branches: 34 90 37.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Michael Chang, Yancheng Ou, Aina Niemetz
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * The solver for optimization queries.
14
 */
15
16
#include "smt/optimization_solver.h"
17
18
#include "omt/omt_optimizer.h"
19
#include "options/smt_options.h"
20
#include "smt/assertions.h"
21
#include "smt/smt_engine.h"
22
#include "theory/smt_engine_subsolver.h"
23
24
using namespace cvc5::theory;
25
using namespace cvc5::omt;
26
namespace cvc5 {
27
namespace smt {
28
29
18
OptimizationResult::ResultType OptimizationSolver::checkOpt()
30
{
31
18
  Assert(d_objectives.size() == 1);
32
  // NOTE: currently we are only dealing with single obj
33
  std::unique_ptr<OMTOptimizer> optimizer =
34
36
      OMTOptimizer::getOptimizerForObjective(d_objectives[0]);
35
36
18
  if (!optimizer) return OptimizationResult::UNSUPPORTED;
37
38
36
  OptimizationResult optResult;
39
36
  std::unique_ptr<SmtEngine> optChecker = createOptCheckerWithTimeout(d_parent);
40
18
  if (d_objectives[0].getType() == OptimizationObjective::MAXIMIZE)
41
  {
42
8
    optResult =
43
16
        optimizer->maximize(optChecker.get(), d_objectives[0].getTarget());
44
  }
45
10
  else if (d_objectives[0].getType() == OptimizationObjective::MINIMIZE)
46
  {
47
10
    optResult =
48
20
        optimizer->minimize(optChecker.get(), d_objectives[0].getTarget());
49
  }
50
51
18
  d_results[0] = optResult;
52
18
  return optResult.getType();
53
}
54
55
18
void OptimizationSolver::pushObjective(
56
    TNode target, OptimizationObjective::ObjectiveType type, bool bvSigned)
57
{
58
18
  d_objectives.emplace_back(target, type, bvSigned);
59
18
  d_results.emplace_back(OptimizationResult::UNSUPPORTED, Node());
60
18
}
61
62
18
void OptimizationSolver::popObjective()
63
{
64
18
  d_objectives.pop_back();
65
18
  d_results.pop_back();
66
18
}
67
68
18
std::vector<OptimizationResult> OptimizationSolver::getValues()
69
{
70
18
  Assert(d_objectives.size() == d_results.size());
71
18
  return d_results;
72
}
73
74
18
std::unique_ptr<SmtEngine> OptimizationSolver::createOptCheckerWithTimeout(
75
    SmtEngine* parentSMTSolver, bool needsTimeout, unsigned long timeout)
76
{
77
18
  std::unique_ptr<SmtEngine> optChecker;
78
  // initializeSubSolver will copy the options and theories enabled
79
  // from the current solver to optChecker and adds timeout
80
18
  theory::initializeSubsolver(optChecker, needsTimeout, timeout);
81
  // we need to be in incremental mode for multiple objectives since we need to
82
  // push pop we need to produce models to inrement on our objective
83
18
  optChecker->setOption("incremental", "true");
84
18
  optChecker->setOption("produce-models", "true");
85
  // Move assertions from the parent solver to the subsolver
86
36
  std::vector<Node> p_assertions = parentSMTSolver->getExpandedAssertions();
87
56
  for (const Node& e : p_assertions)
88
  {
89
38
    optChecker->assertFormula(e);
90
  }
91
36
  return optChecker;
92
}
93
94
}  // namespace smt
95
28191
}  // namespace cvc5