GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/smt_engine_subsolver.cpp Lines: 41 50 82.0 %
Date: 2021-08-06 Branches: 47 134 35.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
730
Result quickCheck(Node& query)
28
{
29
730
  query = theory::Rewriter::rewrite(query);
30
730
  if (query.isConst())
31
  {
32
216
    if (!query.getConst<bool>())
33
    {
34
30
      return Result(Result::UNSAT);
35
    }
36
    else
37
    {
38
186
      return Result(Result::SAT);
39
    }
40
  }
41
514
  return Result(Result::SAT_UNKNOWN, Result::REQUIRES_FULL_CHECK);
42
}
43
44
2685
void initializeSubsolver(std::unique_ptr<SmtEngine>& smte,
45
                         Options* opts,
46
                         bool needsTimeout,
47
                         unsigned long timeout)
48
{
49
2685
  NodeManager* nm = NodeManager::currentNM();
50
2685
  SmtEngine* smtCurr = smt::currentSmtEngine();
51
2685
  if (opts == nullptr)
52
  {
53
    // must copy the options
54
2266
    opts = &smtCurr->getOptions();
55
  }
56
2685
  smte.reset(new SmtEngine(nm, opts));
57
2685
  smte->setIsInternalSubsolver();
58
2685
  smte->setLogic(smtCurr->getLogicInfo());
59
  // set the options
60
2685
  if (needsTimeout)
61
  {
62
    smte->setTimeLimit(timeout);
63
  }
64
2685
}
65
66
Result checkWithSubsolver(std::unique_ptr<SmtEngine>& smte,
67
                          Node query,
68
                          Options* opts,
69
                          bool needsTimeout,
70
                          unsigned long timeout)
71
{
72
  Assert(query.getType().isBoolean());
73
  Result r = quickCheck(query);
74
  if (!r.isUnknown())
75
  {
76
    return r;
77
  }
78
  initializeSubsolver(smte, opts, needsTimeout, timeout);
79
  smte->assertFormula(query);
80
  return smte->checkSat();
81
}
82
83
157
Result checkWithSubsolver(Node query,
84
                          Options* opts,
85
                          bool needsTimeout,
86
                          unsigned long timeout)
87
{
88
314
  std::vector<Node> vars;
89
314
  std::vector<Node> modelVals;
90
  return checkWithSubsolver(
91
314
      query, vars, modelVals, opts, needsTimeout, timeout);
92
}
93
94
730
Result checkWithSubsolver(Node query,
95
                          const std::vector<Node>& vars,
96
                          std::vector<Node>& modelVals,
97
                          Options* opts,
98
                          bool needsTimeout,
99
                          unsigned long timeout)
100
{
101
730
  Assert(query.getType().isBoolean());
102
730
  Assert(modelVals.empty());
103
  // ensure clear
104
730
  modelVals.clear();
105
730
  Result r = quickCheck(query);
106
730
  if (!r.isUnknown())
107
  {
108
216
    if (r.asSatisfiabilityResult().isSat() == Result::SAT)
109
    {
110
      // default model
111
193
      for (const Node& v : vars)
112
      {
113
7
        modelVals.push_back(v.getType().mkGroundTerm());
114
      }
115
    }
116
216
    return r;
117
  }
118
1028
  std::unique_ptr<SmtEngine> smte;
119
514
  initializeSubsolver(smte, opts, needsTimeout, timeout);
120
514
  smte->assertFormula(query);
121
514
  r = smte->checkSat();
122
514
  if (r.asSatisfiabilityResult().isSat() == Result::SAT)
123
  {
124
2197
    for (const Node& v : vars)
125
    {
126
3746
      Node val = smte->getValue(v);
127
1873
      modelVals.push_back(val);
128
    }
129
  }
130
514
  return r;
131
}
132
133
}  // namespace theory
134
29322
}  // namespace cvc5