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 : : * Utilities for constructing canonical terms. 11 : : */ 12 : : 13 : : #include "cvc5_private.h" 14 : : 15 : : #ifndef CVC5__EXPR__TERM_CANONIZE_H 16 : : #define CVC5__EXPR__TERM_CANONIZE_H 17 : : 18 : : #include <map> 19 : : #include "expr/node.h" 20 : : 21 : : namespace cvc5::internal { 22 : : namespace expr { 23 : : 24 : : /** 25 : : * Generalization of types. This class is a simple callback for giving 26 : : * identifiers to variables that may be a more fine-grained way of classifying 27 : : * the variable than its type. An example usage of type classes are for 28 : : * distinguishing "list variables" for rewrite rule reconstruction. 29 : : */ 30 : : class TypeClassCallback 31 : : { 32 : : public: 33 : 6733 : TypeClassCallback() {} 34 : 6725 : virtual ~TypeClassCallback() {} 35 : : /** Return the type class for variable v */ 36 : : virtual uint32_t getTypeClass(TNode v) = 0; 37 : : }; 38 : : 39 : : /** TermCanonize 40 : : * 41 : : * This class contains utilities for canonizing terms with respect to 42 : : * free variables (which are of kind BOUND_VARIABLE). For example, this 43 : : * class infers that terms like f(BOUND_VARIABLE_1) and f(BOUND_VARIABLE_2) 44 : : * are effectively the same term. 45 : : */ 46 : : class TermCanonize 47 : : { 48 : : public: 49 : : /** 50 : : * @param tcc The type class callback. This class will canonize variables in 51 : : * a way that disinguishes variables that are given different type class 52 : : * identifiers. Otherwise, this class will assume all variables of the 53 : : * same type have the same type class. 54 : : */ 55 : : TermCanonize(TypeClassCallback* tcc = nullptr); 56 : 119267 : ~TermCanonize() {} 57 : : 58 : : /** Maps operators to an identifier, useful for ordering. */ 59 : : int getIdForOperator(Node op); 60 : : /** Maps types to an identifier, useful for ordering. */ 61 : : int getIdForType(TypeNode t); 62 : : /** get term order 63 : : * 64 : : * Returns true if a <= b in the term ordering used by this class. The 65 : : * term order is determined by the leftmost position in a and b whose 66 : : * operators o_a and o_b are distinct at that position. Then a <= b iff 67 : : * getIdForOperator( o_a ) <= getIdForOperator( o_b ). 68 : : */ 69 : : bool getTermOrder(Node a, Node b); 70 : : /** get canonical free variable #i of type tn */ 71 : : Node getCanonicalFreeVar(TypeNode tn, size_t i, uint32_t tc = 0); 72 : : /** 73 : : * Return the range of the free variable in the above map, or 0 if it does not 74 : : * exist. 75 : : */ 76 : : size_t getIndexForFreeVariable(Node v) const; 77 : : /** get canonical term 78 : : * 79 : : * This returns a canonical (alpha-equivalent) version of n, where 80 : : * bound variables in n may be replaced by other ones, and arguments of 81 : : * commutative operators of n may be sorted (if apply_torder is true). If 82 : : * doHoVar is true, we also canonicalize bound variables that occur in 83 : : * operators. 84 : : * 85 : : * In detail, we replace bound variables in n so the the leftmost occurrence 86 : : * of a bound variable for type T is the first canonical free variable for T, 87 : : * the second leftmost is the second, and so on, for each type T. 88 : : */ 89 : : Node getCanonicalTerm(TNode n, 90 : : bool apply_torder = false, 91 : : bool doHoVar = true); 92 : : /** 93 : : * Same as above but tracks visited map, mapping subterms of n to their 94 : : * canonical forms. 95 : : */ 96 : : Node getCanonicalTerm(TNode n, 97 : : std::map<TNode, Node>& visited, 98 : : bool apply_torder = false, 99 : : bool doHoVar = true); 100 : : 101 : : private: 102 : : /** The (optional) type class callback */ 103 : : TypeClassCallback* d_tcc; 104 : : /** the number of ids we have allocated for operators */ 105 : : int d_op_id_count; 106 : : /** map from operators to id */ 107 : : std::map<Node, int> d_op_id; 108 : : /** the number of ids we have allocated for types */ 109 : : int d_typ_id_count; 110 : : /** map from type to id */ 111 : : std::map<TypeNode, int> d_typ_id; 112 : : /** free variables for each type / type class pair */ 113 : : std::map<std::pair<TypeNode, uint32_t>, std::vector<Node> > d_cn_free_var; 114 : : /** 115 : : * Map from each free variable above to their index in their respective vector 116 : : */ 117 : : std::map<Node, size_t> d_fvIndex; 118 : : /** Get type class */ 119 : : uint32_t getTypeClass(TNode v); 120 : : /** get canonical term 121 : : * 122 : : * This is a helper function for getCanonicalTerm above. We maintain a 123 : : * counter of how many variables we have allocated for each type (var_count), 124 : : * and a cache of visited nodes (visited). 125 : : */ 126 : : Node getCanonicalTerm( 127 : : TNode n, 128 : : bool apply_torder, 129 : : bool doHoVar, 130 : : std::map<std::pair<TypeNode, uint32_t>, unsigned>& var_count, 131 : : std::map<TNode, Node>& visited); 132 : : }; 133 : : 134 : : } // namespace expr 135 : : } // namespace cvc5::internal 136 : : 137 : : #endif /* CVC5__EXPR__TERM_CANONIZE_H */