GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/term_registry.cpp Lines: 67 83 80.7 %
Date: 2021-09-16 Branches: 133 290 45.9 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Mudathir Mohamed, 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
 * Implementation of sets term registry object.
14
 */
15
16
#include "theory/sets/term_registry.h"
17
18
#include "expr/emptyset.h"
19
#include "expr/skolem_manager.h"
20
21
using namespace std;
22
using namespace cvc5::kind;
23
24
namespace cvc5 {
25
namespace theory {
26
namespace sets {
27
28
9942
TermRegistry::TermRegistry(Env& env,
29
                           SolverState& state,
30
                           InferenceManager& im,
31
                           SkolemCache& skc,
32
9942
                           ProofNodeManager* pnm)
33
    : EnvObj(env),
34
      d_im(im),
35
      d_skCache(skc),
36
9942
      d_proxy(userContext()),
37
9942
      d_proxy_to_term(userContext()),
38
      d_epg(
39
1243
          pnm ? new EagerProofGenerator(pnm, nullptr, "sets::TermRegistry::epg")
40
31069
              : nullptr)
41
{
42
9942
}
43
44
16451
Node TermRegistry::getProxy(Node n)
45
{
46
16451
  Kind nk = n.getKind();
47
16451
  if (nk != EMPTYSET && nk != SINGLETON && nk != INTERSECTION && nk != SETMINUS
48
3366
      && nk != UNION && nk != UNIVERSE_SET)
49
  {
50
1125
    return n;
51
  }
52
15326
  NodeMap::const_iterator it = d_proxy.find(n);
53
15326
  if (it != d_proxy.end())
54
  {
55
11464
    return (*it).second;
56
  }
57
3862
  NodeManager* nm = NodeManager::currentNM();
58
3862
  Node k = d_skCache.mkTypedSkolemCached(
59
7724
      n.getType(), n, SkolemCache::SK_PURIFY, "sp");
60
61
3862
  d_proxy[n] = k;
62
3862
  d_proxy_to_term[k] = n;
63
7724
  Node eq = k.eqNode(n);
64
3862
  sendSimpleLemmaInternal(eq, InferenceId::SETS_PROXY);
65
3862
  if (nk == SINGLETON)
66
  {
67
3812
    Node slem = nm->mkNode(MEMBER, n[0], k);
68
1906
    sendSimpleLemmaInternal(slem, InferenceId::SETS_PROXY_SINGLETON);
69
  }
70
3862
  return k;
71
}
72
73
8715
Node TermRegistry::getEmptySet(TypeNode tn)
74
{
75
8715
  std::map<TypeNode, Node>::iterator it = d_emptyset.find(tn);
76
8715
  if (it != d_emptyset.end())
77
  {
78
8607
    return it->second;
79
  }
80
216
  Node n = NodeManager::currentNM()->mkConst(EmptySet(tn));
81
108
  d_emptyset[tn] = n;
82
108
  return n;
83
}
84
85
2929
Node TermRegistry::getUnivSet(TypeNode tn)
86
{
87
2929
  std::map<TypeNode, Node>::iterator it = d_univset.find(tn);
88
2929
  if (it != d_univset.end())
89
  {
90
2791
    return it->second;
91
  }
92
138
  NodeManager* nm = NodeManager::currentNM();
93
276
  Node n = nm->mkNullaryOperator(tn, UNIVERSE_SET);
94
152
  for (it = d_univset.begin(); it != d_univset.end(); ++it)
95
  {
96
28
    Node n1;
97
28
    Node n2;
98
14
    if (tn.isSubtypeOf(it->first))
99
    {
100
      n1 = n;
101
      n2 = it->second;
102
    }
103
14
    else if (it->first.isSubtypeOf(tn))
104
    {
105
      n1 = it->second;
106
      n2 = n;
107
    }
108
14
    if (!n1.isNull())
109
    {
110
      Node ulem = nm->mkNode(SUBSET, n1, n2);
111
      Trace("sets-lemma") << "Sets::Lemma : " << ulem << " by univ-type"
112
                          << std::endl;
113
      d_im.lemma(ulem, InferenceId::SETS_UNIV_TYPE);
114
    }
115
  }
116
138
  d_univset[tn] = n;
117
138
  return n;
118
}
119
120
Node TermRegistry::getTypeConstraintSkolem(Node n, TypeNode tn)
121
{
122
  std::map<TypeNode, Node>::iterator it = d_tc_skolem[n].find(tn);
123
  if (it == d_tc_skolem[n].end())
124
  {
125
    SkolemManager* sm = NodeManager::currentNM()->getSkolemManager();
126
    Node k = sm->mkDummySkolem("tc_k", tn);
127
    d_tc_skolem[n][tn] = k;
128
    return k;
129
  }
130
  return it->second;
131
}
132
133
4348
void TermRegistry::debugPrintSet(Node s, const char* c) const
134
{
135
4348
  if (s.getNumChildren() == 0)
136
  {
137
3042
    NodeMap::const_iterator it = d_proxy_to_term.find(s);
138
3042
    if (it != d_proxy_to_term.end())
139
    {
140
850
      debugPrintSet((*it).second, c);
141
    }
142
    else
143
    {
144
2192
      Trace(c) << s;
145
    }
146
  }
147
  else
148
  {
149
1306
    Trace(c) << "(" << s.getOperator();
150
3918
    for (const Node& sc : s)
151
    {
152
2612
      Trace(c) << " ";
153
2612
      debugPrintSet(sc, c);
154
    }
155
1306
    Trace(c) << ")";
156
  }
157
4348
}
158
159
5768
void TermRegistry::sendSimpleLemmaInternal(Node n, InferenceId id)
160
{
161
5768
  Trace("sets-lemma") << "Sets::Lemma : " << n << " by " << id << std::endl;
162
5768
  if (d_epg.get() != nullptr)
163
  {
164
    TrustNode teq =
165
1388
        d_epg->mkTrustNode(n, PfRule::MACRO_SR_PRED_INTRO, {}, {n});
166
694
    d_im.trustedLemma(teq, id);
167
  }
168
  else
169
  {
170
5074
    d_im.lemma(n, id);
171
  }
172
5768
}
173
174
}  // namespace sets
175
}  // namespace theory
176
29577
}  // namespace cvc5