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