GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/lazy_trie.cpp Lines: 73 78 93.6 %
Date: 2021-11-06 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
2640
Node LazyTrie::add(Node n,
23
                   LazyTrieEvaluator* ev,
24
                   unsigned index,
25
                   unsigned ntotal,
26
                   bool forceKeep)
27
{
28
2640
  LazyTrie* lt = this;
29
160064
  while (lt != NULL)
30
  {
31
81352
    if (index == ntotal)
32
    {
33
      // lazy child holds the leaf data
34
1231
      if (lt->d_lazy_child.isNull() || forceKeep)
35
      {
36
523
        lt->d_lazy_child = n;
37
      }
38
3871
      return lt->d_lazy_child;
39
    }
40
80121
    if (lt->d_children.empty())
41
    {
42
28013
      if (lt->d_lazy_child.isNull())
43
      {
44
        // no one has been here, we are done
45
1409
        lt->d_lazy_child = n;
46
1409
        return lt->d_lazy_child;
47
      }
48
      // evaluate the lazy child
49
53208
      Node e_lc = ev->evaluate(lt->d_lazy_child, index);
50
      // store at next level
51
26604
      lt->d_children[e_lc].d_lazy_child = lt->d_lazy_child;
52
      // replace
53
26604
      lt->d_lazy_child = Node::null();
54
    }
55
    // recurse
56
157424
    Node e = ev->evaluate(n, index);
57
78712
    lt = &lt->d_children[e];
58
78712
    index = index + 1;
59
  }
60
  return Node::null();
61
}
62
63
162
void LazyTrieMulti::addClassifier(LazyTrieEvaluator* ev, unsigned ntotal)
64
{
65
324
  Trace("lazy-trie-multi") << "LazyTrieM: Adding classifier " << ntotal + 1
66
162
                           << "\n";
67
324
  std::vector<IndTriePair> visit;
68
162
  unsigned index = 0;
69
  LazyTrie* trie;
70
162
  visit.push_back(IndTriePair(0, &d_trie));
71
646
  while (!visit.empty())
72
  {
73
242
    index = visit.back().first;
74
242
    trie = visit.back().second;
75
242
    visit.pop_back();
76
    // not at (previous) last level, traverse children
77
242
    if (index < ntotal)
78
    {
79
120
      for (std::pair<const Node, LazyTrie>& p_nt : trie->d_children)
80
      {
81
80
        visit.push_back(IndTriePair(index + 1, &p_nt.second));
82
      }
83
80
      continue;
84
    }
85
202
    Assert(trie->d_children.empty());
86
    // if last level and no element at leaf, ignore
87
202
    if (trie->d_lazy_child.isNull())
88
    {
89
      continue;
90
    }
91
    // apply new classifier
92
202
    Assert(d_rep_to_class.find(trie->d_lazy_child) != d_rep_to_class.end());
93
404
    std::vector<Node> prev_sep_class = d_rep_to_class[trie->d_lazy_child];
94
202
    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
202
    d_rep_to_class.erase(trie->d_lazy_child);
104
    // replace
105
202
    trie->d_lazy_child = Node::null();
106
638
    for (const Node& n : prev_sep_class)
107
    {
108
736
      Node eval = ev->evaluate(n, index);
109
436
      std::map<Node, LazyTrie>::iterator it = trie->d_children.find(eval);
110
572
      if (it != trie->d_children.end())
111
      {
112
        // add n to to map of item in next level
113
272
        Trace("lazy-trie-multi") << "...add " << n << " to the class of "
114
136
                                 << it->second.d_lazy_child << "\n";
115
136
        d_rep_to_class[it->second.d_lazy_child].push_back(n);
116
136
        continue;
117
      }
118
      // store at next level
119
300
      trie->d_children[eval].d_lazy_child = n;
120
      // create new map
121
300
      Trace("lazy-trie-multi") << "...create new class for : " << n << "\n";
122
300
      Assert(d_rep_to_class.find(n) == d_rep_to_class.end());
123
300
      d_rep_to_class[n].clear();
124
300
      d_rep_to_class[n].push_back(n);
125
    }
126
  }
127
162
}
128
129
388
Node LazyTrieMulti::add(Node f, LazyTrieEvaluator* ev, unsigned ntotal)
130
{
131
388
  Trace("lazy-trie-multi") << "LazyTrieM: Adding " << f << "\n";
132
388
  Node res = d_trie.add(f, ev, 0, ntotal, false);
133
  // f was added to the separation class with representative res
134
388
  if (res != f)
135
  {
136
516
    Trace("lazy-trie-multi") << "... added " << f << " to the sepclass of "
137
258
                             << res << "\n";
138
258
    Assert(d_rep_to_class.find(res) != d_rep_to_class.end());
139
258
    Assert(!d_rep_to_class[res].empty());
140
258
    d_rep_to_class[res].push_back(f);
141
258
    return res;
142
  }
143
  // f is the representatitve of a singleton seperation class
144
260
  Trace("lazy-trie-multi") << "... added " << f
145
130
                           << " as the rep of the sepclass with itself\n";
146
130
  Assert(d_rep_to_class.find(res) == d_rep_to_class.end());
147
130
  d_rep_to_class[res].clear();
148
130
  d_rep_to_class[res].push_back(f);
149
130
  return res;
150
}
151
152
130
void LazyTrieMulti::clear()
153
{
154
130
  d_trie.clear();
155
130
  d_rep_to_class.clear();
156
130
}
157
158
}  // namespace quantifiers
159
}  // namespace theory
160
31137
}  // namespace cvc5