GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/smt_engine_subsolver.cpp Lines: 60 69 87.0 %
Date: 2021-11-07 Branches: 62 156 39.7 %

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
 * SolverEngine) during solving.
15
 */
16
17
#include "theory/smt_engine_subsolver.h"
18
19
#include "proof/unsat_core.h"
20
#include "smt/env.h"
21
#include "smt/solver_engine.h"
22
#include "smt/solver_engine_scope.h"
23
#include "theory/rewriter.h"
24
25
namespace cvc5 {
26
namespace theory {
27
28
// optimization: try to rewrite to constant
29
1476
Result quickCheck(Node& query)
30
{
31
1476
  query = theory::Rewriter::rewrite(query);
32
1476
  if (query.isConst())
33
  {
34
472
    if (!query.getConst<bool>())
35
    {
36
88
      return Result(Result::UNSAT);
37
    }
38
    else
39
    {
40
384
      return Result(Result::SAT);
41
    }
42
  }
43
1004
  return Result(Result::SAT_UNKNOWN, Result::REQUIRES_FULL_CHECK);
44
}
45
46
7610
void initializeSubsolver(std::unique_ptr<SolverEngine>& smte,
47
                         const Options& opts,
48
                         const LogicInfo& logicInfo,
49
                         bool needsTimeout,
50
                         unsigned long timeout)
51
{
52
7610
  NodeManager* nm = NodeManager::currentNM();
53
7610
  smte.reset(new SolverEngine(nm, &opts));
54
7610
  smte->setIsInternalSubsolver();
55
7610
  smte->setLogic(logicInfo);
56
  // set the options
57
7610
  if (needsTimeout)
58
  {
59
    smte->setTimeLimit(timeout);
60
  }
61
7610
}
62
1876
void initializeSubsolver(std::unique_ptr<SolverEngine>& smte,
63
                         const Env& env,
64
                         bool needsTimeout,
65
                         unsigned long timeout)
66
{
67
1876
  initializeSubsolver(
68
      smte, env.getOptions(), env.getLogicInfo(), needsTimeout, timeout);
69
1876
}
70
71
Result checkWithSubsolver(std::unique_ptr<SolverEngine>& smte,
72
                          Node query,
73
                          const Options& opts,
74
                          const LogicInfo& logicInfo,
75
                          bool needsTimeout,
76
                          unsigned long timeout)
77
{
78
  Assert(query.getType().isBoolean());
79
  Result r = quickCheck(query);
80
  if (!r.isUnknown())
81
  {
82
    return r;
83
  }
84
  initializeSubsolver(smte, opts, logicInfo, needsTimeout, timeout);
85
  smte->assertFormula(query);
86
  return smte->checkSat();
87
}
88
89
436
Result checkWithSubsolver(Node query,
90
                          const Options& opts,
91
                          const LogicInfo& logicInfo,
92
                          bool needsTimeout,
93
                          unsigned long timeout)
94
{
95
872
  std::vector<Node> vars;
96
872
  std::vector<Node> modelVals;
97
  return checkWithSubsolver(
98
872
      query, vars, modelVals, opts, logicInfo, needsTimeout, timeout);
99
}
100
101
1476
Result checkWithSubsolver(Node query,
102
                          const std::vector<Node>& vars,
103
                          std::vector<Node>& modelVals,
104
                          const Options& opts,
105
                          const LogicInfo& logicInfo,
106
                          bool needsTimeout,
107
                          unsigned long timeout)
108
{
109
1476
  Assert(query.getType().isBoolean());
110
1476
  Assert(modelVals.empty());
111
  // ensure clear
112
1476
  modelVals.clear();
113
1476
  Result r = quickCheck(query);
114
1476
  if (!r.isUnknown())
115
  {
116
472
    if (r.asSatisfiabilityResult().isSat() == Result::SAT)
117
    {
118
      // default model
119
406
      for (const Node& v : vars)
120
      {
121
22
        modelVals.push_back(v.getType().mkGroundTerm());
122
      }
123
    }
124
472
    return r;
125
  }
126
2008
  std::unique_ptr<SolverEngine> smte;
127
1004
  initializeSubsolver(smte, opts, logicInfo, needsTimeout, timeout);
128
1004
  smte->assertFormula(query);
129
1004
  r = smte->checkSat();
130
1004
  if (r.asSatisfiabilityResult().isSat() == Result::SAT)
131
  {
132
3199
    for (const Node& v : vars)
133
    {
134
5132
      Node val = smte->getValue(v);
135
2566
      modelVals.push_back(val);
136
    }
137
  }
138
1004
  return r;
139
}
140
141
1680
void getModelFromSubsolver(SolverEngine& smt,
142
                           const std::vector<Node>& vars,
143
                           std::vector<Node>& vals)
144
{
145
6830
  for (const Node& v : vars)
146
  {
147
10300
    Node mv = smt.getValue(v);
148
5150
    vals.push_back(mv);
149
  }
150
1680
}
151
152
2418
bool getUnsatCoreFromSubsolver(SolverEngine& smt,
153
                               const std::unordered_set<Node>& queryAsserts,
154
                               std::vector<Node>& uasserts)
155
{
156
4836
  UnsatCore uc = smt.getUnsatCore();
157
2418
  bool hasQuery = false;
158
4880
  for (UnsatCore::const_iterator i = uc.begin(); i != uc.end(); ++i)
159
  {
160
4892
    Node uassert = *i;
161
2494
    if (queryAsserts.find(uassert) != queryAsserts.end())
162
    {
163
32
      hasQuery = true;
164
32
      continue;
165
    }
166
2430
    uasserts.push_back(uassert);
167
  }
168
4836
  return hasQuery;
169
}
170
171
2380
void getUnsatCoreFromSubsolver(SolverEngine& smt, std::vector<Node>& uasserts)
172
{
173
4760
  std::unordered_set<Node> queryAsserts;
174
2380
  getUnsatCoreFromSubsolver(smt, queryAsserts, uasserts);
175
2380
}
176
177
}  // namespace theory
178
31137
}  // namespace cvc5