GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/term_registry.cpp Lines: 67 83 80.7 %
Date: 2021-05-22 Branches: 131 288 45.5 %

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
9460
TermRegistry::TermRegistry(SolverState& state,
29
                           InferenceManager& im,
30
                           SkolemCache& skc,
31
9460
                           ProofNodeManager* pnm)
32
    : d_im(im),
33
      d_skCache(skc),
34
9460
      d_proxy(state.getUserContext()),
35
9460
      d_proxy_to_term(state.getUserContext()),
36
      d_epg(
37
1192
          pnm ? new EagerProofGenerator(pnm, nullptr, "sets::TermRegistry::epg")
38
29572
              : nullptr)
39
{
40
9460
}
41
42
17770
Node TermRegistry::getProxy(Node n)
43
{
44
17770
  Kind nk = n.getKind();
45
17770
  if (nk != EMPTYSET && nk != SINGLETON && nk != INTERSECTION && nk != SETMINUS
46
3282
      && nk != UNION && nk != UNIVERSE_SET)
47
  {
48
1090
    return n;
49
  }
50
16680
  NodeMap::const_iterator it = d_proxy.find(n);
51
16680
  if (it != d_proxy.end())
52
  {
53
12816
    return (*it).second;
54
  }
55
3864
  NodeManager* nm = NodeManager::currentNM();
56
3864
  Node k = d_skCache.mkTypedSkolemCached(
57
7728
      n.getType(), n, SkolemCache::SK_PURIFY, "sp");
58
59
3864
  d_proxy[n] = k;
60
3864
  d_proxy_to_term[k] = n;
61
7728
  Node eq = k.eqNode(n);
62
3864
  sendSimpleLemmaInternal(eq, InferenceId::SETS_PROXY);
63
3864
  if (nk == SINGLETON)
64
  {
65
3868
    Node slem = nm->mkNode(MEMBER, n[0], k);
66
1934
    sendSimpleLemmaInternal(slem, InferenceId::SETS_PROXY_SINGLETON);
67
  }
68
3864
  return k;
69
}
70
71
8336
Node TermRegistry::getEmptySet(TypeNode tn)
72
{
73
8336
  std::map<TypeNode, Node>::iterator it = d_emptyset.find(tn);
74
8336
  if (it != d_emptyset.end())
75
  {
76
8234
    return it->second;
77
  }
78
204
  Node n = NodeManager::currentNM()->mkConst(EmptySet(tn));
79
102
  d_emptyset[tn] = n;
80
102
  return n;
81
}
82
83
2769
Node TermRegistry::getUnivSet(TypeNode tn)
84
{
85
2769
  std::map<TypeNode, Node>::iterator it = d_univset.find(tn);
86
2769
  if (it != d_univset.end())
87
  {
88
2631
    return it->second;
89
  }
90
138
  NodeManager* nm = NodeManager::currentNM();
91
276
  Node n = nm->mkNullaryOperator(tn, UNIVERSE_SET);
92
152
  for (it = d_univset.begin(); it != d_univset.end(); ++it)
93
  {
94
28
    Node n1;
95
28
    Node n2;
96
14
    if (tn.isSubtypeOf(it->first))
97
    {
98
      n1 = n;
99
      n2 = it->second;
100
    }
101
14
    else if (it->first.isSubtypeOf(tn))
102
    {
103
      n1 = it->second;
104
      n2 = n;
105
    }
106
14
    if (!n1.isNull())
107
    {
108
      Node ulem = nm->mkNode(SUBSET, n1, n2);
109
      Trace("sets-lemma") << "Sets::Lemma : " << ulem << " by univ-type"
110
                          << std::endl;
111
      d_im.lemma(ulem, InferenceId::SETS_UNIV_TYPE);
112
    }
113
  }
114
138
  d_univset[tn] = n;
115
138
  return n;
116
}
117
118
Node TermRegistry::getTypeConstraintSkolem(Node n, TypeNode tn)
119
{
120
  std::map<TypeNode, Node>::iterator it = d_tc_skolem[n].find(tn);
121
  if (it == d_tc_skolem[n].end())
122
  {
123
    SkolemManager* sm = NodeManager::currentNM()->getSkolemManager();
124
    Node k = sm->mkDummySkolem("tc_k", tn);
125
    d_tc_skolem[n][tn] = k;
126
    return k;
127
  }
128
  return it->second;
129
}
130
131
4274
void TermRegistry::debugPrintSet(Node s, const char* c) const
132
{
133
4274
  if (s.getNumChildren() == 0)
134
  {
135
2988
    NodeMap::const_iterator it = d_proxy_to_term.find(s);
136
2988
    if (it != d_proxy_to_term.end())
137
    {
138
834
      debugPrintSet((*it).second, c);
139
    }
140
    else
141
    {
142
2154
      Trace(c) << s;
143
    }
144
  }
145
  else
146
  {
147
1286
    Trace(c) << "(" << s.getOperator();
148
3858
    for (const Node& sc : s)
149
    {
150
2572
      Trace(c) << " ";
151
2572
      debugPrintSet(sc, c);
152
    }
153
1286
    Trace(c) << ")";
154
  }
155
4274
}
156
157
5798
void TermRegistry::sendSimpleLemmaInternal(Node n, InferenceId id)
158
{
159
5798
  Trace("sets-lemma") << "Sets::Lemma : " << n << " by " << id << std::endl;
160
5798
  if (d_epg.get() != nullptr)
161
  {
162
    TrustNode teq =
163
1386
        d_epg->mkTrustNode(n, PfRule::MACRO_SR_PRED_INTRO, {}, {n});
164
693
    d_im.trustedLemma(teq, id);
165
  }
166
  else
167
  {
168
5105
    d_im.lemma(n, id);
169
  }
170
5798
}
171
172
}  // namespace sets
173
}  // namespace theory
174
28194
}  // namespace cvc5