GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/lazy_trie.cpp Lines: 73 78 93.6 %
Date: 2021-05-22 Branches: 124 314 39.5 %

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
2269
Node LazyTrie::add(Node n,
23
                   LazyTrieEvaluator* ev,
24
                   unsigned index,
25
                   unsigned ntotal,
26
                   bool forceKeep)
27
{
28
2269
  LazyTrie* lt = this;
29
108933
  while (lt != NULL)
30
  {
31
55601
    if (index == ntotal)
32
    {
33
      // lazy child holds the leaf data
34
1165
      if (lt->d_lazy_child.isNull() || forceKeep)
35
      {
36
501
        lt->d_lazy_child = n;
37
      }
38
3434
      return lt->d_lazy_child;
39
    }
40
54436
    if (lt->d_children.empty())
41
    {
42
19246
      if (lt->d_lazy_child.isNull())
43
      {
44
        // no one has been here, we are done
45
1104
        lt->d_lazy_child = n;
46
1104
        return lt->d_lazy_child;
47
      }
48
      // evaluate the lazy child
49
36284
      Node e_lc = ev->evaluate(lt->d_lazy_child, index);
50
      // store at next level
51
18142
      lt->d_children[e_lc].d_lazy_child = lt->d_lazy_child;
52
      // replace
53
18142
      lt->d_lazy_child = Node::null();
54
    }
55
    // recurse
56
106664
    Node e = ev->evaluate(n, index);
57
53332
    lt = &lt->d_children[e];
58
53332
    index = index + 1;
59
  }
60
  return Node::null();
61
}
62
63
132
void LazyTrieMulti::addClassifier(LazyTrieEvaluator* ev, unsigned ntotal)
64
{
65
264
  Trace("lazy-trie-multi") << "LazyTrieM: Adding classifier " << ntotal + 1
66
132
                           << "\n";
67
264
  std::vector<IndTriePair> visit;
68
132
  unsigned index = 0;
69
  LazyTrie* trie;
70
132
  visit.push_back(IndTriePair(0, &d_trie));
71
404
  while (!visit.empty())
72
  {
73
136
    index = visit.back().first;
74
136
    trie = visit.back().second;
75
136
    visit.pop_back();
76
    // not at (previous) last level, traverse children
77
136
    if (index < ntotal)
78
    {
79
6
      for (std::pair<const Node, LazyTrie>& p_nt : trie->d_children)
80
      {
81
4
        visit.push_back(IndTriePair(index + 1, &p_nt.second));
82
      }
83
4
      continue;
84
    }
85
134
    Assert(trie->d_children.empty());
86
    // if last level and no element at leaf, ignore
87
134
    if (trie->d_lazy_child.isNull())
88
    {
89
      continue;
90
    }
91
    // apply new classifier
92
134
    Assert(d_rep_to_class.find(trie->d_lazy_child) != d_rep_to_class.end());
93
268
    std::vector<Node> prev_sep_class = d_rep_to_class[trie->d_lazy_child];
94
134
    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
134
    d_rep_to_class.erase(trie->d_lazy_child);
104
    // replace
105
134
    trie->d_lazy_child = Node::null();
106
537
    for (const Node& n : prev_sep_class)
107
    {
108
600
      Node eval = ev->evaluate(n, index);
109
403
      std::map<Node, LazyTrie>::iterator it = trie->d_children.find(eval);
110
609
      if (it != trie->d_children.end())
111
      {
112
        // add n to to map of item in next level
113
412
        Trace("lazy-trie-multi") << "...add " << n << " to the class of "
114
206
                                 << it->second.d_lazy_child << "\n";
115
206
        d_rep_to_class[it->second.d_lazy_child].push_back(n);
116
206
        continue;
117
      }
118
      // store at next level
119
197
      trie->d_children[eval].d_lazy_child = n;
120
      // create new map
121
197
      Trace("lazy-trie-multi") << "...create new class for : " << n << "\n";
122
197
      Assert(d_rep_to_class.find(n) == d_rep_to_class.end());
123
197
      d_rep_to_class[n].clear();
124
197
      d_rep_to_class[n].push_back(n);
125
    }
126
  }
127
132
}
128
129
444
Node LazyTrieMulti::add(Node f, LazyTrieEvaluator* ev, unsigned ntotal)
130
{
131
444
  Trace("lazy-trie-multi") << "LazyTrieM: Adding " << f << "\n";
132
444
  Node res = d_trie.add(f, ev, 0, ntotal, false);
133
  // f was added to the separation class with representative res
134
444
  if (res != f)
135
  {
136
620
    Trace("lazy-trie-multi") << "... added " << f << " to the sepclass of "
137
310
                             << res << "\n";
138
310
    Assert(d_rep_to_class.find(res) != d_rep_to_class.end());
139
310
    Assert(!d_rep_to_class[res].empty());
140
310
    d_rep_to_class[res].push_back(f);
141
310
    return res;
142
  }
143
  // f is the representatitve of a singleton seperation class
144
268
  Trace("lazy-trie-multi") << "... added " << f
145
134
                           << " as the rep of the sepclass with itself\n";
146
134
  Assert(d_rep_to_class.find(res) == d_rep_to_class.end());
147
134
  d_rep_to_class[res].clear();
148
134
  d_rep_to_class[res].push_back(f);
149
134
  return res;
150
}
151
152
134
void LazyTrieMulti::clear()
153
{
154
134
  d_trie.clear();
155
134
  d_rep_to_class.clear();
156
134
}
157
158
}  // namespace quantifiers
159
}  // namespace theory
160
28194
}  // namespace cvc5