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