GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/theory_sets.cpp Lines: 100 109 91.7 %
Date: 2021-09-10 Branches: 137 308 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
9913
TheorySets::TheorySets(Env& env, OutputChannel& out, Valuation valuation)
31
    : Theory(THEORY_SETS, env, out, valuation),
32
      d_skCache(),
33
      d_state(env, valuation, d_skCache),
34
      d_im(env, *this, d_state, d_pnm),
35
      d_internal(
36
9913
          new TheorySetsPrivate(env, *this, d_state, d_im, d_skCache, d_pnm)),
37
19826
      d_notify(*d_internal.get(), d_im)
38
{
39
  // use the official theory state and inference manager objects
40
9913
  d_theoryState = &d_state;
41
9913
  d_inferManager = &d_im;
42
9913
}
43
44
19820
TheorySets::~TheorySets()
45
{
46
19820
}
47
48
9913
TheoryRewriter* TheorySets::getTheoryRewriter()
49
{
50
9913
  return d_internal->getTheoryRewriter();
51
}
52
53
3781
ProofRuleChecker* TheorySets::getProofChecker() { return nullptr; }
54
55
9913
bool TheorySets::needsEqualityEngine(EeSetupInfo& esi)
56
{
57
9913
  esi.d_notify = &d_notify;
58
9913
  esi.d_name = "theory::sets::ee";
59
9913
  esi.d_notifyNewClass = true;
60
9913
  esi.d_notifyMerge = true;
61
9913
  esi.d_notifyDisequal = true;
62
9913
  return true;
63
}
64
65
9913
void TheorySets::finishInit()
66
{
67
9913
  Assert(d_equalityEngine != nullptr);
68
69
9913
  d_valuation.setUnevaluatedKind(COMPREHENSION);
70
  // choice is used to eliminate witness
71
9913
  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
9913
  d_valuation.setUnevaluatedKind(UNIVERSE_SET);
75
76
  // functions we are doing congruence over
77
9913
  d_equalityEngine->addFunctionKind(SINGLETON);
78
9913
  d_equalityEngine->addFunctionKind(UNION);
79
9913
  d_equalityEngine->addFunctionKind(INTERSECTION);
80
9913
  d_equalityEngine->addFunctionKind(SETMINUS);
81
9913
  d_equalityEngine->addFunctionKind(MEMBER);
82
9913
  d_equalityEngine->addFunctionKind(SUBSET);
83
  // relation operators
84
9913
  d_equalityEngine->addFunctionKind(PRODUCT);
85
9913
  d_equalityEngine->addFunctionKind(JOIN);
86
9913
  d_equalityEngine->addFunctionKind(TRANSPOSE);
87
9913
  d_equalityEngine->addFunctionKind(TCLOSURE);
88
9913
  d_equalityEngine->addFunctionKind(JOIN_IMAGE);
89
9913
  d_equalityEngine->addFunctionKind(IDEN);
90
9913
  d_equalityEngine->addFunctionKind(APPLY_CONSTRUCTOR);
91
  // we do congruence over cardinality
92
9913
  d_equalityEngine->addFunctionKind(CARD);
93
94
  // finish initialization internally
95
9913
  d_internal->finishInit();
96
9913
}
97
98
106347
void TheorySets::postCheck(Effort level) { d_internal->postCheck(level); }
99
100
229125
void TheorySets::notifyFact(TNode atom,
101
                            bool polarity,
102
                            TNode fact,
103
                            bool isInternal)
104
{
105
229125
  d_internal->notifyFact(atom, polarity, fact);
106
229125
}
107
108
4728
bool TheorySets::collectModelValues(TheoryModel* m,
109
                                    const std::set<Node>& termSet)
