GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/term_pools.cpp Lines: 72 74 97.3 %
Date: 2021-05-22 Branches: 94 230 40.9 %

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
4981
void TermPoolQuantInfo::initialize()
34
{
35
4981
  d_instAddToPool.clear();
36
4981
  d_skolemAddToPool.clear();
37
4981
}
38
39
9460
TermPools::TermPools(QuantifiersState& qs) : d_qs(qs) {}
40
41
24825
bool TermPools::reset(Theory::Effort e)
42
{
43
24837
  for (std::pair<const Node, TermPoolDomain>& p : d_pools)
44
  {
45
12
    p.second.d_currTerms.clear();
46
  }
47
24825
  return true;
48
}
49
50
25053
void TermPools::registerQuantifier(Node q)
51
{
52
25053
  if (q.getNumChildren() < 3)
53
  {
54
20072
    return;
55
  }
56
4981
  TermPoolQuantInfo& qi = d_qinfo[q];
57
4981
  qi.initialize();
58
10303
  for (const Node& p : q[2])
59
  {
60
5322
    Kind pk = p.getKind();
61
5322
    if (pk == kind::INST_ADD_TO_POOL)
62
    {
63
      qi.d_instAddToPool.push_back(p);
64
    }
65
5322
    else if (pk == kind::SKOLEM_ADD_TO_POOL)
66
    {
67
8
      qi.d_skolemAddToPool.push_back(p);
68
    }
69
  }
70
4981
  if (qi.d_instAddToPool.empty() && qi.d_skolemAddToPool.empty())
71
  {
72
4973
    d_qinfo.erase(q);
73
  }
74
}
75
76
24825
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
8
    for (const Node& t : dom.d_terms)
104
    {
105
8
      Node r = d_qs.getRepresentative(t);
106
4
      if (reps.find(r) == reps.end())
107
      {
108
4
        reps.insert(r);
109
4
        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
36917
void TermPools::processInstantiation(Node q, const std::vector<Node>& terms)
119
{
120
36917
  processInternal(q, terms, true);
121
36917
}
122
123
2501
void TermPools::processSkolemization(Node q, const std::vector<Node>& skolems)
124
{
125
2501
  processInternal(q, skolems, false);
126
2501
}
127
128
39418
void TermPools::processInternal(Node q,
129
                                const std::vector<Node>& ts,
130
                                bool isInst)
131
{
132
39418
  Assert(q.getKind() == kind::FORALL);
133
39418
  std::map<Node, TermPoolQuantInfo>::iterator it = d_qinfo.find(q);
134
39418
  if (it == d_qinfo.end())
135
  {
136
    // does not impact
137
39402
    return;
138
  }
139
32
  std::vector<Node> vars(q[0].begin(), q[0].end());
140
16
  Assert(vars.size() == ts.size());
141
  std::vector<Node>& cmds =
142
16
      isInst ? it->second.d_instAddToPool : it->second.d_skolemAddToPool;
143
24
  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
28194
}  // namespace cvc5