GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/sets/term_registry.cpp Lines: 65 83 78.3 %
Date: 2021-09-29 Branches: 125 290 43.1 %

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
6271
TermRegistry::TermRegistry(Env& env,
29
                           SolverState& state,
30
                           InferenceManager& im,
31
                           SkolemCache& skc,
32
6271
                           ProofNodeManager* pnm)
33
    : EnvObj(env),
34
      d_im(im),
35
      d_skCache(skc),
36
6271
      d_proxy(userContext()),
37
6271
      d_proxy_to_term(userContext()),
38
      d_epg(
39
60
          pnm ? new EagerProofGenerator(pnm, nullptr, "sets::TermRegistry::epg")
40
18873
              : nullptr)
41
{
42
6271
}
43
44
7988
Node TermRegistry::getProxy(Node n)
45
{
46
7988
  Kind nk = n.getKind();
47
7988
  if (nk != EMPTYSET && nk != SINGLETON && nk != INTERSECTION && nk != SETMINUS
48
1839
      && nk != UNION && nk != UNIVERSE_SET)
49
  {
50
586
    return n;
51
  }
52
7402
  NodeMap::const_iterator it = d_proxy.find(n);
53
7402
  if (it != d_proxy.end())
54
  {
55
5776
    return (*it).second;
56
  }
57
1626
  NodeManager* nm = NodeManager::currentNM();
58
1626
  Node k = d_skCache.mkTypedSkolemCached(
59
3252
      n.getType(), n, SkolemCache::SK_PURIFY, "sp");
60
61
1626
  d_proxy[n] = k;
62
1626
  d_proxy_to_term[k] = n;
63
3252
  Node eq = k.eqNode(n);
64
1626
  sendSimpleLemmaInternal(eq, InferenceId::SETS_PROXY);
65
1626
  if (nk == SINGLETON)
66
  {
67
1284
    Node slem = nm->mkNode(MEMBER, n[0], k);
68
642
    sendSimpleLemmaInternal(slem, InferenceId::SETS_PROXY_SINGLETON);
69
  }
70
1626
  return k;
71
}
72
73
4951
Node TermRegistry::getEmptySet(TypeNode tn)
74
{
75
4951
  std::map<TypeNode, Node>::iterator it = d_emptyset.find(tn);
76
4951
  if (it != d_emptyset.end())
77
  {
78
4873
    return it->second;
79
  }
80
156
  Node n = NodeManager::currentNM()->mkConst(EmptySet(tn));
81
78
  d_emptyset[tn] = n;
82
78
  return n;
83
}
84
85
1834
Node TermRegistry::getUnivSet(TypeNode tn)
86
{
87
1834
  std::map<TypeNode, Node>::iterator it = d_univset.find(tn);
88
1834
  if (it != d_univset.end())
89
  {
90
1756
    return it->second;
91
  }
92
78
  NodeManager* nm = NodeManager::currentNM();
93
156
  Node n = nm->mkNullaryOperator(tn, UNIVERSE_SET);
94
88
  for (it = d_univset.begin(); it != d_univset.end(); ++it)
95
  {
96
20
    Node n1;
97
20
    Node n2;
98
10
    if (tn.isSubtypeOf(it->first))
99
    {
100
      n1 = n;
101
      n2 = it->second;
102
    }
103
10
    else if (it->first.isSubtypeOf(tn))
104
    {
105
      n1 = it->second;
106
      n2 = n;
107
    }
108
10
    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
78
  d_univset[tn] = n;
117
78
  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
2697
void TermRegistry::debugPrintSet(Node s, const char* c) const
134
{
135
2697
  if (s.getNumChildren() == 0)
136
  {
137
1908
    NodeMap::const_iterator it = d_proxy_to_term.find(s);
138
1908
    if (it != d_proxy_to_term.end())
139
    {
140
597
      debugPrintSet((*it).second, c);
141
    }
142
    else
143
    {
144
1311
      Trace(c) << s;
145
    }
146
  }
147
  else
148
  {
149
789
    Trace(c) << "(" << s.getOperator();
150
2367
    for (const Node& sc : s)
151
    {
152
1578
      Trace(c) << " ";
153
1578
      debugPrintSet(sc, c);
154
    }
155
789
    Trace(c) << ")";
156
  }
157
2697
}
158
159
2268
void TermRegistry::sendSimpleLemmaInternal(Node n, InferenceId id)
160
{
161
2268
  Trace("sets-lemma") << "Sets::Lemma : " << n << " by " << id << std::endl;
162
2268
  if (d_epg.get() != nullptr)
163
  {
164
    TrustNode teq =
165
        d_epg->mkTrustNode(n, PfRule::MACRO_SR_PRED_INTRO, {}, {n});
166
    d_im.trustedLemma(teq, id);
167
  }
168
  else
169
  {
170
2268
    d_im.lemma(n, id);
171
  }
172
2268
}
173
174
}  // namespace sets
175
}  // namespace theory
176
22746
}  // namespace cvc5