--- /dev/null
+/******************************************************************************
+ * Top contributors (to current version):
+ * Andrew Reynolds
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved. See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Algorithms for node tries
+ */
+
+#include "expr/node_trie_algorithm.h"
+
+namespace cvc5 {
+
+void nodeTriePathPairProcess(const TNodeTrie* t,
+ size_t arity,
+ NodeTriePathPairProcessCallback& ntpc)
+{
+ std::vector<std::tuple<const TNodeTrie*, const TNodeTrie*, size_t>> visit;
+ std::tuple<const TNodeTrie*, const TNodeTrie*, size_t> cur;
+ const TNodeTrie* t1;
+ const TNodeTrie* t2;
+ size_t depth;
+ visit.emplace_back(t, nullptr, 0);
+ do
+ {
+ cur = visit.back();
+ t1 = std::get<0>(cur);
+ t2 = std::get<1>(cur);
+ depth = std::get<2>(cur);
+ visit.pop_back();
+ if (depth == arity)
+ {
+ // We are at the leaves. If we split the path, process the data.
+ if (t2 != nullptr)
+ {
+ ntpc.processData(t1->getData(), t2->getData());
+ }
+ }
+ else if (t2 == nullptr)
+ {
+ // we are exploring paths with a common prefix
+ if (depth < (arity - 1))
+ {
+ // continue exploring paths with common prefix, internal to each child
+ for (const std::pair<const TNode, TNodeTrie>& tt : t1->d_data)
+ {
+ visit.emplace_back(&tt.second, nullptr, depth + 1);
+ }
+ }
+ // consider splitting the path at this node
+ for (std::map<TNode, TNodeTrie>::const_iterator it = t1->d_data.begin();
+ it != t1->d_data.end();
+ ++it)
+ {
+ std::map<TNode, TNodeTrie>::const_iterator it2 = it;
+ ++it2;
+ for (; it2 != t1->d_data.end(); ++it2)
+ {
+ if (ntpc.considerPath(it->first, it2->first))
+ {
+ visit.emplace_back(&it->second, &it2->second, depth + 1);
+ }
+ }
+ }
+ }
+ else
+ {
+ Assert(t1 != t2);
+ // considering two different paths, take the product of their children
+ for (const std::pair<const TNode, TNodeTrie>& tt1 : t1->d_data)
+ {
+ for (const std::pair<const TNode, TNodeTrie>& tt2 : t2->d_data)
+ {
+ if (ntpc.considerPath(tt1.first, tt2.first))
+ {
+ visit.emplace_back(&tt1.second, &tt2.second, depth + 1);
+ }
+ }
+ }
+ }
+ } while (!visit.empty());
+}
+
+} // namespace cvc5
--- /dev/null
+/******************************************************************************
+ * Top contributors (to current version):
+ * Andrew Reynolds
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved. See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Algorithms for node tries
+ */
+
+#include "cvc5_private.h"
+
+#ifndef CVC5__EXPR__NODE_TRIE_ALGORITHM_H
+#define CVC5__EXPR__NODE_TRIE_ALGORITHM_H
+
+#include "expr/node_trie.h"
+
+namespace cvc5 {
+
+/** A virtual base class for the algorithm below. */
+class NodeTriePathPairProcessCallback
+{
+ public:
+ NodeTriePathPairProcessCallback() {}
+ virtual ~NodeTriePathPairProcessCallback() {}
+ /** Whether to consider a pair in paths in a trie */
+ virtual bool considerPath(TNode a, TNode b) = 0;
+ /** Process leaves */
+ virtual void processData(TNode fa, TNode fb) = 0;
+};
+
+/**
+ * Given a TNode trie of arity n, this calls ntpc.processData(fa, fb) on all
+ * pairs of distinct leaves fa and fb in t at paths [fa1, ..., fan] and
+ * [fb1, ..., fbn] in t such that ntpc.considerPath(fai, fbi) returns true for
+ * all i = 1, ..., n.
+ *
+ * A common use case for this algorithm is computing the care graph for theory
+ * combination.
+ */
+void nodeTriePathPairProcess(const TNodeTrie* t,
+ size_t n,
+ NodeTriePathPairProcessCallback& ntpc);
+
+} // namespace cvc5
+
+#endif /* CVC5__EXPR__NODE_TRIE_ALGORITHM_H */