GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/term_pools.cpp Lines: 72 74 97.3 %
Date: 2021-08-16 Branches: 94 228 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
5487
void TermPoolQuantInfo::initialize()
34
{
35
5487
  d_instAddToPool.clear();
36
5487
  d_skolemAddToPool.clear();
37
5487
}
38
39
9853
TermPools::TermPools(QuantifiersState& qs) : d_qs(qs) {}
40
41
28528
bool TermPools::reset(Theory::Effort e)
42
{
43
28540
  for (std::pair<const Node, TermPoolDomain>& p : d_pools)
44
  {
45
12
    p.second.d_currTerms.clear();
46
  }
47
28528
  return true;
48
}
49
50
24969
void TermPools::registerQuantifier(Node q)
51
{
52
24969
  if (q.getNumChildren() < 3)
53
  {
54
19482
    return;
55
  }
56
5487
  TermPoolQuantInfo& qi = d_qinfo[q];
57
5487
  qi.initialize();
58
11316
  for (const Node& p : q[2])
59
  {
60
5829
    Kind pk = p.getKind();
61
5829
    if (pk == kind::INST_ADD_TO_POOL)
62
    {
63
      qi.d_instAddToPool.push_back(p);
64
    }
65
5829
    else if (pk == kind::SKOLEM_ADD_TO_POOL)
66
    {
67
8
      qi.d_skolemAddToPool.push_back(p);
68
    }
69
  }
70
5487
  if (qi.d_instAddToPool.empty() && qi.d_skolemAddToPool.empty())
71
  {
72
5479
    d_qinfo.erase(q);
73
  }
74
}
75
76
28528
std::string TermPools::identify() const { return "TermPools"; }
77
78
5
void TermPools::registerPool(Node p, const std::vector<Node>& initValue)
79
{
80
5
  TermPoolDomain& d = d_pools[p];
81
5
  d.initialize();
82
11
  for (const Node& i : initValue)
83
  {
84
6
    Assert(i.getType().isComparableTo(p.getType().getSetElementType()));
85
6
    d.add(i);
86
  }
87
5
}
88
89
4
void TermPools::getTermsForPool(Node p, std::vector<Node>& terms)
90
{
91
  // for now, we assume p is a variable
92
4
  Assert(p.isVar());
93
4
  TermPoolDomain& dom = d_pools[p];
94
4
  if (dom.d_terms.empty())
95
  {
96
    return;
97
  }
98
  // if we have yet to compute terms on this round
99
4
  if (dom.d_currTerms.empty())
100
  {
101
8
    std::unordered_set<Node> reps;
102
    // eliminate modulo equality
103
12
    for (const Node& t : dom.d_terms)
104
    {
105
16
      Node r = d_qs.getRepresentative(t);
106
8
      if (reps.find(r) == reps.end())
107
      {
108
8
        reps.insert(r);
109
8
        dom.d_currTerms.push_back(t);
110
      }
111
    }
112
8
    Trace("pool-terms") << "* Domain for pool " << p << " is "
113
4
                        << dom.d_currTerms << std::endl;
114
  }
115
4
  terms.insert(terms.end(), dom.d_currTerms.begin(), dom.d_currTerms.end());
116
}
117
118
36698
void TermPools::processInstantiation(Node q, const std::vector<Node>& terms)
119
{
120
36698
  processInternal(q, terms, true);
121
36698
}
122
123
2411
void TermPools::processSkolemization(Node q, const std::vector<Node>& skolems)
124
{
125
2411
  processInternal(q, skolems, false);
126
2411
}
127
128
39109
void TermPools::processInternal(Node q,
129
                                const std::vector<Node>& ts,
130
                                bool isInst)
131
{
132
39109
  Assert(q.getKind() == kind::FORALL);
133
39109
  std::map<Node, TermPoolQuantInfo>::iterator it = d_qinfo.find(q);
134
39109
  if (it == d_qinfo.end())
135
  {
136
    // does not impact
137
39089
    return;
138
  }
139
40
  std::vector<Node> vars(q[0].begin(), q[0].end());
140
20
  Assert(vars.size() == ts.size());
141
  std::vector<Node>& cmds =
142
20
      isInst ? it->second.d_instAddToPool : it->second.d_skolemAddToPool;
143
28
  for (const Node& c : cmds)
144
  {
145
8
    Assert(c.getNumChildren() == 2);
146
16
    Node t = c[0];
147
    // substitute the term
148
16
    Node st = t.substitute(vars.begin(), vars.end(), ts.begin(), ts.end());
149
    // add to pool
150
16
    Trace("pool-terms") << "Due to "
151
8
                        << (isInst ? "instantiation" : "skolemization")
152
8
                        << ", add " << st << " to pool " << c[1] << std::endl;
153
8
    TermPoolDomain& dom = d_pools[c[1]];
154
8
    dom.d_terms.push_back(st);
155
  }
156
}
157
158
}  // namespace quantifiers
159
}  // namespace theory
160
29340
}  // namespace cvc5