1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Paul Meng, Mathias Preiner |
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 |
|
* Pre-process step for performing sort inference. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__SORT_INFERENCE_H |
19 |
|
#define CVC5__SORT_INFERENCE_H |
20 |
|
|
21 |
|
#include <map> |
22 |
|
#include <vector> |
23 |
|
|
24 |
|
#include "expr/node.h" |
25 |
|
#include "expr/type_node.h" |
26 |
|
#include "smt/env_obj.h" |
27 |
|
|
28 |
|
namespace cvc5 { |
29 |
|
|
30 |
|
class Env; |
31 |
|
|
32 |
|
namespace theory { |
33 |
|
|
34 |
|
/** sort inference |
35 |
|
* |
36 |
|
* This class implements sort inference techniques, which rewrites a |
37 |
|
* formula F into an equisatisfiable formula F', where the symbols g in F are |
38 |
|
* replaced by others g', possibly of different types. For details, see e.g.: |
39 |
|
* "Sort it out with Monotonicity" Claessen 2011 |
40 |
|
* "Non-Cyclic Sorts for First-Order Satisfiability" Korovin 2013. |
41 |
|
*/ |
42 |
|
class SortInference : protected EnvObj |
43 |
|
{ |
44 |
|
private: |
45 |
|
//all subsorts |
46 |
|
std::vector< int > d_sub_sorts; |
47 |
|
std::map< int, bool > d_non_monotonic_sorts; |
48 |
|
std::map< TypeNode, std::vector< int > > d_type_sub_sorts; |
49 |
|
void recordSubsort( TypeNode tn, int s ); |
50 |
|
public: |
51 |
20 |
class UnionFind { |
52 |
|
public: |
53 |
20 |
UnionFind(){} |
54 |
|
UnionFind( UnionFind& c ){ |
55 |
|
set( c ); |
56 |
|
} |
57 |
|
std::map< int, int > d_eqc; |
58 |
|
//pairs that must be disequal |
59 |
|
std::vector< std::pair< int, int > > d_deq; |
60 |
|
void print(const char * c); |
61 |
20 |
void clear() { d_eqc.clear(); d_deq.clear(); } |
62 |
|
void set( UnionFind& c ); |
63 |
|
int getRepresentative( int t ); |
64 |
|
void setEqual( int t1, int t2 ); |
65 |
|
void setDisequal( int t1, int t2 ){ d_deq.push_back( std::pair< int, int >( t1, t2 ) ); } |
66 |
|
bool areEqual( int t1, int t2 ) { return getRepresentative( t1 )==getRepresentative( t2 ); } |
67 |
|
bool isValid(); |
68 |
|
}; |
69 |
|
|
70 |
|
private: |
71 |
|
/** the id count for all subsorts we have allocated */ |
72 |
|
int d_sortCount; |
73 |
|
UnionFind d_type_union_find; |
74 |
|
std::map< int, TypeNode > d_type_types; |
75 |
|
std::map< TypeNode, int > d_id_for_types; |
76 |
|
//for apply uf operators |
77 |
|
std::map< Node, int > d_op_return_types; |
78 |
|
std::map< Node, std::vector< int > > d_op_arg_types; |
79 |
|
std::map< Node, int > d_equality_types; |
80 |
|
//for bound variables |
81 |
|
std::map< Node, std::map< Node, int > > d_var_types; |
82 |
|
//get representative |
83 |
|
void setEqual( int t1, int t2 ); |
84 |
|
int getIdForType( TypeNode tn ); |
85 |
|
void printSort( const char* c, int t ); |
86 |
|
//process |
87 |
|
int process( Node n, std::map< Node, Node >& var_bound, std::map< Node, int >& visited ); |
88 |
|
// for monotonicity inference |
89 |
|
private: |
90 |
|
void processMonotonic( Node n, bool pol, bool hasPol, std::map< Node, Node >& var_bound, std::map< Node, std::map< int, bool > >& visited, bool typeMode = false ); |
91 |
|
|
92 |
|
//for rewriting |
93 |
|
private: |
94 |
|
//mapping from old symbols to new symbols |
95 |
|
std::map< Node, Node > d_symbol_map; |
96 |
|
//mapping from constants to new symbols |
97 |
|
std::map< TypeNode, std::map< Node, Node > > d_const_map; |
98 |
|
//helper functions for simplify |
99 |
|
TypeNode getOrCreateTypeForId( int t, TypeNode pref ); |
100 |
|
TypeNode getTypeForId( int t ); |
101 |
|
Node getNewSymbol( Node old, TypeNode tn ); |
102 |
|
//simplify |
103 |
|
Node simplifyNode(Node n, |
104 |
|
std::map<Node, Node>& var_bound, |
105 |
|
TypeNode tnn, |
106 |
|
std::map<Node, Node>& model_replace_f, |
107 |
|
std::map<Node, std::map<TypeNode, Node> >& visited); |
108 |
|
//make injection |
109 |
|
Node mkInjection( TypeNode tn1, TypeNode tn2 ); |
110 |
|
//reset |
111 |
|
void reset(); |
112 |
|
|
113 |
|
public: |
114 |
20 |
SortInference(Env& env) : EnvObj(env), d_sortCount(1) {} |
115 |
40 |
~SortInference(){} |
116 |
|
|
117 |
|
/** initialize |
118 |
|
* |
119 |
|
* This initializes this class. The input formula is indicated by assertions. |
120 |
|
*/ |
121 |
|
void initialize(const std::vector<Node>& assertions); |
122 |
|
/** simplify |
123 |
|
* |
124 |
|
* This returns the simplified form of formula n, based on the information |
125 |
|
* computed during initialization. The argument model_replace_f stores the |
126 |
|
* mapping between functions and their analog in the sort-inferred signature. |
127 |
|
* The argument visited is a cache of the internal results of simplifying |
128 |
|
* previous nodes with this class. |
129 |
|
* |
130 |
|
* Must call initialize() before this function. |
131 |
|
*/ |
132 |
|
Node simplify(Node n, |
133 |
|
std::map<Node, Node>& model_replace_f, |
134 |
|
std::map<Node, std::map<TypeNode, Node> >& visited); |
135 |
|
/** get new constraints |
136 |
|
* |
137 |
|
* This adds constraints to new_asserts that ensure the following. |
138 |
|
* Let F be the conjunction of assertions from the input. Let F' be the |
139 |
|
* conjunction of the simplified form of each conjunct in F. Let C be the |
140 |
|
* conjunction of formulas adding to new_asserts. Then, F and F' ^ C are |
141 |
|
* equisatisfiable. |
142 |
|
*/ |
143 |
|
void getNewAssertions(std::vector<Node>& new_asserts); |
144 |
|
/** compute monotonicity |
145 |
|
* |
146 |
|
* This computes whether sorts are monotonic (see e.g. Claessen 2011). If |
147 |
|
* this function is called, then calls to isMonotonic() can subsequently be |
148 |
|
* used to query whether sorts are monotonic. |
149 |
|
*/ |
150 |
|
void computeMonotonicity(const std::vector<Node>& assertions); |
151 |
|
/** return true if tn was inferred to be monotonic */ |
152 |
|
bool isMonotonic(TypeNode tn); |
153 |
|
//get sort id for term n |
154 |
|
int getSortId( Node n ); |
155 |
|
//get sort id for variable of quantified formula f |
156 |
|
int getSortId( Node f, Node v ); |
157 |
|
//set that sk is the skolem variable of v for quantifier f |
158 |
|
void setSkolemVar( Node f, Node v, Node sk ); |
159 |
|
public: |
160 |
|
//is well sorted |
161 |
|
bool isWellSortedFormula( Node n ); |
162 |
|
bool isWellSorted( Node n ); |
163 |
|
private: |
164 |
|
// store monotonicity for original sorts as well |
165 |
|
std::map<TypeNode, bool> d_non_monotonic_sorts_orig; |
166 |
|
/** |
167 |
|
* Returns true if k is the APPLY_UF kind and we are not using higher-order |
168 |
|
* techniques. This is called in places where we want to know whether to |
169 |
|
* treat a term as uninterpreted function. |
170 |
|
*/ |
171 |
|
bool isHandledApplyUf(Kind k) const; |
172 |
|
}; |
173 |
|
|
174 |
|
} // namespace theory |
175 |
|
} // namespace cvc5 |
176 |
|
|
177 |
|
#endif |