GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/theory_sets.cpp Lines: 100 109 91.7 %
Date: 2021-11-07 Branches: 138 310 44.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
15273
TheorySets::TheorySets(Env& env, OutputChannel& out, Valuation valuation)
31
    : Theory(THEORY_SETS, env, out, valuation),
32
      d_skCache(env.getRewriter()),
33
      d_state(env, valuation, d_skCache),
34
      d_im(env, *this, d_state),
35
      d_internal(
36
15273
          new TheorySetsPrivate(env, *this, d_state, d_im, d_skCache, d_pnm)),
37
30546
      d_notify(*d_internal.get(), d_im)
38
{
39
  // use the official theory state and inference manager objects
40
15273
  d_theoryState = &d_state;
41
15273
  d_inferManager = &d_im;
42
15273
}
43
44
30536
TheorySets::~TheorySets()
45
{
46
30536
}
47
48
15273
TheoryRewriter* TheorySets::getTheoryRewriter()
49
{
50
15273
  return d_internal->getTheoryRewriter();
51
}
52
53
7989
ProofRuleChecker* TheorySets::getProofChecker() { return nullptr; }
54
55
15273
bool TheorySets::needsEqualityEngine(EeSetupInfo& esi)
56
{
57
15273
  esi.d_notify = &d_notify;
58
15273
  esi.d_name = "theory::sets::ee";
59
15273
  esi.d_notifyNewClass = true;
60
15273
  esi.d_notifyMerge = true;
61
15273
  esi.d_notifyDisequal = true;
62
15273
  return true;
63
}
64
65
15273
void TheorySets::finishInit()
66
{
67
15273
  Assert(d_equalityEngine != nullptr);
68
69
15273
  d_valuation.setUnevaluatedKind(COMPREHENSION);
70
  // choice is used to eliminate witness
71
15273
  d_valuation.setUnevaluatedKind(WITNESS);
72
  // Universe set is not evaluated. This is moreover important for ensuring that
73
  // we do not eliminate terms whose value involves the universe set.
74
15273
  d_valuation.setUnevaluatedKind(UNIVERSE_SET);
75
76
  // functions we are doing congruence over
77
15273
  d_equalityEngine->addFunctionKind(SINGLETON);
78
15273
  d_equalityEngine->addFunctionKind(UNION);
79
15273
  d_equalityEngine->addFunctionKind(INTERSECTION);
80
15273
  d_equalityEngine->addFunctionKind(SETMINUS);
81
15273
  d_equalityEngine->addFunctionKind(MEMBER);
82
15273
  d_equalityEngine->addFunctionKind(SUBSET);
83
  // relation operators
84
15273
  d_equalityEngine->addFunctionKind(PRODUCT);
85
15273
  d_equalityEngine->addFunctionKind(JOIN);
86
15273
  d_equalityEngine->addFunctionKind(TRANSPOSE);
87
15273
  d_equalityEngine->addFunctionKind(TCLOSURE);
88
15273
  d_equalityEngine->addFunctionKind(JOIN_IMAGE);
89
15273
  d_equalityEngine->addFunctionKind(IDEN);
90
15273
  d_equalityEngine->addFunctionKind(APPLY_CONSTRUCTOR);
91
  // we do congruence over cardinality
92
15273
  d_equalityEngine->addFunctionKind(CARD);
93
94
  // finish initialization internally
95
15273
  d_internal->finishInit();
96
15273
}
97
98
265291
void TheorySets::postCheck(Effort level) { d_internal->postCheck(level); }
99
100
711808
void TheorySets::notifyFact(TNode atom,
101
                            bool polarity,
102
                            TNode fact,
103
                            bool isInternal)
104
{
105
711808
  d_internal->notifyFact(atom, polarity, fact);
106
711808
}
107
108
7050
bool TheorySets::collectModelValues(TheoryModel* m,
109
                                    const std::set<Node>& termSet)
