Branch data Line data Source code
1 : : /******************************************************************************
2 : : * This file is part of the cvc5 project.
3 : : *
4 : : * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
5 : : * in the top-level source directory and their institutional affiliations.
6 : : * All rights reserved. See the file COPYING in the top-level source
7 : : * directory for licensing information.
8 : : * ****************************************************************************
9 : : *
10 : : * Implementation of a trie that store subsets of tuples of term indices
11 : : * that are not yielding useful instantiations. of quantifier instantiation.
12 : : * This is used in the term_tuple_enumerator.
13 : : */
14 : : #include "theory/quantifiers/index_trie.h"
15 : :
16 : : namespace cvc5::internal {
17 : : namespace theory {
18 : : namespace quantifiers {
19 : :
20 : 83496 : void IndexTrie::add(const std::vector<bool>& mask,
21 : : const std::vector<Node>& values)
22 : : {
23 : 83496 : const size_t cardinality = std::count(mask.begin(), mask.end(), true);
24 [ + - ][ + + ]: 83496 : if (d_ignoreFullySpecified && cardinality == mask.size())
[ + + ]
25 : : {
26 : 63894 : return;
27 : : }
28 : :
29 : 19602 : d_root = addRec(d_root, 0, cardinality, mask, values);
30 : : }
31 : :
32 : 97105 : void IndexTrie::freeRec(IndexTrieNode* n)
33 : : {
34 [ + + ]: 97105 : if (!n)
35 : : {
36 : 55382 : return;
37 : : }
38 [ + + ]: 67841 : for (auto c : n->d_children)
39 : : {
40 : 26118 : freeRec(c.second);
41 : 26118 : }
42 : 41723 : freeRec(n->d_blank);
43 [ + - ]: 41723 : delete n;
44 : : }
45 : :
46 : 215552 : bool IndexTrie::findRec(const IndexTrieNode* n,
47 : : size_t index,
48 : : const std::vector<Node>& members,
49 : : size_t& nonBlankLength) const
50 : : {
51 [ + + ][ - + ]: 215552 : if (!n || index >= members.size())
[ + + ]
52 : : {
53 : 4454 : return true; // all elements of members matched
54 : : }
55 [ + + ][ + + ]: 211098 : if (n->d_blank && findRec(n->d_blank, index + 1, members, nonBlankLength))
[ + + ]
56 : : {
57 : 2539 : return true; // found in the blank branch
58 : : }
59 [ + + ]: 208559 : if (members[index].isNull())
60 : : {
61 : : // null is interpreted as "any", must have found in the blank branch
62 : 12131 : return false;
63 : : }
64 : 196428 : nonBlankLength = index + 1;
65 [ + + ]: 1926203 : for (const auto& c : n->d_children)
66 : : {
67 : 1738886 : if (c.first == members[index]
68 [ + + ][ + + ]: 1738886 : && findRec(c.second, index + 1, members, nonBlankLength))
[ + + ]
69 : : {
70 : 9111 : return true; // found in the matching subtree
71 : : }
72 : : }
73 : 187317 : return false;
74 : : }
75 : :
76 : 61474 : IndexTrieNode* IndexTrie::addRec(IndexTrieNode* n,
77 : : size_t index,
78 : : size_t cardinality,
79 : : const std::vector<bool>& mask,
80 : : const std::vector<Node>& values)
81 : : {
82 [ - + ]: 61474 : if (!n)
83 : : {
84 : 0 : return nullptr; // this tree matches everything, no point to add
85 : : }
86 [ + + ]: 61474 : if (cardinality == 0) // all blanks, all strings match
87 : : {
88 : 19602 : freeRec(n);
89 : 19602 : return nullptr;
90 : : }
91 : :
92 [ - + ][ - + ]: 41872 : Assert(index < mask.size());
[ - - ]
93 : :
94 [ + + ]: 41872 : if (!mask[index]) // blank position in the added vector
95 : : {
96 [ + + ]: 12557 : auto blank = n->d_blank ? n->d_blank : new IndexTrieNode();
97 : 12557 : n->d_blank = addRec(blank, index + 1, cardinality, mask, values);
98 : 12557 : return n;
99 : : }
100 [ - + ][ - + ]: 29315 : Assert(cardinality);
[ - - ]
101 [ - + ][ - + ]: 29315 : Assert(!values[index].isNull());
[ - - ]
102 [ + + ]: 437934 : for (auto& edge : n->d_children)
103 : : {
104 [ + + ]: 411816 : if (edge.first == values[index])
105 : : {
106 : : // value already amongst the children
107 : 3197 : edge.second =
108 : 3197 : addRec(edge.second, index + 1, cardinality - 1, mask, values);
109 : 3197 : return n;
110 : : }
111 : : }
112 : : // new child needs to be added
113 : : auto child =
114 : 26118 : addRec(new IndexTrieNode(), index + 1, cardinality - 1, mask, values);
115 : 26118 : n->d_children.push_back(std::make_pair(values[index], child));
116 : 26118 : return n;
117 : : }
118 : : } // namespace quantifiers
119 : : } // namespace theory
120 : : } // namespace cvc5::internal
|