3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-06 14:13:23 +00:00

add get_lstring per #2286

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-05-22 10:16:15 +04:00
parent 112e13eeea
commit b2845d888e
11 changed files with 64 additions and 10 deletions

View file

@ -167,6 +167,12 @@ namespace api {
return const_cast<char *>(m_string_buffer.c_str()); return const_cast<char *>(m_string_buffer.c_str());
} }
char * context::mk_external_string(char const * str, unsigned n) {
m_string_buffer.clear();
m_string_buffer.append(str, n);
return const_cast<char *>(m_string_buffer.c_str());
}
char * context::mk_external_string(std::string && str) { char * context::mk_external_string(std::string && str) {
m_string_buffer = std::move(str); m_string_buffer = std::move(str);
return const_cast<char *>(m_string_buffer.c_str()); return const_cast<char *>(m_string_buffer.c_str());

View file

@ -181,6 +181,7 @@ namespace api {
// Store a copy of str in m_string_buffer, and return a reference to it. // Store a copy of str in m_string_buffer, and return a reference to it.
// This method is used to communicate local/internal strings with the "external world" // This method is used to communicate local/internal strings with the "external world"
char * mk_external_string(char const * str, unsigned n);
char * mk_external_string(char const * str); char * mk_external_string(char const * str);
char * mk_external_string(std::string && str); char * mk_external_string(std::string && str);

View file

@ -150,6 +150,25 @@ extern "C" {
Z3_CATCH_RETURN(""); Z3_CATCH_RETURN("");
} }
Z3_string Z3_API Z3_get_lstring(Z3_context c, Z3_ast s, unsigned* length) {
Z3_TRY;
LOG_Z3_get_lstring(c, s, length);
RESET_ERROR_CODE();
zstring str;
if (!length) {
SET_ERROR_CODE(Z3_INVALID_ARG, "length argument is null");
return "";
}
if (!mk_c(c)->sutil().str.is_string(to_expr(s), str)) {
SET_ERROR_CODE(Z3_INVALID_ARG, "expression is not a string literal");
return "";
}
std::string s = str.as_string();
*length = static_cast<unsigned>(s.size());
return mk_c(c)->mk_external_string(s.c_str(), s.size());
Z3_CATCH_RETURN("");
}
#define MK_SORTED(NAME, FN ) \ #define MK_SORTED(NAME, FN ) \
Z3_ast Z3_API NAME(Z3_context c, Z3_sort s) { \ Z3_ast Z3_API NAME(Z3_context c, Z3_sort s) { \
Z3_TRY; \ Z3_TRY; \

View file

@ -3375,7 +3375,7 @@ extern "C" {
/** /**
\brief Create a string constant out of the string that is passed in \brief Create a string constant out of the string that is passed in
It takes the length of the string as well to take into account It takes the length of the string as well to take into account
0 characters. 0 characters. The string is unescaped.
def_API('Z3_mk_lstring' ,AST ,(_in(CONTEXT), _in(UINT), _in(STRING))) def_API('Z3_mk_lstring' ,AST ,(_in(CONTEXT), _in(UINT), _in(STRING)))
*/ */
@ -3397,6 +3397,15 @@ extern "C" {
*/ */
Z3_string Z3_API Z3_get_string(Z3_context c, Z3_ast s); Z3_string Z3_API Z3_get_string(Z3_context c, Z3_ast s);
/**
\brief Retrieve the unescaped string constant stored in \c s.
\pre Z3_is_string(c, s)
def_API('Z3_get_lstring' ,STRING ,(_in(CONTEXT), _in(AST), _out(UINT)))
*/
Z3_string Z3_API Z3_get_lstring(Z3_context c, Z3_ast s, unsigned* length);
/** /**
\brief Create an empty sequence of the sequence sort \c seq. \brief Create an empty sequence of the sequence sort \c seq.

View file

@ -3453,9 +3453,9 @@ void scoped_mark::pop_scope(unsigned num_scopes) {
// show an expr_ref on stdout // show an expr_ref on stdout
void prexpr(expr_ref &e){ void prexpr(expr_ref &e){
std::cout << mk_pp(e.get(), e.get_manager()) << std::endl; std::cout << mk_pp(e.get(), e.get_manager()) << std::endl;
} }
void ast_manager::show_id_gen(){ void ast_manager::show_id_gen(){
std::cout << "id_gen: " << m_expr_id_gen.show_hash() << " " << m_decl_id_gen.show_hash() << "\n"; std::cout << "id_gen: " << m_expr_id_gen.show_hash() << " " << m_decl_id_gen.show_hash() << "\n";
} }

View file

@ -224,6 +224,17 @@ std::string zstring::encode() const {
return strm.str(); return strm.str();
} }
std::string zstring::as_string() const {
SASSERT(m_encoding == ascii);
std::ostringstream strm;
for (unsigned i = 0; i < m_buffer.size(); ++i) {
unsigned char ch = m_buffer[i];
strm << (char)(ch);
}
return strm.str();
}
bool zstring::suffixof(zstring const& other) const { bool zstring::suffixof(zstring const& other) const {
if (length() > other.length()) return false; if (length() > other.length()) return false;
bool suffix = true; bool suffix = true;

View file

@ -107,6 +107,7 @@ public:
unsigned num_bits() const { return (m_encoding==ascii)?8:16; } unsigned num_bits() const { return (m_encoding==ascii)?8:16; }
encoding get_encoding() const { return m_encoding; } encoding get_encoding() const { return m_encoding; }
std::string encode() const; std::string encode() const;
std::string as_string() const;
unsigned length() const { return m_buffer.size(); } unsigned length() const { return m_buffer.size(); }
unsigned operator[](unsigned i) const { return m_buffer[i]; } unsigned operator[](unsigned i) const { return m_buffer[i]; }
bool empty() const { return m_buffer.empty(); } bool empty() const { return m_buffer.empty(); }

View file

@ -258,6 +258,7 @@ void asserted_formulas::reduce() {
if (!invoke(m_max_bv_sharing_fn)) return; if (!invoke(m_max_bv_sharing_fn)) return;
if (!invoke(m_elim_bvs_from_quantifiers)) return; if (!invoke(m_elim_bvs_from_quantifiers)) return;
if (!invoke(m_reduce_asserted_formulas)) return; if (!invoke(m_reduce_asserted_formulas)) return;
// if (!invoke(m_propagate_values)) return;
IF_VERBOSE(10, verbose_stream() << "(smt.simplifier-done)\n";); IF_VERBOSE(10, verbose_stream() << "(smt.simplifier-done)\n";);
TRACE("after_reduce", display(tout);); TRACE("after_reduce", display(tout););
@ -431,11 +432,15 @@ void asserted_formulas::commit() {
} }
void asserted_formulas::commit(unsigned new_qhead) { void asserted_formulas::commit(unsigned new_qhead) {
TRACE("asserted_formulas", tout << "commit " << new_qhead << "\n";);
m_macro_manager.mark_forbidden(new_qhead - m_qhead, m_formulas.c_ptr() + m_qhead); m_macro_manager.mark_forbidden(new_qhead - m_qhead, m_formulas.c_ptr() + m_qhead);
m_expr2depth.reset(); m_expr2depth.reset();
bool new_sub = false;
for (unsigned i = m_qhead; i < new_qhead; ++i) { for (unsigned i = m_qhead; i < new_qhead; ++i) {
justified_expr const& j = m_formulas[i]; justified_expr const& j = m_formulas[i];
update_substitution(j.get_fml(), j.get_proof()); if (update_substitution(j.get_fml(), j.get_proof())) {
new_sub = true;
}
} }
m_qhead = new_qhead; m_qhead = new_qhead;
} }
@ -473,6 +478,7 @@ void asserted_formulas::propagate_values() {
} }
num_prop = prop; num_prop = prop;
} }
TRACE("asserted_formulas", tout << num_prop << "\n";);
if (num_prop > 0) if (num_prop > 0)
m_reduce_asserted_formulas(); m_reduce_asserted_formulas();
} }
@ -496,7 +502,7 @@ unsigned asserted_formulas::propagate_values(unsigned i) {
return n != new_n ? 1 : 0; return n != new_n ? 1 : 0;
} }
void asserted_formulas::update_substitution(expr* n, proof* pr) { bool asserted_formulas::update_substitution(expr* n, proof* pr) {
expr* lhs, *rhs, *n1; expr* lhs, *rhs, *n1;
proof_ref pr1(m); proof_ref pr1(m);
if (is_ground(n) && m.is_eq(n, lhs, rhs)) { if (is_ground(n) && m.is_eq(n, lhs, rhs)) {
@ -505,13 +511,13 @@ void asserted_formulas::update_substitution(expr* n, proof* pr) {
if (is_gt(lhs, rhs)) { if (is_gt(lhs, rhs)) {
TRACE("propagate_values", tout << "insert " << mk_pp(lhs, m) << " -> " << mk_pp(rhs, m) << "\n";); TRACE("propagate_values", tout << "insert " << mk_pp(lhs, m) << " -> " << mk_pp(rhs, m) << "\n";);
m_scoped_substitution.insert(lhs, rhs, pr); m_scoped_substitution.insert(lhs, rhs, pr);
return; return true;
} }
if (is_gt(rhs, lhs)) { if (is_gt(rhs, lhs)) {
TRACE("propagate_values", tout << "insert " << mk_pp(rhs, m) << " -> " << mk_pp(lhs, m) << "\n";); TRACE("propagate_values", tout << "insert " << mk_pp(rhs, m) << " -> " << mk_pp(lhs, m) << "\n";);
pr1 = m.proofs_enabled() ? m.mk_symmetry(pr) : nullptr; pr1 = m.proofs_enabled() ? m.mk_symmetry(pr) : nullptr;
m_scoped_substitution.insert(rhs, lhs, pr1); m_scoped_substitution.insert(rhs, lhs, pr1);
return; return true;
} }
TRACE("propagate_values", tout << "incompatible " << mk_pp(n, m) << "\n";); TRACE("propagate_values", tout << "incompatible " << mk_pp(n, m) << "\n";);
} }
@ -523,6 +529,7 @@ void asserted_formulas::update_substitution(expr* n, proof* pr) {
pr1 = m.proofs_enabled() ? m.mk_iff_true(pr) : nullptr; pr1 = m.proofs_enabled() ? m.mk_iff_true(pr) : nullptr;
m_scoped_substitution.insert(n, m.mk_true(), pr1); m_scoped_substitution.insert(n, m.mk_true(), pr1);
} }
return false;
} }

View file

@ -213,7 +213,7 @@ class asserted_formulas {
void set_eliminate_and(bool flag); void set_eliminate_and(bool flag);
void propagate_values(); void propagate_values();
unsigned propagate_values(unsigned i); unsigned propagate_values(unsigned i);
void update_substitution(expr* n, proof* p); bool update_substitution(expr* n, proof* p);
bool is_gt(expr* lhs, expr* rhs); bool is_gt(expr* lhs, expr* rhs);
void compute_depth(expr* e); void compute_depth(expr* e);
unsigned depth(expr* e) { return m_expr2depth[e]; } unsigned depth(expr* e) { return m_expr2depth[e]; }

View file

@ -766,7 +766,7 @@ namespace smt {
bits.swap(new_bits); \ bits.swap(new_bits); \
} \ } \
init_bits(e, bits); \ init_bits(e, bits); \
TRACE("bv", tout << arg_bits << " " << bits << " " << new_bits << "\n";); \ TRACE("bv_verbose", tout << arg_bits << " " << bits << " " << new_bits << "\n";); \
} }

View file

@ -187,7 +187,7 @@ lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, p
else if (is_decided_unsat(r)) { else if (is_decided_unsat(r)) {
goal * final = r[0]; goal * final = r[0];
SASSERT(m.is_false(final->form(0))); SASSERT(m.is_false(final->form(0)));
if (proofs_enabled) pr = final->pr(0); pr = final->pr(0);
if (cores_enabled) core = final->dep(0); if (cores_enabled) core = final->dep(0);
return l_false; return l_false;
} }