110
{
111
7050
  return d_internal->collectModelValues(m, termSet);
112
}
113
114
8788
void TheorySets::computeCareGraph() {
115
8788
  d_internal->computeCareGraph();
116
8788
}
117
118
6549
TrustNode TheorySets::explain(TNode node)
119
{
120
13098
  Node exp = d_internal->explain(node);
121
13098
  return TrustNode::mkTrustPropExp(node, exp, nullptr);
122
}
123
124
Node TheorySets::getModelValue(TNode node) {
125
  return Node::null();
126
}
127
128
83086
void TheorySets::preRegisterTerm(TNode node)
129
{
130
83086
  d_internal->preRegisterTerm(node);
131
83086
}
132
133
38367
TrustNode TheorySets::ppRewrite(TNode n, std::vector<SkolemLemma>& lems)
134
{
135
38367
  Kind nk = n.getKind();
136
38367
  if (nk == UNIVERSE_SET || nk == COMPLEMENT || nk == JOIN_IMAGE
137
38085
      || nk == COMPREHENSION)
138
  {
139
327
    if (!options().sets.setsExt)
140
    {
141
4
      std::stringstream ss;
142
2
      ss << "Extended set operators are not supported in default mode, try "
143
            "--sets-ext.";
144
2
      throw LogicException(ss.str());
145
    }
146
  }
147
38365
  if (nk == COMPREHENSION)
148
  {
149
    // set comprehension is an implicit quantifier, require it in the logic
150
45
    if (!logicInfo().isQuantified())
151
    {
152
2
      std::stringstream ss;
153
1
      ss << "Set comprehensions require quantifiers in the background logic.";
154
1
      throw LogicException(ss.str());
155
    }
156
  }
157
38364
  return d_internal->ppRewrite(n, lems);
158
}
159
160
2323
Theory::PPAssertStatus TheorySets::ppAssert(
161
    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
162
{
163
4646
  TNode in = tin.getNode();
164
2323
  Debug("sets-proc") << "ppAssert : " << in << std::endl;
165
2323
  Theory::PPAssertStatus status = Theory::PP_ASSERT_STATUS_UNSOLVED;
166
167
  // this is based off of Theory::ppAssert
168
2323
  if (in.getKind() == EQUAL)
169
  {
170
698
    if (in[0].isVar() && isLegalElimination(in[0], in[1]))
171
    {
172
      // We cannot solve for sets if setsExt is enabled, since universe set
173
      // may appear when this option is enabled, and solving for such a set
174
      // impacts the semantics of universe set, see
175
      // regress0/sets/pre-proc-univ.smt2
176
309
      if (!in[0].getType().isSet() || !options().sets.setsExt)
177
      {
178
281
        outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
179
281
        status = Theory::PP_ASSERT_STATUS_SOLVED;
180
      }
181
    }
182
389
    else if (in[1].isVar() && isLegalElimination(in[1], in[0]))
183
    {
184
      if (!in[0].getType().isSet() || !options().sets.setsExt)
185
      {
186
        outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
187
        status = Theory::PP_ASSERT_STATUS_SOLVED;
188
      }
189
    }
190
389
    else if (in[0].isConst() && in[1].isConst())
191
    {
192
      if (in[0] != in[1])
193
      {
194
        status = Theory::PP_ASSERT_STATUS_CONFLICT;
195
      }
196
    }
197
  }
198
4646
  return status;
199
}
200
201
20560
void TheorySets::presolve() {
202
20560
  d_internal->presolve();
203
20560
}
204
205
bool TheorySets::isEntailed( Node n, bool pol ) {
206
  return d_internal->isEntailed( n, pol );
207
}
208
209
/**************************** eq::NotifyClass *****************************/
210
211
88368
void TheorySets::NotifyClass::eqNotifyNewClass(TNode t)
212
{
213
176736
  Debug("sets-eq") << "[sets-eq] eqNotifyNewClass:"
214
88368
                   << " t = " << t << std::endl;
215
88368
  d_theory.eqNotifyNewClass(t);
216
88368
}
217
218
741580
void TheorySets::NotifyClass::eqNotifyMerge(TNode t1, TNode t2)
219
{
220
1483160
  Debug("sets-eq") << "[sets-eq] eqNotifyMerge:"
221
741580
                   << " t1 = " << t1 << " t2 = " << t2 << std::endl;
222
741580
  d_theory.eqNotifyMerge(t1, t2);
223
741580
}
224
225
119991
void TheorySets::NotifyClass::eqNotifyDisequal(TNode t1, TNode t2, TNode reason)
226
{
227
239982
  Debug("sets-eq") << "[sets-eq] eqNotifyDisequal:"
228
119991
                   << " t1 = " << t1 << " t2 = " << t2 << " reason = " << reason
229
119991
                   << std::endl;
230
119991
  d_theory.eqNotifyDisequal(t1, t2, reason);
231
119991
}
232
233
}  // namespace sets
234
}  // namespace theory
235
31137
}  // namespace cvc5