GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/assertions.cpp Lines: 79 90 87.8 %
Date: 2021-08-17 Branches: 98 208 47.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Andres Noetzli, Haniel Barbosa
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 module for storing assertions for an SMT engine.
14
 */
15
16
#include "smt/assertions.h"
17
18
#include <sstream>
19
20
#include "base/modal_exception.h"
21
#include "expr/node_algorithm.h"
22
#include "options/base_options.h"
23
#include "options/expr_options.h"
24
#include "options/language.h"
25
#include "options/smt_options.h"
26
#include "smt/abstract_values.h"
27
#include "smt/env.h"
28
#include "smt/smt_engine.h"
29
#include "theory/trust_substitutions.h"
30
31
using namespace cvc5::theory;
32
using namespace cvc5::kind;
33
34
namespace cvc5 {
35
namespace smt {
36
37
10494
Assertions::Assertions(Env& env, AbstractValues& absv)
38
    : d_env(env),
39
      d_absValues(absv),
40
      d_produceAssertions(false),
41
10494
      d_assertionList(env.getUserContext()),
42
      d_globalNegation(false),
43
20988
      d_assertions()
44
{
45
10494
}
46
47
10494
Assertions::~Assertions()
48
{
49
10494
}
50
51
9850
void Assertions::finishInit()
52
{
53
  // [MGD 10/20/2011] keep around in incremental mode, due to a
54
  // cleanup ordering issue and Nodes/TNodes.  If SAT is popped
55
  // first, some user-context-dependent TNodes might still exist
56
  // with rc == 0.
57
9850
  if (options::produceAssertions() || options::incrementalSolving())
58
  {
59
    // In the case of incremental solving, we appear to need these to
60
    // ensure the relevant Nodes remain live.
61
7530
    d_produceAssertions = true;
62
7530
    d_globalDefineFunLemmas.reset(new std::vector<Node>());
63
  }
64
9850
}
65
66
17297
void Assertions::clearCurrent()
67
{
68
17297
  d_assertions.clear();
69
17297
  d_assertions.getIteSkolemMap().clear();
70
17297
}
71
72
15215
void Assertions::initializeCheckSat(const std::vector<Node>& assumptions,
73
                                    bool isEntailmentCheck)
74
{
75
15215
  NodeManager* nm = NodeManager::currentNM();
76
  // reset global negation
77
15215
  d_globalNegation = false;
78
  // clear the assumptions
79
15215
  d_assumptions.clear();
80
15215
  if (isEntailmentCheck)
81
  {
82
662
    size_t size = assumptions.size();
83
662
    if (size > 1)
84
    {
85
      /* Assume: not (BIGAND assumptions)  */
86
2
      d_assumptions.push_back(nm->mkNode(AND, assumptions).notNode());
87
    }
88
660
    else if (size == 1)
89
    {
90
      /* Assume: not expr  */
91
660
      d_assumptions.push_back(assumptions[0].notNode());
92
    }
93
  }
94
  else
95
  {
96
    /* Assume: BIGAND assumptions  */
97
14553
    d_assumptions = assumptions;
98
  }
99
100
30430
  Result r(Result::SAT_UNKNOWN, Result::UNKNOWN_REASON);
101
17699
  for (const Node& e : d_assumptions)
102
  {
103
    // Substitute out any abstract values in ex.
104
4968
    Node n = d_absValues.substituteAbstractValues(e);
105
    // Ensure expr is type-checked at this point.
106
2484
    ensureBoolean(n);
107
2484
    addFormula(n, true, true, false, false);
108
  }
109
15215
  if (d_globalDefineFunLemmas != nullptr)
110
  {
111
    // Global definitions are asserted at check-sat-time because we have to
112
    // make sure that they are always present (they are essentially level
113
    // zero assertions)
114
13204
    for (const Node& lemma : *d_globalDefineFunLemmas)
115
    {
116
297
      addFormula(lemma, true, false, true, false);
117
    }
118
  }
119
15215
}
120
121
89032
void Assertions::assertFormula(const Node& n)
122
{
123
89032
  ensureBoolean(n);
124
89032
  bool maybeHasFv = language::isInputLangSygus(options::inputLanguage());
125
89032
  addFormula(n, true, false, false, maybeHasFv);
126
89032
}
127
128
13
std::vector<Node>& Assertions::getAssumptions() { return d_assumptions; }
129
15185
bool Assertions::isGlobalNegated() const { return d_globalNegation; }
130
6
void Assertions::flipGlobalNegated() { d_globalNegation = !d_globalNegation; }
131
132
51682
preprocessing::AssertionPipeline& Assertions::getAssertionPipeline()
133
{
134
51682
  return d_assertions;
135
}
136
137
6640
context::CDList<Node>* Assertions::getAssertionList()
138
{
139
6640
  return d_produceAssertions ? &d_assertionList : nullptr;
140
}
141
142
94057
void Assertions::addFormula(TNode n,
143
                            bool inInput,
144
                            bool isAssumption,
145
                            bool isFunDef,
146
                            bool maybeHasFv)
147
{
148
  // add to assertion list if it exists
149
94057
  if (d_produceAssertions)
150
  {
151
63369
    d_assertionList.push_back(n);
152
  }
153
94057
  if (n.isConst() && n.getConst<bool>())
154
  {
155
    // true, nothing to do
156
534
    return;
157
  }
158
187046
  Trace("smt") << "SmtEnginePrivate::addFormula(" << n
159
93523
               << ", inInput = " << inInput
160
93523
               << ", isAssumption = " << isAssumption
161
93523
               << ", isFunDef = " << isFunDef << std::endl;
162
93523
  if (isFunDef)
163
  {
164
    // if a non-recursive define-fun, just add as a top-level substitution
165
2541
    if (n.getKind() == EQUAL && n[0].isVar())
166
    {
167
      // A define-fun is an assumption in the overall proof, thus
168
      // we justify the substitution with ASSUME here.
169
4720
      d_env.getTopLevelSubstitutions().addSubstitution(
170
2360
          n[0], n[1], PfRule::ASSUME, {}, {n});
171
2360
      return;
172
    }
173
  }
174
175
  // Ensure that it does not contain free variables
176
91163
  if (maybeHasFv)
177
  {
178
481
    if (expr::hasFreeVar(n))
179
    {
180
      std::stringstream se;
181
      se << "Cannot process assertion with free variable.";
182
      if (language::isInputLangSygus(options::inputLanguage()))
183
      {
184
        // Common misuse of SyGuS is to use top-level assert instead of
185
        // constraint when defining the synthesis conjecture.
186
        se << " Perhaps you meant `constraint` instead of `assert`?";
187
      }
188
      throw ModalException(se.str().c_str());
189
    }
190
  }
191
192
  // Add the normalized formula to the queue
193
91163
  d_assertions.push_back(n, isAssumption, true);
194
}
195
196
2461
void Assertions::addDefineFunDefinition(Node n, bool global)
197
{
198
2461
  n = d_absValues.substituteAbstractValues(n);
199
2461
  if (global && d_globalDefineFunLemmas != nullptr)
200
  {
201
    // Global definitions are asserted at check-sat-time because we have to
202
    // make sure that they are always present
203
217
    Assert(!language::isInputLangSygus(options::inputLanguage()));
204
217
    d_globalDefineFunLemmas->emplace_back(n);
205
  }
206
  else
207
  {
208
    // we don't check for free variables here, since even if we are sygus,
209
    // we could contain functions-to-synthesize within definitions.
210
2244
    addFormula(n, true, false, true, false);
211
  }
212
2461
}
213
214
91516
void Assertions::ensureBoolean(const Node& n)
215
{
216
183032
  TypeNode type = n.getType(options::typeChecking());
217
91516
  if (!type.isBoolean())
218
  {
219
    std::stringstream ss;
220
    ss << "Expected Boolean type\n"
221
       << "The assertion : " << n << "\n"
222
       << "Its type      : " << type;
223
    throw TypeCheckingExceptionPrivate(n, ss.str());
224
  }
225
91516
}
226
227
3766
void Assertions::setProofGenerator(smt::PreprocessProofGenerator* pppg)
228
{
229
3766
  d_assertions.setProofGenerator(pppg);
230
3766
}
231
232
bool Assertions::isProofEnabled() const
233
{
234
  return d_assertions.isProofEnabled();
235
}
236
237
}  // namespace smt
238
29337
}  // namespace cvc5