110
{
111
4728
  return d_internal->collectModelValues(m, termSet);
112
}
113
114
6388
void TheorySets::computeCareGraph() {
115
6388
  d_internal->computeCareGraph();
116
6388
}
117
118
2807
TrustNode TheorySets::explain(TNode node)
119
{
120
5614
  Node exp = d_internal->explain(node);
121
5614
  return TrustNode::mkTrustPropExp(node, exp, nullptr);
122
}
123
124
Node TheorySets::getModelValue(TNode node) {
125
  return Node::null();
126
}
127
128
75657
void TheorySets::preRegisterTerm(TNode node)
129
{
130
75657
  d_internal->preRegisterTerm(node);
131
75657
}
132
133
45570
TrustNode TheorySets::ppRewrite(TNode n, std::vector<SkolemLemma>& lems)
134
{
135
45570
  Kind nk = n.getKind();
136
45570
  if (nk == UNIVERSE_SET || nk == COMPLEMENT || nk == JOIN_IMAGE
137
45073
      || nk == COMPREHENSION)
138
  {
139
520
    if (!options::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
45568
  if (nk == COMPREHENSION)
148
  {
149
    // set comprehension is an implicit quantifier, require it in the logic
150
23
    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
45567
  return d_internal->ppRewrite(n, lems);
158
}
159
160
2297
Theory::PPAssertStatus TheorySets::ppAssert(
161
    TrustNode tin, TrustSubstitutionMap& outSubstitutions)
162
{
163
4594
  TNode in = tin.getNode();
164
2297
  Debug("sets-proc") << "ppAssert : " << in << std::endl;
165
2297
  Theory::PPAssertStatus status = Theory::PP_ASSERT_STATUS_UNSOLVED;
166
167
  // this is based off of Theory::ppAssert
168
2297
  if (in.getKind() == EQUAL)
169
  {
170
682
    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
305
      if (!in[0].getType().isSet() || !options::setsExt())
177
      {
178
277
        outSubstitutions.addSubstitutionSolved(in[0], in[1], tin);
179
277
        status = Theory::PP_ASSERT_STATUS_SOLVED;
180
      }
181
    }
182
377
    else if (in[1].isVar() && isLegalElimination(in[1], in[0]))
183
    {
184
      if (!in[0].getType().isSet() || !options::setsExt())
185
      {
186
        outSubstitutions.addSubstitutionSolved(in[1], in[0], tin);
187
        status = Theory::PP_ASSERT_STATUS_SOLVED;
188
      }
189
    }
190
377
    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
4594
  return status;
199
}
200
201
15237
void TheorySets::presolve() {
202
15237
  d_internal->presolve();
203
15237
}
204
205
bool TheorySets::isEntailed( Node n, bool pol ) {
206
  return d_internal->isEntailed( n, pol );
207
}
208
209
/**************************** eq::NotifyClass *****************************/
210
211
79641
void TheorySets::NotifyClass::eqNotifyNewClass(TNode t)
212
{
213
159282
  Debug("sets-eq") << "[sets-eq] eqNotifyNewClass:"
214
79641
                   << " t = " << t << std::endl;
215
79641
  d_theory.eqNotifyNewClass(t);
216
79641
}
217
218
246300
void TheorySets::NotifyClass::eqNotifyMerge(TNode t1, TNode t2)
219
{
220
492600
  Debug("sets-eq") << "[sets-eq] eqNotifyMerge:"
221
246300
                   << " t1 = " << t1 << " t2 = " << t2 << std::endl;
222
246300
  d_theory.eqNotifyMerge(t1, t2);
223
246300
}
224
225
33404
void TheorySets::NotifyClass::eqNotifyDisequal(TNode t1, TNode t2, TNode reason)
226
{
227
66808
  Debug("sets-eq") << "[sets-eq] eqNotifyDisequal:"
228
33404
                   << " t1 = " << t1 << " t2 = " << t2 << " reason = " << reason
229
33404
                   << std::endl;
230
33404
  d_theory.eqNotifyDisequal(t1, t2, reason);
231
33404
}
232
233
}  // namespace sets
234
}  // namespace theory
235
29502
}  // namespace cvc5