1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 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 |
|
* Implementation of LFSC node conversion |
14 |
|
*/ |
15 |
|
#include "cvc5_private.h" |
16 |
|
|
17 |
|
#ifndef CVC4__PROOF__LFSC__LFSC_NODE_CONVERTER_H |
18 |
|
#define CVC4__PROOF__LFSC__LFSC_NODE_CONVERTER_H |
19 |
|
|
20 |
|
#include <iostream> |
21 |
|
#include <map> |
22 |
|
|
23 |
|
#include "expr/node.h" |
24 |
|
#include "expr/node_converter.h" |
25 |
|
#include "expr/type_node.h" |
26 |
|
|
27 |
|
namespace cvc5 { |
28 |
|
namespace proof { |
29 |
|
|
30 |
|
/** |
31 |
|
* This is a helper class for the LFSC printer that converts nodes into |
32 |
|
* form that LFSC expects. It should only be used by the LFSC printer. |
33 |
|
*/ |
34 |
|
class LfscNodeConverter : public NodeConverter |
35 |
|
{ |
36 |
|
public: |
37 |
|
LfscNodeConverter(); |
38 |
|
~LfscNodeConverter() {} |
39 |
|
/** convert to internal */ |
40 |
|
Node postConvert(Node n) override; |
41 |
|
/** convert to internal */ |
42 |
|
TypeNode postConvertType(TypeNode tn) override; |
43 |
|
/** |
44 |
|
* Get the null terminator for kind k and type tn. The type tn can be |
45 |
|
* omitted if applications of kind k do not have parametric type. |
46 |
|
* |
47 |
|
* The returned null terminator is *not* converted to internal form. |
48 |
|
* |
49 |
|
* For examples of null terminators, see nary_term_utils.h. |
50 |
|
*/ |
51 |
|
Node getNullTerminator(Kind k, TypeNode tn = TypeNode::null()); |
52 |
|
/** |
53 |
|
* Return the properly named operator for n of the form (f t1 ... tn), where |
54 |
|
* f could be interpreted or uninterpreted. This method is used for cases |
55 |
|
* where it is important to get the term corresponding to the operator for |
56 |
|
* a term. An example is for the base REFL step of nested CONG. |
57 |
|
*/ |
58 |
|
Node getOperatorOfTerm(Node n, bool macroApply = false); |
59 |
|
/** |
60 |
|
* Recall that (forall ((x Int)) (P x)) is printed as: |
61 |
|
* (apply (forall N Int) (apply P (bvar N Int))) |
62 |
|
* in LFSC, where N is an integer indicating the id of the variable. |
63 |
|
* |
64 |
|
* Get closure operator. In the above example, this method returns the |
65 |
|
* uninterpreted function whose name is "forall" and is used to construct |
66 |
|
* higher-order operators for each bound variable in the closure. |
67 |
|
*/ |
68 |
|
Node getOperatorOfClosure(Node q, bool macroApply = false); |
69 |
|
/** |
70 |
|
* Get closure operator, where cop is the term returned by |
71 |
|
* getOperatorOfClosure(q), where q is the closures to which v |
72 |
|
* belongs. For example, for FORALL closures, this method will return the |
73 |
|
* node that prints as "(forall N Int)". |
74 |
|
*/ |
75 |
|
Node getOperatorOfBoundVar(Node cop, Node v); |
76 |
|
/** |
77 |
|
* Get the variable index for variable v, or assign a fresh index if it is |
78 |
|
* not yet assigned. |
79 |
|
*/ |
80 |
|
size_t getOrAssignIndexForVar(Node v); |
81 |
|
/** |
82 |
|
* Make an internal symbol with custom name. This is a BOUND_VARIABLE that |
83 |
|
* has a distinguished status so that it is *not* printed as (bvar ...). The |
84 |
|
* returned variable is always fresh. |
85 |
|
*/ |
86 |
|
Node mkInternalSymbol(const std::string& name, TypeNode tn); |
87 |
|
/** |
88 |
|
* Get builtin kind for internal symbol op |
89 |
|
*/ |
90 |
|
Kind getBuiltinKindForInternalSymbol(Node op) const; |
91 |
|
|
92 |
|
/** get name for user name */ |
93 |
|
static std::string getNameForUserName(const std::string& name); |
94 |
|
|
95 |
|
private: |
96 |
|
/** Should we traverse n? */ |
97 |
|
bool shouldTraverse(Node n) override; |
98 |
|
/** |
99 |
|
* Make skolem function, if k was constructed by a skolem function identifier |
100 |
|
* (in SkolemManager::mkSkolemFunction) that is supported in the LFSC |
101 |
|
* signature. |
102 |
|
*/ |
103 |
|
Node maybeMkSkolemFun(Node k, bool macroApply = false); |
104 |
|
/** |
105 |
|
* Type as node, returns a node that prints in the form that LFSC will |
106 |
|
* interpret as the type tni. This method is required since types can be |
107 |
|
* passed as arguments to terms. This method assumes that tni has been |
108 |
|
* converted to internal form (via the convertType method of this class). |
109 |
|
*/ |
110 |
|
Node typeAsNode(TypeNode tni) const; |
111 |
|
/** |
112 |
|
* Get symbol for term, a special case of the method below for the type and |
113 |
|
* kind of n. |
114 |
|
*/ |
115 |
|
Node getSymbolInternalFor(Node n, const std::string& name); |
116 |
|
/** |
117 |
|
* Get symbol internal, (k,tn,name) are for caching, name is the name. This |
118 |
|
* method returns a fresh symbol of the given name and type. It is frequently |
119 |
|
* used when the type of a native operator does not match the type of the |
120 |
|
* LFSC operator. |
121 |
|
*/ |
122 |
|
Node getSymbolInternal(Kind k, TypeNode tn, const std::string& name); |
123 |
|
/** |
124 |
|
* Get character vector, add internal vector of characters for c. |
125 |
|
*/ |
126 |
|
void getCharVectorInternal(Node c, std::vector<Node>& chars); |
127 |
|
/** Is k a kind that is printed as an indexed operator in LFSC? */ |
128 |
|
static bool isIndexedOperatorKind(Kind k); |
129 |
|
/** get indices for printing the operator of n in the LFSC format */ |
130 |
|
static std::vector<Node> getOperatorIndices(Kind k, Node n); |
131 |
|
/** terms with different syntax than smt2 */ |
132 |
|
std::map<std::tuple<Kind, TypeNode, std::string>, Node> d_symbolsMap; |
133 |
|
/** the set of all internally generated symbols */ |
134 |
|
std::unordered_set<Node> d_symbols; |
135 |
|
/** symbols to builtin kinds*/ |
136 |
|
std::map<Node, Kind> d_symbolToBuiltinKind; |
137 |
|
/** arrow type constructor */ |
138 |
|
TypeNode d_arrow; |
139 |
|
/** the type of LFSC sorts, which can appear in terms */ |
140 |
|
TypeNode d_sortType; |
141 |
|
/** Used for getting unique index for variable */ |
142 |
|
std::map<Node, size_t> d_varIndex; |
143 |
|
/** Cache for typeAsNode */ |
144 |
|
std::map<TypeNode, Node> d_typeAsNode; |
145 |
|
/** Used for interpreted builtin parametric sorts */ |
146 |
|
std::map<Kind, Node> d_typeKindToNodeCons; |
147 |
|
}; |
148 |
|
|
149 |
|
} // namespace proof |
150 |
|
} // namespace cvc5 |
151 |
|
|
152 |
|
#endif |