forked from VeriFIT/z3-noodler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.h
202 lines (179 loc) · 7.75 KB
/
util.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#ifndef _NOODLER_UTIL_H_
#define _NOODLER_UTIL_H_
#include <functional>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <memory>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "smt/params/smt_params.h"
#include "ast/arith_decl_plugin.h"
#include "ast/seq_decl_plugin.h"
#include "smt/params/theory_str_params.h"
#include "smt/smt_kernel.h"
#include "smt/smt_theory.h"
#include "smt/smt_arith_value.h"
#include "util/scoped_vector.h"
#include "util/union_find.h"
#include "ast/rewriter/seq_rewriter.h"
#include "ast/rewriter/th_rewriter.h"
#include "formula.h"
#include "aut_assignment.h"
// FIXME most if not all these functions should probably be in theory_str_noodler
namespace smt::noodler::util {
using expr_pair = std::pair<expr_ref, expr_ref>;
using expr_pair_flag = std::tuple<expr_ref, expr_ref, bool>;
/**
* Throws error and select which class to throw based on debug (if we are
* debugging, we do not want z3 to catch our error, if we are not debugging
* we want z3 to catch it and return unknown).
*
* @param errMsg Error message
*/
void throw_error(std::string errMsg);
/**
Get variables from a given expression @p ex. Append to the output parameter @p res.
@param ex Expression to be checked for variables.
@param m_util_s Seq util for AST
@param m AST manager
@param[out] res Vector of found variables (may contain duplicities).
@param pred_map predicate to variable mapping
*/
void get_str_variables(expr* ex, const seq_util& m_util_s, const ast_manager& m, obj_hashtable<expr>& res, obj_map<expr, expr*>* pred_map=nullptr);
/**
* Check whether an @p expression is a string variable.
*
* Function checks only the top-level expression and is not recursive.
* Regex variables do not count as string variables.
* @param expression Expression to check.
* @return True if @p expression is a variable, false otherwise.
*/
bool is_str_variable(const expr* expression, const seq_util& m_util_s);
/**
* Check whether an @p expression is any kind of variable (string, regex, integer).
*
* Function checks only the top-level expression and is not recursive.
* @param expression Expression to check.
* @return True if @p expression is a variable, false otherwise.
*/
bool is_variable(const expr* expression);
/**
* Get variable names from a given expression @p ex. Append to the output parameter @p res.
* @param[in] ex Expression to be checked for variables.
* @param[in] m_util_s Seq util for AST.
* @param[in] m AST manager.
* @param[out] res Vector of found variables (may contain duplicities).
*/
void get_variable_names(expr* ex, const seq_util& m_util_s, const ast_manager& m, std::unordered_set<std::string>& res);
/**
* Get dummy symbols.
*
* @param[in] new_symb_num Number of added symbols.
* @param[out] symbols_to_append_to Set of symbols where dummy symbols are appended to.
* @return Set of dummy symbols.
*/
std::set<uint32_t> get_dummy_symbols(size_t new_symb_num, std::set<uint32_t>& symbols_to_append_to);
/**
* Collect basic terms (vars, literals) from a concatenation @p ex. Append the basic terms to the output parameter
* @p terms.
* @param ex Expression to be checked for basic terms.
* @param m_util_s Seq util for AST
* @param pred_replace Replacement of predicate and functions
* @param[out] terms Vector of found BasicTerm (in right order).
*
* TODO: Test.
*/
void collect_terms(app* ex, ast_manager& m, const seq_util& m_util_s, obj_map<expr, expr*>& pred_replace,
std::map<BasicTerm, expr_ref>& var_name, std::vector<BasicTerm>& terms
);
/**
* Convert variable in @c expr form to @c BasicTerm.
* @param variable Variable to be converted to @c BasicTerm.
* @return Passed @p variable as a @c BasicTerm
*
* TODO: Test.
*/
BasicTerm get_variable_basic_term(expr* variable);
void get_len_exprs(app* ex, const seq_util& m_util_s, const ast_manager& m, obj_hashtable<app>& res);
/**
* @brief Create a fresh Z3 int variable with a given @p name followed by a unique suffix.
*
* @param name Infix of the name (rest is added to get a unique name)
* FIXME same function is in theory_str_noodler, decide which to keep
*/
static expr_ref mk_int_var_fresh(const std::string& name, ast_manager& m, arith_util& m_util_a) {
app* fresh_var = m.mk_fresh_const(name, m_util_a.mk_int(), false);
// TODO maybe we need to internalize and mark as relevant, so that arith solver can handle it (see mk_int_var in theory_str.h of z3str3)
return expr_ref(fresh_var, m);
}
/**
* @brief Create a fresh Z3 string variable with a given @p name followed by a unique suffix.
*
* @param name Infix of the name (rest is added to get a unique name)
* FIXME same function is in theory_str_noodler, decide which to keep
*/
static expr_ref mk_str_var_fresh(const std::string& name, ast_manager& m, seq_util& m_util_s) {
app* fresh_var = m.mk_fresh_const(name, m_util_s.mk_string_sort(), false);
return expr_ref(fresh_var, m);
}
/**
* @brief Get Z3 int var with exact given @p name
*
* @param name Name of the var
*/
static expr_ref mk_int_var(const std::string& name, ast_manager& m, arith_util& m_util_a) {
app* var = m.mk_const(name, m_util_a.mk_int());
// TODO maybe we need to internalize and mark as relevant, so that arith solver can handle it (see mk_int_var in theory_str.h of z3str3)
return expr_ref(var, m);
}
/**
* @brief Get Z3 string var with exact given @p name
*
* @param name Name of the var
*/
static expr_ref mk_str_var(const std::string& name, ast_manager& m, seq_util& m_util_s) {
app* var = m.mk_const(name, m_util_s.mk_string_sort());
return expr_ref(var, m);
}
/**
* @brief Create a fresh noodler (BasicTerm) variable with a given @p name followed by a unique suffix.
*
* The suffix contains a number which is incremented for each use of this function for a given @p name
*
* @param name Infix of the name (rest is added to get a unique name)
*/
inline BasicTerm mk_noodler_var_fresh(const std::string& name) {
// TODO kinda ugly, function is defined in header and have static variable
// so it needs to be inline, maybe we should define some variable handler class
static std::map<std::string,unsigned> next_id_of_name;
return BasicTerm{BasicTermType::Variable, name + std::string("!n") + std::to_string((next_id_of_name[name])++)};
}
/**
* @brief Check whether the expression @p val is of the form ( @p num_res ) + (len @p s ).
*
* @param val Expression to be checked
* @param s String term with length
* @param m ast manager
* @param m_util_s string ast util
* @param m_util_a arith ast util
* @param[out] num_res expression to be substracked from length term
* @return Is of the form.
*/
bool is_len_sub(expr* val, expr* s, ast_manager& m, seq_util& m_util_s, arith_util& m_util_a, expr*& num_res);
/**
* @brief Convert Length node to z3 length formula
*
* @param node Length node
* @param variable_map mapping of variables(BasicTerms) to the corresponding z3 variables(expr_ref)
* @param m ast manager
* @param m_util_s string ast util
* @param m_util_a arith ast util
* @return expr_ref
*/
expr_ref len_to_expr(const LenNode &node, const std::map<BasicTerm, expr_ref>& variable_map, ast_manager &m, seq_util& m_util_s, arith_util& m_util_a);
}
#endif