GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/index_trie.cpp Lines: 42 43 97.7 %
Date: 2021-11-07 Branches: 55 98 56.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   MikolasJanota
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 a trie that store subsets of tuples of term indices
14
 * that are not yielding  useful instantiations. of quantifier instantiation.
15
 * This is used in the term_tuple_enumerator.
16
 */
17
#include "theory/quantifiers/index_trie.h"
18
19
namespace cvc5 {
20
namespace theory {
21
namespace quantifiers {
22
23
4116
void IndexTrie::add(const std::vector<bool>& mask,
24
                    const std::vector<size_t>& values)
25
{
26
4116
  const size_t cardinality = std::count(mask.begin(), mask.end(), true);
27
4116
  if (d_ignoreFullySpecified && cardinality == mask.size())
28
  {
29
3766
    return;
30
  }
31
32
350
  d_root = addRec(d_root, 0, cardinality, mask, values);
33
}
34
35
7396
void IndexTrie::freeRec(IndexTrieNode* n)
36
{
37
7396
  if (!n)
38
  {
39
3854
    return;
40
  }
41
5323
  for (auto c : n->d_children)
42
  {
43
1781
    freeRec(c.second);
44
  }
45
3542
  freeRec(n->d_blank);
46
3542
  delete n;
47
}
48
49
7310
bool IndexTrie::findRec(const IndexTrieNode* n,
50
                        size_t index,
51
                        const std::vector<size_t>& members,
52
                        size_t& nonBlankLength) const
53
{
54
7310
  if (!n || index >= members.size())
55
  {
56
278
    return true;  // all elements of members matched
57
  }
58
7032
  if (n->d_blank && findRec(n->d_blank, index + 1, members, nonBlankLength))
59
  {
60
76
    return true;  // found in the blank branch
61
  }
62
6956
  nonBlankLength = index + 1;
63
9376
  for (const auto& c : n->d_children)
64
  {
65
7752
    if (c.first == members[index]
66
3876
        && findRec(c.second, index + 1, members, nonBlankLength))
67
    {
68
1456
      return true;  // found in the matching subtree
69
    }
70
  }
71
5500
  return false;
72
}
73
74
2610
IndexTrieNode* IndexTrie::addRec(IndexTrieNode* n,
75
                                 size_t index,
76
                                 size_t cardinality,
77
                                 const std::vector<bool>& mask,
78
                                 const std::vector<size_t>& values)
79
{
80
2610
  if (!n)
81
  {
82
    return nullptr;  // this tree matches everything, no point to add
83
  }
84
2610
  if (cardinality == 0)  // all blanks, all strings match
85
  {
86
350
    freeRec(n);
87
350
    return nullptr;
88
  }
89
90
2260
  Assert(index < mask.size());
91
92
2260
  if (!mask[index])  // blank position in the added vector
93
  {
94
62
    auto blank = n->d_blank ? n->d_blank : new IndexTrieNode();
95
62
    n->d_blank = addRec(blank, index + 1, cardinality, mask, values);
96
62
    return n;
97
  }
98
2198
  Assert(cardinality);
99
100
2290
  for (auto& edge : n->d_children)
101
  {
102
509
    if (edge.first == values[index])
103
    {
104
      // value already amongst the children
105
417
      edge.second =
106
417
          addRec(edge.second, index + 1, cardinality - 1, mask, values);
107
417
      return n;
108
    }
109
  }
110
  // new child needs to be added
111
  auto child =
112
1781
      addRec(new IndexTrieNode(), index + 1, cardinality - 1, mask, values);
113
1781
  n->d_children.push_back(std::make_pair(values[index], child));
114
1781
  return n;
115
}
116
}  // namespace quantifiers
117
}  // namespace theory
118
}  // namespace cvc5