GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/theory_sets.cpp Lines: 99 107 92.5 %
Date: 2021-05-22 Branches: 150 316 47.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Kshitij Bansal, Andres Noetzli
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
 * Sets theory.
14
 */
15
16
#include "theory/sets/theory_sets.h"
17
18
#include "options/sets_options.h"
19
#include "theory/sets/theory_sets_private.h"
20
#include "theory/sets/theory_sets_rewriter.h"
21
#include "theory/theory_model.h"
22
#include "theory/trust_substitutions.h"
23
24
using namespace cvc5::kind;
25
26
namespace cvc5 {
27
namespace theory {
28
namespace sets {
29
30
9460
TheorySets::TheorySets(context::Context* c,
31
                       context::UserContext* u,
32
                       OutputChannel& out,
33
                       Valuation valuation,
34
                       const LogicInfo& logicInfo,
35
9460
                       ProofNodeManager* pnm)
36
    : Theory(THEORY_SETS, c, u, out, valuation, logicInfo, pnm),
37
      d_skCache(),
38
      d_state(c, u, valuation, d_skCache),
39
      d_im(*this, d_state, nullptr),
40
9460
      d_internal(new TheorySetsPrivate(*this, d_state, d_im, d_skCache, pnm)),
41
18920
      d_notify(*d_internal.get(), d_im)
42
{
43
  // use the official theory state and inference manager objects
44
9460
  d_theoryState = &d_state;
45
9460
  d_inferManager = &d_im;
46
9460
}
47
48
18920
TheorySets::~TheorySets()
49
{
50
18920
}
51
52
9460
TheoryRewriter* TheorySets::getTheoryRewriter()
53
{
54
9460
  return d_internal->getTheoryRewriter();
55
}
56
57
3600
ProofRuleChecker* TheorySets::getProofChecker() { return nullptr; }
58
59
9460
bool TheorySets::needsEqualityEngine(EeSetupInfo& esi)
60
{
61
9460
  esi.d_notify = &d_notify;
62
9460
  esi.d_name = "theory::sets::ee";
63
9460
  return true;
64
}
65
66
9460
void TheorySets::finishInit()
67
{
68
9460
  Assert(d_equalityEngine != nullptr);
69
70
9460
  d_valuation.setUnevaluatedKind(COMPREHENSION);
71
  // choice is used to eliminate witness
72
9460
  d_valuation.setUnevaluatedKind(WITNESS);
73
  // Universe set is not evaluated. This is moreover important for ensuring that
74
  // we do not eliminate terms whose value involves the universe set.
75
9460
  d_valuation.setUnevaluatedKind(UNIVERSE_SET);
76
77
  // functions we are doing congruence over
78
9460
  d_equalityEngine->addFunctionKind(SINGLETON);
79
9460
  d_equalityEngine->addFunctionKind(UNION);
80
9460
  d_equalityEngine->addFunctionKind(INTERSECTION);
81
9460
  d_equalityEngine->addFunctionKind(SETMINUS);
82
9460
  d_equalityEngine->addFunctionKind(MEMBER);
83
9460
  d_equalityEngine->addFunctionKind(SUBSET);
84
  // relation operators
85
9460
  d_equalityEngine->addFunctionKind(PRODUCT);
86
9460
  d_equalityEngine->addFunctionKind(JOIN);
87
9460
  d_equalityEngine->addFunctionKind(TRANSPOSE);
88
9460
  d_equalityEngine->addFunctionKind(TCLOSURE);
89
9460
  d_equalityEngine->addFunctionKind(JOIN_IMAGE);
90
9460
  d_equalityEngine->addFunctionKind(IDEN);
91
9460
  d_equalityEngine->addFunctionKind(APPLY_CONSTRUCTOR);
92
  // we do congruence over cardinality
93
9460
  d_equalityEngine->addFunctionKind(CARD);
94
95
  // finish initialization internally
96
9460
  d_internal->finishInit();
97
9460
}
98
99
87926
void TheorySets::postCheck(Effort level) { d_internal->postCheck(level); }
100
101
183854
void TheorySets::notifyFact(TNode atom,
102
                            bool polarity,
103
                            TNode fact,
104
                            bool isInternal)
105
{
106
183854
  d_internal->notifyFact(atom, polarity, fact);
107
183854
}
108
109
4505
bool TheorySets::collectModelValues(TheoryModel* m,
110
                                    const std::set<Node>& termSet)
111
{
112
4505
  return d_internal->collectModelValues(m, termSet);
113
}
114
115
6056
void TheorySets::computeCareGraph() {
116
6056
  d_internal->computeCareGraph();
117
6056
}
118
119
2143
TrustNode TheorySets::explain(TNode node)
120
{
121
4286
  Node exp = d_internal->explain(node);
122
4286
  return TrustNode::mkTrustPropExp(node, exp, nullptr);
123
}
124
125
Node TheorySets::getModelValue(TNode node) {
126
  return Node::null();
127
}
128
129
75286
void TheorySets::preRegisterTerm(TNode node)
130
{
131
75286
  d_internal->preRegisterTerm(node);
132
75286
}
133
134
45420
TrustNode TheorySets::ppRewrite(TNode n, std::vector<SkolemLemma>& lems)
135
{
136
45420
  Kind nk = n.getKind();
137
45420
  if (nk == UNIVERSE_SET || nk == COMPLEMENT || nk == JOIN_IMAGE
138
44865
      || nk == COMPREHENSION)
139
  {
140
578
    if (!options::setsExt())
141
    {
142
4
      std::stringstream ss;
143
2
      ss << "Extended set operators are not supported in default mode, try "
144
            "--sets-ext.";
145
2
      throw LogicException(ss.str());
146
    }
147
  }
148
45418
  if (nk == COMPREHENSION)
149
  {
150
    // set comprehension is an implicit quantifier, require it in the logic
151
23
    if (!getLogicInfo().isQuantified())
152
    {
153
2
      std::stringstream ss;
154
1
      ss << "Set comprehensions require quantifiers in the background logic.";
155
1
      throw LogicException(ss.str());
156
    }
157
  }
158
45417
  return d_internal->ppRewrite(n, lems);
159
}
160
161
2303
Theory::PPAssertStatus TheorySets::ppAssert(
162
    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
163
{
164
4606
  TNode in = tin.getNode();
165
2303
  Debug("sets-proc") << "ppAssert : " << in << std::endl;
166
2303
  Theory::PPAssertStatus status = Theory::PP_ASSERT_STATUS_UNSOLVED;
167
168
  // this is based off of Theory::ppAssert
169
2303
  if (in.getKind() == EQUAL)
170
  {
171
682
    if (in[0].isVar() && isLegalElimination(in[0], in[1]))
172
    {
173
      // We cannot solve for sets if setsExt is enabled, since universe set
174
      // may appear when this option is enabled, and solving for such a set
175
      // impacts the semantics of universe set, see
176
      // regress0/sets/pre-proc-univ.smt2
177
325
      if (!in[0].getType().isSet() || !options::setsExt())
178
      {
179
277
        outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
180
277
        status = Theory::PP_ASSERT_STATUS_SOLVED;
181
      }
182
    }
183
357
    else if (in[1].isVar() && isLegalElimination(in[1], in[0]))
184
    {
185
5
      if (!in[0].getType().isSet() || !options::setsExt())
186
      {
187
        outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
188
        status = Theory::PP_ASSERT_STATUS_SOLVED;
189
      }
190
    }
191
352
    else if (in[0].isConst() && in[1].isConst())
192
    {
193
      if (in[0] != in[1])
194
      {
195
        status = Theory::PP_ASSERT_STATUS_CONFLICT;
196
      }
197
    }
198
  }
199
4606
  return status;
200
}
201
202
14310
void TheorySets::presolve() {
203
14310
  d_internal->presolve();
204
14310
}
205
206
bool TheorySets::isEntailed( Node n, bool pol ) {
207
  return d_internal->isEntailed( n, pol );
208
}
209
210
/**************************** eq::NotifyClass *****************************/
211
212
73251
void TheorySets::NotifyClass::eqNotifyNewClass(TNode t)
213
{
214
146502
  Debug("sets-eq") << "[sets-eq] eqNotifyNewClass:"
215
73251
                   << " t = " << t << std::endl;
216
73251
  d_theory.eqNotifyNewClass(t);
217
73251
}
218
219
197225
void TheorySets::NotifyClass::eqNotifyMerge(TNode t1, TNode t2)
220
{
221
394450
  Debug("sets-eq") << "[sets-eq] eqNotifyMerge:"
222
197225
                   << " t1 = " << t1 << " t2 = " << t2 << std::endl;
223
197225
  d_theory.eqNotifyMerge(t1, t2);
224
197225
}
225
226
26756
void TheorySets::NotifyClass::eqNotifyDisequal(TNode t1, TNode t2, TNode reason)
227
{
228
53512
  Debug("sets-eq") << "[sets-eq] eqNotifyDisequal:"
229
26756
                   << " t1 = " << t1 << " t2 = " << t2 << " reason = " << reason
230
26756
                   << std::endl;
231
26756
  d_theory.eqNotifyDisequal(t1, t2, reason);
232
26756
}
233
234
}  // namespace sets
235
}  // namespace theory
236
28194
}  // namespace cvc5