Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds, Haniel Barbosa 4 : : * 5 : : * This file is part of the cvc5 project. 6 : : * 7 : : * Copyright (c) 2009-2024 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 : : * Node converter utility 14 : : */ 15 : : 16 : : #include "cvc5_private.h" 17 : : 18 : : #ifndef CVC5__EXPR__NODE_CONVERTER_H 19 : : #define CVC5__EXPR__NODE_CONVERTER_H 20 : : 21 : : #include <iostream> 22 : : #include <map> 23 : : 24 : : #include "expr/node.h" 25 : : #include "expr/type_node.h" 26 : : 27 : : namespace cvc5::internal { 28 : : 29 : : /** 30 : : * A node converter for terms and types. Implements term/type traversals, 31 : : * calling the provided implementations of conversion methods (pre/postConvert 32 : : * and pre/postConvertType) at pre-traversal and post-traversal. 33 : : * 34 : : * This class can be used as a generic method for converting terms/types, which 35 : : * is orthogonal to methods for traversing nodes. 36 : : */ 37 : : class NodeConverter 38 : : { 39 : : public: 40 : : /** 41 : : * @param forceIdem If true, this assumes that terms returned by postConvert 42 : : * and postConvertType should not be converted again. 43 : : */ 44 : : NodeConverter(NodeManager* nm, bool forceIdem = true); 45 : 146937 : virtual ~NodeConverter() {} 46 : : /** 47 : : * This converts node n based on the preConvert/postConvert methods that can 48 : : * be overriden by instances of this class. 49 : : * 50 : : * If n is null, this always returns the null node. 51 : : * 52 : : * @param preserveTypes If true, we make calls to postConvert below for the 53 : : * conversion, which requires that the conversion preserves the types of 54 : : * all subterms in n. If false, we make calls to postConvertUntyped, which 55 : : * may change the type of subterms. 56 : : */ 57 : : Node convert(Node n, bool preserveTypes = true); 58 : : 59 : : /** 60 : : * This converts type node n based on the preConvertType/postConvertType 61 : : * methods that can be overriden by instances of this class. 62 : : */ 63 : : TypeNode convertType(TypeNode tn); 64 : : 65 : : protected: 66 : : //------------------------- virtual interface 67 : : /** Should we traverse n? */ 68 : : virtual bool shouldTraverse(Node n); 69 : : /** 70 : : * Run the conversion for n during pre-order traversal. 71 : : * Returning null is equivalent to saying the node should not be changed. 72 : : * 73 : : * If convert is called with preserveTypes=true, then we require that the 74 : : * type of the returned term (if non-null) is the same as the type of n. 75 : : */ 76 : : virtual Node preConvert(Node n); 77 : : /** 78 : : * Run the conversion for post-order traversal, where notice n is a term 79 : : * of the form: 80 : : * (f i_1 ... i_m) 81 : : * where i_1, ..., i_m are terms that have been returned by previous calls 82 : : * to postConvert. 83 : : * 84 : : * Returning null is equivalent to saying the node should not be changed. 85 : : * 86 : : * We require that the type of the returned term (if non-null) is the same 87 : : * as the type of n. 88 : : */ 89 : : virtual Node postConvert(Node n); 90 : : /** 91 : : * Run the conversion for post-porder traversal. If orig is of the form 92 : : * (f e_1 ... e_m), then terms is {i_1, ..., i_m}, where i_1, ..., i_m 93 : : * is the result of converting e_1, ..., e_m. In contrast to the above 94 : : * method, the type of the returned term does not need to match the type 95 : : * of orig. The method also takes whether any of the elements of terms differ 96 : : * from the children of orig. 97 : : */ 98 : : virtual Node postConvertUntyped(Node orig, 99 : : const std::vector<Node>& terms, 100 : : bool termsChanged); 101 : : /** 102 : : * Run the conversion, same as `preConvert`, but for type nodes, which notice 103 : : * can be built from children similar to Node. 104 : : */ 105 : : virtual TypeNode preConvertType(TypeNode n); 106 : : /** 107 : : * Run the conversion, same as `postConvert`, but for type nodes, which notice 108 : : * can be built from children similar to Node. 109 : : */ 110 : : virtual TypeNode postConvertType(TypeNode n); 111 : : //------------------------- end virtual interface 112 : : protected: 113 : : /** The underlying node manager */ 114 : : NodeManager* d_nm; 115 : : 116 : : private: 117 : : /** Add to cache */ 118 : : void addToCache(TNode cur, TNode ret); 119 : : /** Add to type cache */ 120 : : void addToTypeCache(TypeNode cur, TypeNode ret); 121 : : /** Node cache for preConvert */ 122 : : std::unordered_map<Node, Node> d_preCache; 123 : : /** Node cache for postConvert */ 124 : : std::unordered_map<Node, Node> d_cache; 125 : : /** TypeNode cache for preConvert */ 126 : : std::unordered_map<TypeNode, TypeNode> d_preTCache; 127 : : /** TypeNode cache for postConvert */ 128 : : std::unordered_map<TypeNode, TypeNode> d_tcache; 129 : : /** Whether this node converter is idempotent. */ 130 : : bool d_forceIdem; 131 : : }; 132 : : 133 : : } // namespace cvc5::internal 134 : : 135 : : #endif