GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/smt_engine_subsolver.cpp Lines: 39 48 81.3 %
Date: 2021-05-22 Branches: 45 132 34.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Andres Noetzli, Gereon Kremer
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
 * Implementation of utilities for initializing subsolvers (copies of
14
 * SmtEngine) during solving.
15
 */
16
17
#include "theory/smt_engine_subsolver.h"
18
19
#include "smt/smt_engine.h"
20
#include "smt/smt_engine_scope.h"
21
#include "theory/rewriter.h"
22
23
namespace cvc5 {
24
namespace theory {
25
26
// optimization: try to rewrite to constant
27
695
Result quickCheck(Node& query)
28
{
29
695
  query = theory::Rewriter::rewrite(query);
30
695
  if (query.isConst())
31
  {
32
215
    if (!query.getConst<bool>())
33
    {
34
30
      return Result(Result::UNSAT);
35
    }
36
    else
37
    {
38
185
      return Result(Result::SAT);
39
    }
40
  }
41
480
  return Result(Result::SAT_UNKNOWN, Result::REQUIRES_FULL_CHECK);
42
}
43
44
2575
void initializeSubsolver(std::unique_ptr<SmtEngine>& smte,
45
                         bool needsTimeout,
46
                         unsigned long timeout)
47
{
48
2575
  NodeManager* nm = NodeManager::currentNM();
49
2575
  SmtEngine* smtCurr = smt::currentSmtEngine();
50
  // must copy the options
51
2575
  smte.reset(new SmtEngine(nm, &smtCurr->getOptions()));
52
2575
  smte->setIsInternalSubsolver();
53
2575
  smte->setLogic(smtCurr->getLogicInfo());
54
  // set the options
55
2575
  if (needsTimeout)
56
  {
57
    smte->setTimeLimit(timeout);
58
  }
59
2575
}
60
61
Result checkWithSubsolver(std::unique_ptr<SmtEngine>& smte,
62
                          Node query,
63
                          bool needsTimeout,
64
                          unsigned long timeout)
65
{
66
  Assert(query.getType().isBoolean());
67
  Result r = quickCheck(query);
68
  if (!r.isUnknown())
69
  {
70
    return r;
71
  }
72
  initializeSubsolver(smte, needsTimeout, timeout);
73
  smte->assertFormula(query);
74
  return smte->checkSat();
75
}
76
77
156
Result checkWithSubsolver(Node query, bool needsTimeout, unsigned long timeout)
78
{
79
312
  std::vector<Node> vars;
80
312
  std::vector<Node> modelVals;
81
312
  return checkWithSubsolver(query, vars, modelVals, needsTimeout, timeout);
82
}
83
84
695
Result checkWithSubsolver(Node query,
85
                          const std::vector<Node>& vars,
86
                          std::vector<Node>& modelVals,
87
                          bool needsTimeout,
88
                          unsigned long timeout)
89
{
90
695
  Assert(query.getType().isBoolean());
91
695
  Assert(modelVals.empty());
92
  // ensure clear
93
695
  modelVals.clear();
94
695
  Result r = quickCheck(query);
95
695
  if (!r.isUnknown())
96
  {
97
215
    if (r.asSatisfiabilityResult().isSat() == Result::SAT)
98
    {
99
      // default model
100
192
      for (const Node& v : vars)
101
      {
102
7
        modelVals.push_back(v.getType().mkGroundTerm());
103
      }
104
    }
105
215
    return r;
106
  }
107
960
  std::unique_ptr<SmtEngine> smte;
108
480
  initializeSubsolver(smte, needsTimeout, timeout);
109
480
  smte->assertFormula(query);
110
480
  r = smte->checkSat();
111
480
  if (r.asSatisfiabilityResult().isSat() == Result::SAT)
112
  {
113
1632
    for (const Node& v : vars)
114
    {
115
2644
      Node val = smte->getValue(v);
116
1322
      modelVals.push_back(val);
117
    }
118
  }
119
480
  return r;
120
}
121
122
}  // namespace theory
123
28194
}  // namespace cvc5