diff --git a/src/ast/seq_decl_plugin.cpp b/src/ast/seq_decl_plugin.cpp index f1158dd53..81783c85c 100644 --- a/src/ast/seq_decl_plugin.cpp +++ b/src/ast/seq_decl_plugin.cpp @@ -913,6 +913,11 @@ app* seq_decl_plugin::mk_string(zstring const& s) { } +bool seq_decl_plugin::is_considered_uninterpreted(func_decl * f) { + seq_util util(*m_manager); + return util.str.is_nth_u(f); +} + bool seq_decl_plugin::is_value(app* e) const { while (true) { if (is_app_of(e, m_family_id, OP_SEQ_EMPTY)) { diff --git a/src/ast/seq_decl_plugin.h b/src/ast/seq_decl_plugin.h index 874262624..1f68d85dd 100644 --- a/src/ast/seq_decl_plugin.h +++ b/src/ast/seq_decl_plugin.h @@ -207,6 +207,7 @@ public: bool has_re() const { return m_has_re; } + bool is_considered_uninterpreted(func_decl * f) override; }; class seq_util { diff --git a/src/model/model.cpp b/src/model/model.cpp index c05d9a1f3..1c678d88e 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -29,6 +29,12 @@ Revision History: #include "model/model.h" #include "model/model_params.hpp" #include "model/model_evaluator.h" +#include "model/array_factory.h" +#include "model/value_factory.h" +#include "model/seq_factory.h" +#include "model/datatype_factory.h" +#include "model/numeral_factory.h" + model::model(ast_manager & m): model_core(m), @@ -88,40 +94,38 @@ bool model::eval_expr(expr * e, expr_ref & result, bool model_completion) { } } -struct model::value_proc : public some_value_proc { - model & m_model; - value_proc(model & m):m_model(m) {} - expr * operator()(sort * s) override { - ptr_vector * u = nullptr; - if (m_model.m_usort2universe.find(s, u)) { - if (!u->empty()) - return u->get(0); - } - return nullptr; - } -}; +value_factory* model::get_factory(sort* s) { + if (m_factories.plugins().empty()) { + seq_util su(m); + m_factories.register_plugin(alloc(array_factory, m, *this)); + m_factories.register_plugin(alloc(datatype_factory, m, *this)); + m_factories.register_plugin(alloc(bv_factory, m)); + m_factories.register_plugin(alloc(arith_factory, m)); + m_factories.register_plugin(alloc(seq_factory, m, su.get_family_id(), *this)); + } + family_id fid = s->get_family_id(); + return m_factories.get_plugin(fid); +} expr * model::get_some_value(sort * s) { - value_proc p(*this); - return m.get_some_value(s, &p); + ptr_vector * u = nullptr; + if (m_usort2universe.find(s, u)) { + if (!u->empty()) + return u->get(0); + } + return m.get_some_value(s); } expr * model::get_fresh_value(sort * s) { - value_proc p(*this); - return m.get_some_value(s, &p); + return get_factory(s)->get_fresh_value(s); } bool model::get_some_values(sort * s, expr_ref& v1, expr_ref& v2) { - v1 = get_some_value(s); - v2 = get_some_value(s); - return true; + return get_factory(s)->get_some_values(s, v1, v2); } ptr_vector const & model::get_universe(sort * s) const { - ptr_vector * u = nullptr; - m_usort2universe.find(s, u); - SASSERT(u != nullptr); - return *u; + return *m_usort2universe[s]; } bool model::has_uninterpreted_sort(sort * s) const { diff --git a/src/model/model.h b/src/model/model.h index 13c4f14b3..efe486bbb 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -19,10 +19,13 @@ Revision History: #ifndef MODEL_H_ #define MODEL_H_ +#include "util/ref.h" +#include "util/vector.h" +#include "ast/ast_translation.h" +#include "util/plugin_manager.h" #include "model/model_core.h" #include "model/model_evaluator.h" -#include "util/ref.h" -#include "ast/ast_translation.h" +#include "model/value_factory.h" class model; typedef ref model_ref; @@ -37,7 +40,7 @@ protected: model_evaluator m_mev; bool m_cleaned; bool m_inline; - struct value_proc; + plugin_manager m_factories; struct deps_collector; struct occs_collector; @@ -52,6 +55,7 @@ protected: expr_ref cleanup_expr(top_sort& ts, expr* e, unsigned current_partition); void remove_decls(ptr_vector & decls, func_decl_set const & s); bool can_inline_def(top_sort& ts, func_decl* f); + value_factory* get_factory(sort* s); public: model(ast_manager & m); diff --git a/src/model/seq_factory.h b/src/model/seq_factory.h new file mode 100644 index 000000000..1ddae7d87 --- /dev/null +++ b/src/model/seq_factory.h @@ -0,0 +1,149 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + theory_seq_empty.h + +Abstract: + + + +Author: + + Nikolaj Bjorner (nbjorner) 2011-14-11 + +Revision History: + +--*/ +#ifndef SEQ_FACTORY_H_ +#define SEQ_FACTORY_H_ + +#include "ast/seq_decl_plugin.h" +#include "model/model_core.h" + +class seq_factory : public value_factory { + typedef hashtable symbol_set; + model_core& m_model; + ast_manager& m; + seq_util u; + symbol_set m_strings; + unsigned m_next; + std::string m_unique_delim; + obj_map m_unique_sequences; + expr_ref_vector m_trail; +public: + + seq_factory(ast_manager & m, family_id fid, model_core& md): + value_factory(m, fid), + m_model(md), + m(m), + u(m), + m_next(0), + m_unique_delim("!"), + m_trail(m) + { + m_strings.insert(symbol("")); + m_strings.insert(symbol("a")); + m_strings.insert(symbol("b")); + } + + void add_trail(expr* e) { + m_trail.push_back(e); + } + + void set_prefix(char const* p) { + m_unique_delim = p; + } + + // generic method for setting unique sequences + void set_prefix(expr* uniq) { + m_trail.push_back(uniq); + m_unique_sequences.insert(m.get_sort(uniq), uniq); + } + + expr* get_some_value(sort* s) override { + if (u.is_seq(s)) { + return u.str.mk_empty(s); + } + sort* seq = nullptr; + if (u.is_re(s, seq)) { + return u.re.mk_to_re(u.str.mk_empty(seq)); + } + UNREACHABLE(); + return nullptr; + } + bool get_some_values(sort* s, expr_ref& v1, expr_ref& v2) override { + if (u.is_string(s)) { + v1 = u.str.mk_string(symbol("a")); + v2 = u.str.mk_string(symbol("b")); + return true; + } + sort* ch; + if (u.is_seq(s, ch)) { + if (m_model.get_some_values(ch, v1, v2)) { + v1 = u.str.mk_unit(v1); + v2 = u.str.mk_unit(v2); + return true; + } + else { + return false; + } + } + NOT_IMPLEMENTED_YET(); + return false; + } + expr* get_fresh_value(sort* s) override { + if (u.is_string(s)) { + while (true) { + std::ostringstream strm; + strm << m_unique_delim << std::hex << m_next++ << std::dec << m_unique_delim; + symbol sym(strm.str().c_str()); + if (m_strings.contains(sym)) continue; + m_strings.insert(sym); + return u.str.mk_string(sym); + } + } + sort* seq = nullptr, *ch = nullptr; + if (u.is_re(s, seq)) { + expr* v0 = get_fresh_value(seq); + return u.re.mk_to_re(v0); + } + if (u.is_char(s)) { + //char s[2] = { ++m_char, 0 }; + //return u.str.mk_char(zstring(s), 0); + return u.str.mk_char(zstring("a"), 0); + } + if (u.is_seq(s, ch)) { + expr* v = m_model.get_fresh_value(ch); + if (!v) return nullptr; + return u.str.mk_unit(v); + } + UNREACHABLE(); + return nullptr; + } + void register_value(expr* n) override { + symbol sym; + if (u.str.is_string(n, sym)) { + m_strings.insert(sym); + if (sym.str().find(m_unique_delim) != std::string::npos) { + add_new_delim(); + } + } + } +private: + + void add_new_delim() { + bool found = true; + while (found) { + found = false; + m_unique_delim += "!"; + symbol_set::iterator it = m_strings.begin(), end = m_strings.end(); + for (; it != end && !found; ++it) { + found = it->str().find(m_unique_delim) != std::string::npos; + } + } + } +}; + +#endif diff --git a/src/smt/proto_model/proto_model.h b/src/smt/proto_model/proto_model.h index c73665715..587ddc510 100644 --- a/src/smt/proto_model/proto_model.h +++ b/src/smt/proto_model/proto_model.h @@ -31,7 +31,6 @@ Revision History: #include "model/model_core.h" #include "model/model_evaluator.h" #include "model/value_factory.h" -#include "util/plugin_manager.h" #include "ast/arith_decl_plugin.h" #include "ast/func_decl_dependencies.h" #include "model/model.h" diff --git a/src/smt/theory_seq_empty.h b/src/smt/theory_seq_empty.h index 81f1af06f..ac4a37750 100644 --- a/src/smt/theory_seq_empty.h +++ b/src/smt/theory_seq_empty.h @@ -21,131 +21,9 @@ Revision History: #include "smt/smt_theory.h" #include "ast/seq_decl_plugin.h" +#include "model/seq_factory.h" namespace smt { - class seq_factory : public value_factory { - typedef hashtable symbol_set; - proto_model& m_model; - ast_manager& m; - seq_util u; - symbol_set m_strings; - unsigned m_next; - std::string m_unique_delim; - obj_map m_unique_sequences; - expr_ref_vector m_trail; - public: - - seq_factory(ast_manager & m, family_id fid, proto_model& md): - value_factory(m, fid), - m_model(md), - m(m), - u(m), - m_next(0), - m_unique_delim("!"), - m_trail(m) - { - m_strings.insert(symbol("")); - m_strings.insert(symbol("a")); - m_strings.insert(symbol("b")); - } - - void add_trail(expr* e) { - m_trail.push_back(e); - } - - void set_prefix(char const* p) { - m_unique_delim = p; - } - - // generic method for setting unique sequences - void set_prefix(expr* uniq) { - m_trail.push_back(uniq); - m_unique_sequences.insert(m.get_sort(uniq), uniq); - } - - expr* get_some_value(sort* s) override { - if (u.is_seq(s)) { - return u.str.mk_empty(s); - } - sort* seq = nullptr; - if (u.is_re(s, seq)) { - return u.re.mk_to_re(u.str.mk_empty(seq)); - } - UNREACHABLE(); - return nullptr; - } - bool get_some_values(sort* s, expr_ref& v1, expr_ref& v2) override { - if (u.is_string(s)) { - v1 = u.str.mk_string(symbol("a")); - v2 = u.str.mk_string(symbol("b")); - return true; - } - sort* ch; - if (u.is_seq(s, ch)) { - if (m_model.get_some_values(ch, v1, v2)) { - v1 = u.str.mk_unit(v1); - v2 = u.str.mk_unit(v2); - return true; - } - else { - return false; - } - } - NOT_IMPLEMENTED_YET(); - return false; - } - expr* get_fresh_value(sort* s) override { - if (u.is_string(s)) { - while (true) { - std::ostringstream strm; - strm << m_unique_delim << std::hex << m_next++ << std::dec << m_unique_delim; - symbol sym(strm.str().c_str()); - if (m_strings.contains(sym)) continue; - m_strings.insert(sym); - return u.str.mk_string(sym); - } - } - sort* seq = nullptr, *ch = nullptr; - if (u.is_re(s, seq)) { - expr* v0 = get_fresh_value(seq); - return u.re.mk_to_re(v0); - } - if (u.is_char(s)) { - //char s[2] = { ++m_char, 0 }; - //return u.str.mk_char(zstring(s), 0); - return u.str.mk_char(zstring("a"), 0); - } - if (u.is_seq(s, ch)) { - expr* v = m_model.get_fresh_value(ch); - if (!v) return nullptr; - return u.str.mk_unit(v); - } - UNREACHABLE(); - return nullptr; - } - void register_value(expr* n) override { - symbol sym; - if (u.str.is_string(n, sym)) { - m_strings.insert(sym); - if (sym.str().find(m_unique_delim) != std::string::npos) { - add_new_delim(); - } - } - } - private: - - void add_new_delim() { - bool found = true; - while (found) { - found = false; - m_unique_delim += "!"; - symbol_set::iterator it = m_strings.begin(), end = m_strings.end(); - for (; it != end && !found; ++it) { - found = it->str().find(m_unique_delim) != std::string::npos; - } - } - } - }; class theory_seq_empty : public theory { bool m_used;