GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/lazy_trie.cpp Lines: 73 78 93.6 %
Date: 2021-09-17 Branches: 124 312 39.7 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Haniel Barbosa, 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
 * Implementation of lazy trie.
14
 */
15
16
#include "theory/quantifiers/lazy_trie.h"
17
18
namespace cvc5 {
19
namespace theory {
20
namespace quantifiers {
21
22
2335
Node LazyTrie::add(Node n,
23
                   LazyTrieEvaluator* ev,
24
                   unsigned index,
25
                   unsigned ntotal,
26
                   bool forceKeep)
27
{
28
2335
  LazyTrie* lt = this;
29
113259
  while (lt != NULL)
30
  {
31
57797
    if (index == ntotal)
32
    {
33
      // lazy child holds the leaf data
34
1216
      if (lt->d_lazy_child.isNull() || forceKeep)
35
      {
36
513
        lt->d_lazy_child = n;
37
      }
38
3551
      return lt->d_lazy_child;
39
    }
40
56581
    if (lt->d_children.empty())
41
    {
42
19901
      if (lt->d_lazy_child.isNull())
43
      {
44
        // no one has been here, we are done
45
1119
        lt->d_lazy_child = n;
46
1119
        return lt->d_lazy_child;
47
      }
48
      // evaluate the lazy child
49
37564
      Node e_lc = ev->evaluate(lt->d_lazy_child, index);
50
      // store at next level
51
18782
      lt->d_children[e_lc].d_lazy_child = lt->d_lazy_child;
52
      // replace
53
18782
      lt->d_lazy_child = Node::null();
54
    }
55
    // recurse
56
110924
    Node e = ev->evaluate(n, index);
57
55462
    lt = &lt->d_children[e];
58
55462
    index = index + 1;
59
  }
60
  return Node::null();
61
}
62
63
224
void LazyTrieMulti::addClassifier(LazyTrieEvaluator* ev, unsigned ntotal)
64
{
65
448
  Trace("lazy-trie-multi") << "LazyTrieM: Adding classifier " << ntotal + 1
66
224
                           << "\n";
67
448
  std::vector<IndTriePair> visit;
68
224
  unsigned index = 0;
69
  LazyTrie* trie;
70
224
  visit.push_back(IndTriePair(0, &d_trie));
71
1028
  while (!visit.empty())
72
  {
73
402
    index = visit.back().first;
74
402
    trie = visit.back().second;
75
402
    visit.pop_back();
76
    // not at (previous) last level, traverse children
77
402
    if (index < ntotal)
78
    {
79
267
      for (std::pair<const Node, LazyTrie>& p_nt : trie->d_children)
80
      {
81
178
        visit.push_back(IndTriePair(index + 1, &p_nt.second));
82
      }
83
178
      continue;
84
    }
85
313
    Assert(trie->d_children.empty());
86
    // if last level and no element at leaf, ignore
87
313
    if (trie->d_lazy_child.isNull())
88
    {
89
      continue;
90
    }
91
    // apply new classifier
92
313
    Assert(d_rep_to_class.find(trie->d_lazy_child) != d_rep_to_class.end());
93
626
    std::vector<Node> prev_sep_class = d_rep_to_class[trie->d_lazy_child];
94
313
    if (Trace.isOn("lazy-trie-multi"))
95
    {
96
      Trace("lazy-trie-multi") << "...last level. Prev sep class: \n";
97
      for (const Node& n : prev_sep_class)
98
      {
99
        Trace("lazy-trie-multi") << "...... " << n << "\n";
100
      }
101
    }
102
    // make new sepclass of lc a singleton with itself
103
313
    d_rep_to_class.erase(trie->d_lazy_child);
104
    // replace
105
313
    trie->d_lazy_child = Node::null();
106
938
    for (const Node& n : prev_sep_class)
107
    {
108
1087
      Node eval = ev->evaluate(n, index);
109
625
      std::map<Node, LazyTrie>::iterator it = trie->d_children.find(eval);
110
788
      if (it != trie->d_children.end())
111
      {
112
        // add n to to map of item in next level
113
326
        Trace("lazy-trie-multi") << "...add " << n << " to the class of "
114
163
                                 << it->second.d_lazy_child << "\n";
115
163
        d_rep_to_class[it->second.d_lazy_child].push_back(n);
116
163
        continue;
117
      }
118
      // store at next level
119
462
      trie->d_children[eval].d_lazy_child = n;
120
      // create new map
121
462
      Trace("lazy-trie-multi") << "...create new class for : " << n << "\n";
122
462
      Assert(d_rep_to_class.find(n) == d_rep_to_class.end());
123
462
      d_rep_to_class[n].clear();
124
462
      d_rep_to_class[n].push_back(n);
125
    }
126
  }
127
224
}
128
129
485
Node LazyTrieMulti::add(Node f, LazyTrieEvaluator* ev, unsigned ntotal)
130
{
131
485
  Trace("lazy-trie-multi") << "LazyTrieM: Adding " << f << "\n";
132
485
  Node res = d_trie.add(f, ev, 0, ntotal, false);
133
  // f was added to the separation class with representative res
134
485
  if (res != f)
135
  {
136
692
    Trace("lazy-trie-multi") << "... added " << f << " to the sepclass of "
137
346
                             << res << "\n";
138
346
    Assert(d_rep_to_class.find(res) != d_rep_to_class.end());
139
346
    Assert(!d_rep_to_class[res].empty());
140
346
    d_rep_to_class[res].push_back(f);
141
346
    return res;
142
  }
143
  // f is the representatitve of a singleton seperation class
144
278
  Trace("lazy-trie-multi") << "... added " << f
145
139
                           << " as the rep of the sepclass with itself\n";
146
139
  Assert(d_rep_to_class.find(res) == d_rep_to_class.end());
147
139
  d_rep_to_class[res].clear();
148
139
  d_rep_to_class[res].push_back(f);
149
139
  return res;
150
}
151
152
139
void LazyTrieMulti::clear()
153
{
154
139
  d_trie.clear();
155
139
  d_rep_to_class.clear();
156
139
}
157
158
}  // namespace quantifiers
159
}  // namespace theory
160
29577
}  // namespace cvc5