GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/term_pools.cpp Lines: 74 76 97.4 %
Date: 2021-09-10 Branches: 93 226 41.2 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds
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
 * Utilities for term enumeration.
14
 */
15
16
#include "theory/quantifiers/term_pools.h"
17
18
#include "theory/quantifiers/quantifiers_state.h"
19
20
namespace cvc5 {
21
namespace theory {
22
namespace quantifiers {
23
24
5
void TermPoolDomain::initialize() { d_terms.clear(); }
25
6
void TermPoolDomain::add(Node n)
26
{
27
6
  if (std::find(d_terms.begin(), d_terms.end(), n) == d_terms.end())
28
  {
29
6
    d_terms.push_back(n);
30
  }
31
6
}
32
33
5311
void TermPoolQuantInfo::initialize()
34
{
35
5311
  d_instAddToPool.clear();
36
5311
  d_skolemAddToPool.clear();
37
5311
}
38
39
9913
TermPools::TermPools(Env& env, QuantifiersState& qs)
40
9913
    : QuantifiersUtil(env), d_qs(qs)
41
{
42
9913
}
43
44
28088
bool TermPools::reset(Theory::Effort e)
45
{
46
28100
  for (std::pair<const Node, TermPoolDomain>& p : d_pools)
47
  {
48
12
    p.second.d_currTerms.clear();
49
  }
50
28088
  return true;
51
}
52
53
25073
void TermPools::registerQuantifier(Node q)
54
{
55
25073
  if (q.getNumChildren() < 3)
56
  {
57
19762
    return;
58
  }
59
5311
  TermPoolQuantInfo& qi = d_qinfo[q];
60
5311
  qi.initialize();
61
11070
  for (const Node& p : q[2])
62
  {
63
5759
    Kind pk = p.getKind();
64
5759
    if (pk == kind::INST_ADD_TO_POOL)
65
    {
66
      qi.d_instAddToPool.push_back(p);
67
    }
68
5759
    else if (pk == kind::SKOLEM_ADD_TO_POOL)
69
    {
70
8
      qi.d_skolemAddToPool.push_back(p);
71
    }
72
  }
73
5311
  if (qi.d_instAddToPool.empty() && qi.d_skolemAddToPool.empty())
74
  {
75
5303
    d_qinfo.erase(q);
76
  }
77
}
78
79
28088
std::string TermPools::identify() const { return "TermPools"; }
80
81
5
void TermPools::registerPool(Node p, const std::vector<Node>& initValue)
82
{
83
5
  TermPoolDomain& d = d_pools[p];
84
5
  d.initialize();
85
11
  for (const Node& i : initValue)
86
  {
87
6
    Assert(i.getType().isComparableTo(p.getType().getSetElementType()));
88
6
    d.add(i);
89
  }
90
5
}
91
92
4
void TermPools::getTermsForPool(Node p, std::vector<Node>& terms)
93
{
94
  // for now, we assume p is a variable
95
4
  Assert(p.isVar());
96
4
  TermPoolDomain& dom = d_pools[p];
97
4
  if (dom.d_terms.empty())
98
  {
99
    return;
100
  }
101
  // if we have yet to compute terms on this round
102
4
  if (dom.d_currTerms.empty())
103
  {
104
8
    std::unordered_set<Node> reps;
105
    // eliminate modulo equality
106
12
    for (const Node& t : dom.d_terms)
107
    {
108
16
      Node r = d_qs.getRepresentative(t);
109
8
      const auto i = reps.insert(r);
110
8
      if (i.second)
111
      {
112
8
        dom.d_currTerms.push_back(t);
113
      }
114
    }
115
8
    Trace("pool-terms") << "* Domain for pool " << p << " is "
116
4
                        << dom.d_currTerms << std::endl;
117
  }
118
4
  terms.insert(terms.end(), dom.d_currTerms.begin(), dom.d_currTerms.end());
119
}
120
121
38080
void TermPools::processInstantiation(Node q, const std::vector<Node>& terms)
122
{
123
38080
  processInternal(q, terms, true);
124
38080
}
125
126
2398
void TermPools::processSkolemization(Node q, const std::vector<Node>& skolems)
127
{
128
2398
  processInternal(q, skolems, false);
129
2398
}
130
131
40478
void TermPools::processInternal(Node q,
132
                                const std::vector<Node>& ts,
133
                                bool isInst)
134
{
135
40478
  Assert(q.getKind() == kind::FORALL);
136
40478
  std::map<Node, TermPoolQuantInfo>::iterator it = d_qinfo.find(q);
137
40478
  if (it == d_qinfo.end())
138
  {
139
    // does not impact
140
40458
    return;
141
  }
142
40
  std::vector<Node> vars(q[0].begin(), q[0].end());
143
20
  Assert(vars.size() == ts.size());
144
  std::vector<Node>& cmds =
145
20
      isInst ? it->second.d_instAddToPool : it->second.d_skolemAddToPool;
146
28
  for (const Node& c : cmds)
147
  {
148
8
    Assert(c.getNumChildren() == 2);
149
16
    Node t = c[0];
150
    // substitute the term
151
16
    Node st = t.substitute(vars.begin(), vars.end(), ts.begin(), ts.end());
152
    // add to pool
153
16
    Trace("pool-terms") << "Due to "
154
8
                        << (isInst ? "instantiation" : "skolemization")
155
8
                        << ", add " << st << " to pool " << c[1] << std::endl;
156
8
    TermPoolDomain& dom = d_pools[c[1]];
157
8
    dom.d_terms.push_back(st);
158
  }
159
}
160
161
}  // namespace quantifiers
162
}  // namespace theory
163
29502
}  // namespace cvc5