mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-03 21:09:11 +00:00 
			
		
		
		
	implementing model updates
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									92b5301b7f
								
							
						
					
					
						commit
						3de8c193ea
					
				
					 63 changed files with 482 additions and 294 deletions
				
			
		| 
						 | 
				
			
			@ -62,6 +62,10 @@ public:
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void display(std::ostream & out) {
 | 
			
		||||
        out << "(ackr-model-converter)\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    ast_manager &             m;
 | 
			
		||||
    const ackr_info_ref       info;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +148,7 @@ void ackr_model_converter::add_entry(model_evaluator & evaluator,
 | 
			
		|||
    else {
 | 
			
		||||
        TRACE("ackr_model", tout << "entry already present\n";);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,11 @@ public:
 | 
			
		|||
    virtual model_converter * translate(ast_translation & translator) {
 | 
			
		||||
        NOT_IMPLEMENTED_YET();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void display(std::ostream & out) {
 | 
			
		||||
        out << "(lackr-model-converter)\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    ast_manager&                       m;
 | 
			
		||||
    const lackr_model_constructor_ref  model_constructor;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6279,21 +6279,6 @@ class Solver(Z3PPObject):
 | 
			
		|||
        consequences = [ consequences[i] for i in range(sz) ]
 | 
			
		||||
        return CheckSatResult(r), consequences
 | 
			
		||||
    
 | 
			
		||||
    def lemmas(self):
 | 
			
		||||
        """Extract auxiliary lemmas produced by solver"""
 | 
			
		||||
        return AstVector(Z3_solver_get_lemmas(self.ctx.ref(), self.solver), self.ctx)
 | 
			
		||||
        
 | 
			
		||||
    def lookahead(self, candidates = None):
 | 
			
		||||
        """Get lookahead literal"""
 | 
			
		||||
        if candidates is None:
 | 
			
		||||
            candidates = AstVector(None, self.ctx)
 | 
			
		||||
        elif not isinstance(candidates, AstVector):
 | 
			
		||||
            _cs = AstVector(None, self.ctx)
 | 
			
		||||
            for c in candidates:
 | 
			
		||||
                _asms.push(c)
 | 
			
		||||
            candidates = _cs
 | 
			
		||||
        return _to_expr_ref(Z3_solver_lookahead(self.ctx.ref(), self.solver, candidates), self.ctx)        
 | 
			
		||||
 | 
			
		||||
    def cube(self):
 | 
			
		||||
        """Get set of cubes"""
 | 
			
		||||
        rounds = 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1356,6 +1356,10 @@ ast_manager::ast_manager(ast_manager const & src, bool disable_proofs):
 | 
			
		|||
    copy_families_plugins(src);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ast_manager::update_fresh_id(ast_manager const& m) {
 | 
			
		||||
    m_fresh_id = std::max(m_fresh_id, m.m_fresh_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ast_manager::init() {
 | 
			
		||||
    m_int_real_coercions = true;
 | 
			
		||||
    m_debug_ref_count = false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1435,6 +1435,8 @@ public:
 | 
			
		|||
 | 
			
		||||
    void show_id_gen();
 | 
			
		||||
 | 
			
		||||
    void update_fresh_id(ast_manager const& other);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    reslimit                  m_limit;
 | 
			
		||||
    small_object_allocator    m_alloc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,6 @@ void ast_pp_util::collect(expr_ref_vector const& es) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void ast_pp_util::display_decls(std::ostream& out) {
 | 
			
		||||
    smt2_pp_environment_dbg env(m);
 | 
			
		||||
    ast_smt_pp pp(m);
 | 
			
		||||
    unsigned n = coll.get_num_sorts();
 | 
			
		||||
    for (unsigned i = 0; i < n; ++i) {
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +45,7 @@ void ast_pp_util::display_decls(std::ostream& out) {
 | 
			
		|||
    for (unsigned i = 0; i < n; ++i) {
 | 
			
		||||
        func_decl* f = coll.get_func_decls()[i];
 | 
			
		||||
        if (f->get_family_id() == null_family_id) {
 | 
			
		||||
            ast_smt2_pp(out, f, env);
 | 
			
		||||
            ast_smt2_pp(out, f, m_env);
 | 
			
		||||
            out << "\n";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -54,10 +53,9 @@ void ast_pp_util::display_decls(std::ostream& out) {
 | 
			
		|||
 | 
			
		||||
void ast_pp_util::display_asserts(std::ostream& out, expr_ref_vector const& fmls, bool neat) {
 | 
			
		||||
    if (neat) {
 | 
			
		||||
        smt2_pp_environment_dbg env(m);
 | 
			
		||||
        for (expr* f : fmls) {
 | 
			
		||||
            out << "(assert ";
 | 
			
		||||
            ast_smt2_pp(out, f, env);
 | 
			
		||||
            ast_smt2_pp(out, f, m_env);
 | 
			
		||||
            out << ")\n";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,14 +20,16 @@ Revision History:
 | 
			
		|||
#define AST_PP_UTIL_H_
 | 
			
		||||
 | 
			
		||||
#include "ast/decl_collector.h"
 | 
			
		||||
#include "ast/ast_smt2_pp.h"
 | 
			
		||||
 | 
			
		||||
class ast_pp_util {
 | 
			
		||||
    ast_manager&        m;
 | 
			
		||||
    smt2_pp_environment_dbg m_env;
 | 
			
		||||
 public:        
 | 
			
		||||
 | 
			
		||||
    decl_collector      coll;
 | 
			
		||||
 | 
			
		||||
    ast_pp_util(ast_manager& m): m(m), coll(m, false) {}
 | 
			
		||||
    ast_pp_util(ast_manager& m): m(m), m_env(m), coll(m, false) {}
 | 
			
		||||
 | 
			
		||||
    void collect(expr* e);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +40,8 @@ class ast_pp_util {
 | 
			
		|||
    void display_decls(std::ostream& out);
 | 
			
		||||
 | 
			
		||||
    void display_asserts(std::ostream& out, expr_ref_vector const& fmls, bool neat = true);
 | 
			
		||||
 | 
			
		||||
    smt2_pp_environment& env() { return m_env; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* AST_PP_UTIL_H_ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ public:
 | 
			
		|||
        out << f->get_name();
 | 
			
		||||
    }
 | 
			
		||||
    virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), params_ref(), r); }
 | 
			
		||||
    virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), params_ref(), r); }
 | 
			
		||||
    virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), params_ref(), r, "declare-fun"); }
 | 
			
		||||
    virtual void pp(expr * n, format_ns::format_ref & r) const { 
 | 
			
		||||
        sbuffer<symbol> buf;
 | 
			
		||||
        mk_smt2_format(n, env(), params_ref(), 0, 0, r, buf); 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -876,8 +876,21 @@ class smt2_printer {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void register_var_names(unsigned n) {
 | 
			
		||||
        unsigned idx = 1;
 | 
			
		||||
        for (unsigned i = 0; i < n; i++) {
 | 
			
		||||
            symbol name = next_name("x", idx);            
 | 
			
		||||
            SASSERT(!m_var_names_set.contains(name));
 | 
			
		||||
            m_var_names.push_back(name);
 | 
			
		||||
            m_var_names_set.insert(name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unregister_var_names(quantifier * q) {
 | 
			
		||||
        unsigned num_decls = q->get_num_decls();
 | 
			
		||||
        unregister_var_names(q->get_num_decls());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unregister_var_names(unsigned num_decls) {
 | 
			
		||||
        for (unsigned i = 0; i < num_decls; i++) {
 | 
			
		||||
            symbol s = m_var_names.back();
 | 
			
		||||
            m_var_names.pop_back();
 | 
			
		||||
| 
						 | 
				
			
			@ -885,25 +898,28 @@ class smt2_printer {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    format * pp_var_decls(quantifier * q) {
 | 
			
		||||
    format * pp_var_args(unsigned num_decls, sort* const* srts) {
 | 
			
		||||
        ptr_buffer<format> buf;
 | 
			
		||||
        unsigned num_decls = q->get_num_decls();
 | 
			
		||||
        SASSERT(num_decls <= m_var_names.size());
 | 
			
		||||
        symbol * it = m_var_names.end() - num_decls;
 | 
			
		||||
        for (unsigned i = 0; i < num_decls; i++, it++) {
 | 
			
		||||
            format * fs[1] = { m_env.pp_sort(q->get_decl_sort(i)) };
 | 
			
		||||
            format * fs[1] = { m_env.pp_sort(srts[i]) };
 | 
			
		||||
            std::string var_name;
 | 
			
		||||
            if (is_smt2_quoted_symbol (*it)) {
 | 
			
		||||
                var_name = mk_smt2_quoted_symbol (*it);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
              var_name = it->str ();\
 | 
			
		||||
                var_name = it->str ();          
 | 
			
		||||
            }
 | 
			
		||||
            buf.push_back(mk_seq1<format**,f2f>(m(), fs, fs+1, f2f(), var_name.c_str ()));
 | 
			
		||||
        }
 | 
			
		||||
        return mk_seq5(m(), buf.begin(), buf.end(), f2f());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    format * pp_var_decls(quantifier * q) {
 | 
			
		||||
        return pp_var_args(q->get_num_decls(), q->get_decl_sorts());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void process_quantifier(quantifier * q, frame & fr) {
 | 
			
		||||
        if (fr.m_idx == 0) {
 | 
			
		||||
            begin_scope();
 | 
			
		||||
| 
						 | 
				
			
			@ -1098,7 +1114,7 @@ public:
 | 
			
		|||
        r = m_env.pp_sort(s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator()(func_decl * f, format_ref & r) {
 | 
			
		||||
    void operator()(func_decl * f, format_ref & r, char const* cmd) {
 | 
			
		||||
        unsigned arity = f->get_arity();
 | 
			
		||||
        unsigned len;
 | 
			
		||||
        format * fname = m_env.pp_fdecl_name(f, len);
 | 
			
		||||
| 
						 | 
				
			
			@ -1110,9 +1126,27 @@ public:
 | 
			
		|||
        }
 | 
			
		||||
        args[1] = mk_seq5<format**, f2f>(m(), buf.begin(), buf.end(), f2f());
 | 
			
		||||
        args[2] = m_env.pp_sort(f->get_range());
 | 
			
		||||
        r = mk_seq1<format**, f2f>(m(), args, args+3, f2f(), "declare-fun");
 | 
			
		||||
        r = mk_seq1<format**, f2f>(m(), args, args+3, f2f(), cmd); 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void operator()(func_decl * f, expr * e, format_ref & r, char const* cmd) {
 | 
			
		||||
        unsigned arity = f->get_arity();
 | 
			
		||||
        unsigned len;
 | 
			
		||||
        format * fname = m_env.pp_fdecl_name(f, len);
 | 
			
		||||
        register_var_names(f->get_arity());        
 | 
			
		||||
        format * args[4];
 | 
			
		||||
        args[0] = fname;
 | 
			
		||||
        args[1] = pp_var_args(f->get_arity(), f->get_domain());
 | 
			
		||||
        args[2] = m_env.pp_sort(f->get_range());
 | 
			
		||||
        process(e, r);
 | 
			
		||||
        args[3] = r;
 | 
			
		||||
        r = mk_seq1<format**, f2f>(m(), args, args+4, f2f(), cmd); 
 | 
			
		||||
        unregister_var_names(f->get_arity());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p,
 | 
			
		||||
| 
						 | 
				
			
			@ -1127,9 +1161,14 @@ void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, f
 | 
			
		|||
    pr(s, r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ref & r) {
 | 
			
		||||
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ref & r, char const* cmd) {
 | 
			
		||||
    smt2_printer pr(env, p);
 | 
			
		||||
    pr(f, r);
 | 
			
		||||
    pr(f, r, cmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mk_smt2_format(func_decl * f, expr * e, smt2_pp_environment & env, params_ref const & p, format_ref & r, char const* cmd) {
 | 
			
		||||
    smt2_printer pr(env, p);
 | 
			
		||||
    pr(f, e, r, cmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mk_smt2_format(unsigned sz, expr * const* es, smt2_pp_environment & env, params_ref const & p,
 | 
			
		||||
| 
						 | 
				
			
			@ -1170,17 +1209,29 @@ std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & e
 | 
			
		|||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent) {
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) {
 | 
			
		||||
    ast_manager & m = env.get_manager();
 | 
			
		||||
    format_ref r(fm(m));
 | 
			
		||||
    sbuffer<symbol> var_names;
 | 
			
		||||
    mk_smt2_format(f, env, p, r);
 | 
			
		||||
    mk_smt2_format(f, env, p, r, cmd);
 | 
			
		||||
    if (indent > 0)
 | 
			
		||||
        r = mk_indent(m, indent, r.get());
 | 
			
		||||
    pp(out, r.get(), m, p);
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) {
 | 
			
		||||
    ast_manager & m = env.get_manager();
 | 
			
		||||
    format_ref r(fm(m));
 | 
			
		||||
    sbuffer<symbol> var_names;
 | 
			
		||||
    mk_smt2_format(f, e, env, p, r, cmd);
 | 
			
		||||
    if (indent > 0)
 | 
			
		||||
        r = mk_indent(m, indent, r.get());
 | 
			
		||||
    pp(out, r.get(), m, p);
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, unsigned sz, expr * const* es, smt2_pp_environment & env, params_ref const & p, unsigned indent,
 | 
			
		||||
                            unsigned num_vars, char const * var_prefix) {
 | 
			
		||||
    ast_manager & m = env.get_manager();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,12 +97,13 @@ void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p,
 | 
			
		|||
                    unsigned num_vars, char const * var_prefix,
 | 
			
		||||
                    format_ns::format_ref & r, sbuffer<symbol> & var_names);
 | 
			
		||||
void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r);
 | 
			
		||||
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r);
 | 
			
		||||
void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r, char const* cmd);
 | 
			
		||||
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, 
 | 
			
		||||
                           unsigned num_vars = 0, char const * var_prefix = 0);
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0);
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0);
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "declare-fun");
 | 
			
		||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "define-fun");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Internal wrapper (for debugging purposes only)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,7 @@ public:
 | 
			
		|||
    ast_translation(ast_manager & from, ast_manager & to, bool copy_plugins = true) : m_from_manager(from), m_to_manager(to) {
 | 
			
		||||
        if (copy_plugins)
 | 
			
		||||
            m_to_manager.copy_families_plugins(m_from_manager);
 | 
			
		||||
        m_to_manager.update_fresh_id(m_from_manager);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~ast_translation();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,7 @@ Notes:
 | 
			
		|||
#include "model/model_v2_pp.h"
 | 
			
		||||
#include "model/model_params.hpp"
 | 
			
		||||
#include "tactic/tactic_exception.h"
 | 
			
		||||
#include "tactic/generic_model_converter.h"
 | 
			
		||||
#include "solver/smt_logics.h"
 | 
			
		||||
#include "cmd_context/basic_cmds.h"
 | 
			
		||||
#include "cmd_context/interpolant_cmds.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -864,6 +865,17 @@ void cmd_context::insert(symbol const & s, object_ref * r) {
 | 
			
		|||
    m_object_refs.insert(s, r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cmd_context::model_add(symbol const & s, unsigned arity, sort *const* domain, expr * t) {
 | 
			
		||||
    if (!m_mc0) m_mc0 = alloc(generic_model_converter, m());
 | 
			
		||||
    func_decl_ref fn(m().mk_func_decl(s, arity, domain, m().get_sort(t)), m());
 | 
			
		||||
    m_mc0->add(fn, t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cmd_context::model_del(func_decl* f) {
 | 
			
		||||
    if (!m_mc0) m_mc0 = alloc(generic_model_converter, m());
 | 
			
		||||
    m_mc0->hide(f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector<symbol> const& ids, expr* e) {
 | 
			
		||||
    expr_ref eq(m());
 | 
			
		||||
    app_ref lhs(m());
 | 
			
		||||
| 
						 | 
				
			
			@ -1573,6 +1585,7 @@ void cmd_context::display_dimacs() {
 | 
			
		|||
 | 
			
		||||
void cmd_context::display_model(model_ref& mdl) {
 | 
			
		||||
    if (mdl) {
 | 
			
		||||
        if (m_mc0) (*m_mc0)(mdl);
 | 
			
		||||
        model_params p;
 | 
			
		||||
        if (p.v1() || p.v2()) {
 | 
			
		||||
            std::ostringstream buffer;
 | 
			
		||||
| 
						 | 
				
			
			@ -1895,7 +1908,7 @@ void cmd_context::pp(expr * n, format_ns::format_ref & r) const {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void cmd_context::pp(func_decl * f, format_ns::format_ref & r) const {
 | 
			
		||||
    mk_smt2_format(f, get_pp_env(), params_ref(), r);
 | 
			
		||||
    mk_smt2_format(f, get_pp_env(), params_ref(), r, "declare-fun");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cmd_context::display(std::ostream & out, sort * s, unsigned indent) const {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,20 +23,21 @@ Notes:
 | 
			
		|||
 | 
			
		||||
#include<sstream>
 | 
			
		||||
#include<vector>
 | 
			
		||||
#include "ast/ast.h"
 | 
			
		||||
#include "ast/ast_printer.h"
 | 
			
		||||
#include "cmd_context/pdecl.h"
 | 
			
		||||
#include "util/dictionary.h"
 | 
			
		||||
#include "solver/solver.h"
 | 
			
		||||
#include "ast/datatype_decl_plugin.h"
 | 
			
		||||
#include "util/stopwatch.h"
 | 
			
		||||
#include "util/cmd_context_types.h"
 | 
			
		||||
#include "util/event_handler.h"
 | 
			
		||||
#include "util/sexpr.h"
 | 
			
		||||
#include "util/dictionary.h"
 | 
			
		||||
#include "util/scoped_ptr_vector.h"
 | 
			
		||||
#include "ast/ast.h"
 | 
			
		||||
#include "ast/ast_printer.h"
 | 
			
		||||
#include "ast/datatype_decl_plugin.h"
 | 
			
		||||
#include "tactic/generic_model_converter.h"
 | 
			
		||||
#include "solver/solver.h"
 | 
			
		||||
#include "solver/progress_callback.h"
 | 
			
		||||
#include "cmd_context/pdecl.h"
 | 
			
		||||
#include "cmd_context/tactic_manager.h"
 | 
			
		||||
#include "cmd_context/check_logic.h"
 | 
			
		||||
#include "solver/progress_callback.h"
 | 
			
		||||
#include "util/scoped_ptr_vector.h"
 | 
			
		||||
#include "cmd_context/context_params.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -303,6 +304,7 @@ protected:
 | 
			
		|||
    void erase_macro(symbol const& s);
 | 
			
		||||
    bool macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const;
 | 
			
		||||
 | 
			
		||||
    ref<generic_model_converter> m_mc0;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null);
 | 
			
		||||
| 
						 | 
				
			
			@ -381,6 +383,8 @@ public:
 | 
			
		|||
    void insert_user_tactic(symbol const & s, sexpr * d);
 | 
			
		||||
    void insert_aux_pdecl(pdecl * p);
 | 
			
		||||
    void insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector<symbol> const& ids, expr* e);
 | 
			
		||||
    void model_add(symbol const & s, unsigned arity, sort *const* domain, expr * t);
 | 
			
		||||
    void model_del(func_decl* f);
 | 
			
		||||
    func_decl * find_func_decl(symbol const & s) const;
 | 
			
		||||
    func_decl * find_func_decl(symbol const & s, unsigned num_indices, unsigned const * indices,
 | 
			
		||||
                               unsigned arity, sort * const * domain, sort * range) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -211,6 +211,7 @@ public:
 | 
			
		|||
        assert_exprs_from(ctx, *g);
 | 
			
		||||
        TRACE("check_sat_using", g->display(tout););
 | 
			
		||||
        model_ref           md;
 | 
			
		||||
        model_converter_ref mc;
 | 
			
		||||
        proof_ref           pr(m);
 | 
			
		||||
        expr_dependency_ref core(m);
 | 
			
		||||
        std::string reason_unknown;
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +227,7 @@ public:
 | 
			
		|||
                cmd_context::scoped_watch sw(ctx);
 | 
			
		||||
                lbool r = l_undef;
 | 
			
		||||
                try {
 | 
			
		||||
                    r = check_sat(t, g, md, result->labels, pr, core, reason_unknown);                    
 | 
			
		||||
                    r = check_sat(t, g, md, mc, result->labels, pr, core, reason_unknown);                    
 | 
			
		||||
                    ctx.display_sat_result(r);
 | 
			
		||||
                    result->set_status(r);
 | 
			
		||||
                    if (r == l_undef) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -384,6 +384,7 @@ namespace datalog {
 | 
			
		|||
            return alloc(skip_model_converter);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream & out) { }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    model_converter* mk_skip_model_converter() { return alloc(skip_model_converter); }
 | 
			
		||||
| 
						 | 
				
			
			@ -398,6 +399,7 @@ namespace datalog {
 | 
			
		|||
            return alloc(skip_proof_converter);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream & out) { out << "(skip-proof-converter)\n"; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    proof_converter* mk_skip_proof_converter() { return alloc(skip_proof_converter); }
 | 
			
		||||
| 
						 | 
				
			
			@ -508,10 +510,9 @@ namespace datalog {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    void collect_and_transform(const unsigned_vector & src, const unsigned_vector & translation, 
 | 
			
		||||
            unsigned_vector & res) {
 | 
			
		||||
        unsigned n = src.size();
 | 
			
		||||
        for(unsigned i=0; i<n; i++) {
 | 
			
		||||
            unsigned translated = translation[src[i]];
 | 
			
		||||
                               unsigned_vector & res) {
 | 
			
		||||
        for (unsigned s : src) {
 | 
			
		||||
            unsigned translated = translation[s];
 | 
			
		||||
            if(translated!=UINT_MAX) {
 | 
			
		||||
                res.push_back(translated);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -520,10 +521,8 @@ namespace datalog {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    void transform_set(const unsigned_vector & map, const idx_set & src, idx_set & result) {
 | 
			
		||||
        idx_set::iterator it = src.begin();
 | 
			
		||||
        idx_set::iterator end = src.end();
 | 
			
		||||
        for(; it!=end; ++it) {
 | 
			
		||||
            result.insert(map[*it]);
 | 
			
		||||
        for (unsigned s : src) {
 | 
			
		||||
            result.insert(map[s]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ public:
 | 
			
		|||
    virtual void collect_statistics(statistics &st) const ;
 | 
			
		||||
    virtual void reset_statistics();
 | 
			
		||||
    virtual void get_unsat_core(ptr_vector<expr> &r);
 | 
			
		||||
    virtual void get_model(model_ref &m) {m_solver.get_model(m);}
 | 
			
		||||
    virtual void get_model_core(model_ref &m) {m_solver.get_model(m);}
 | 
			
		||||
    virtual proof *get_proof() {return m_solver.get_proof();}
 | 
			
		||||
    virtual std::string reason_unknown() const
 | 
			
		||||
    {return m_solver.reason_unknown();}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ public:
 | 
			
		|||
    virtual void get_unsat_core(ptr_vector<expr> &r);
 | 
			
		||||
    virtual void assert_expr(expr *e);
 | 
			
		||||
    virtual void collect_statistics(statistics &st) const {}
 | 
			
		||||
    virtual void get_model(model_ref &m) {m_context.get_model(m);}
 | 
			
		||||
    virtual void get_model_core(model_ref &m) {m_context.get_model(m);}
 | 
			
		||||
    virtual proof* get_proof();
 | 
			
		||||
    virtual std::string reason_unknown() const
 | 
			
		||||
    {return m_context.last_failure_as_string();}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,8 @@ namespace datalog {
 | 
			
		|||
            return alloc(bit_blast_model_converter, m);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream& out) { out << "(bit-blast-model-converter)\n"; }
 | 
			
		||||
 | 
			
		||||
        virtual void operator()(model_ref & model) {
 | 
			
		||||
            for (unsigned i = 0; i < m_new_funcs.size(); ++i) {
 | 
			
		||||
                func_decl* p = m_new_funcs[i].get();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,6 +150,8 @@ namespace datalog {
 | 
			
		|||
            return mc;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream& out) { out << "(add-invariant-model-converter)\n"; }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        void mk_body(matrix const& M, expr_ref& body) {
 | 
			
		||||
            expr_ref_vector conj(m);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,6 +53,8 @@ namespace datalog {
 | 
			
		|||
            return alloc(qa_model_converter, m);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream& out) { display_add(out, m); }
 | 
			
		||||
 | 
			
		||||
        void insert(func_decl* old_p, func_decl* new_p, expr_ref_vector& sub, sort_ref_vector& sorts, svector<bool> const& bound) {
 | 
			
		||||
            m_old_funcs.push_back(old_p);
 | 
			
		||||
            m_new_funcs.push_back(new_p);
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +83,11 @@ namespace datalog {
 | 
			
		|||
                    SASSERT(body);                    
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    body = m.mk_false();  
 | 
			
		||||
                    expr_ref_vector args(m);
 | 
			
		||||
                    for (unsigned i = 0; i < p->get_arity(); ++i) {
 | 
			
		||||
                        args.push_back(m.mk_var(i, p->get_domain(i)));
 | 
			
		||||
                    }
 | 
			
		||||
                    body = m.mk_app(p, args.size(), args.c_ptr());
 | 
			
		||||
                }
 | 
			
		||||
                // Create quantifier wrapper around body.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,6 +99,9 @@ namespace datalog {
 | 
			
		|||
            UNREACHABLE();
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream& out) { out << "(scale-model-converter)\n"; }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -283,6 +283,8 @@ namespace datalog {
 | 
			
		|||
            // this would require implementing translation for the dl_context.
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream& out) { out << "(slice-proof-converter)\n"; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class mk_slice::slice_model_converter : public model_converter {
 | 
			
		||||
| 
						 | 
				
			
			@ -396,6 +398,8 @@ namespace datalog {
 | 
			
		|||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream& out) { out << "(slice-model-converter)\n"; }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
   
 | 
			
		||||
    mk_slice::mk_slice(context & ctx):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -331,7 +331,7 @@ namespace opt {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void context::get_model(model_ref& mdl) {
 | 
			
		||||
    void context::get_model_core(model_ref& mdl) {
 | 
			
		||||
        mdl = m_model;
 | 
			
		||||
        fix_model(mdl);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -184,7 +184,7 @@ namespace opt {
 | 
			
		|||
        virtual void set_hard_constraints(ptr_vector<expr> & hard);
 | 
			
		||||
        virtual lbool optimize();
 | 
			
		||||
        virtual void set_model(model_ref& _m) { m_model = _m; }
 | 
			
		||||
        virtual void get_model(model_ref& _m);
 | 
			
		||||
        virtual void get_model_core(model_ref& _m);
 | 
			
		||||
        virtual void get_box_model(model_ref& _m, unsigned index);
 | 
			
		||||
        virtual void fix_model(model_ref& _m);
 | 
			
		||||
        virtual void collect_statistics(statistics& stats) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -296,7 +296,7 @@ namespace opt {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void opt_solver::get_model(model_ref & m) {
 | 
			
		||||
    void opt_solver::get_model_core(model_ref & m) {
 | 
			
		||||
        m_context.get_model(m);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,7 +97,7 @@ namespace opt {
 | 
			
		|||
        virtual void pop_core(unsigned n);
 | 
			
		||||
        virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions);        
 | 
			
		||||
        virtual void get_unsat_core(ptr_vector<expr> & r);
 | 
			
		||||
        virtual void get_model(model_ref & _m);        
 | 
			
		||||
        virtual void get_model_core(model_ref & _m);        
 | 
			
		||||
        virtual proof * get_proof();
 | 
			
		||||
        virtual std::string reason_unknown() const;
 | 
			
		||||
        virtual void set_reason_unknown(char const* msg);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,6 +96,8 @@ namespace smt2 {
 | 
			
		|||
        symbol               m_check_sat;
 | 
			
		||||
        symbol               m_define_fun;
 | 
			
		||||
        symbol               m_define_const;
 | 
			
		||||
        symbol               m_model_add;
 | 
			
		||||
        symbol               m_model_del;
 | 
			
		||||
        symbol               m_declare_fun;
 | 
			
		||||
        symbol               m_declare_const;
 | 
			
		||||
        symbol               m_define_sort;
 | 
			
		||||
| 
						 | 
				
			
			@ -2179,9 +2181,9 @@ namespace smt2 {
 | 
			
		|||
            next();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void parse_define_fun() {
 | 
			
		||||
        void parse_define(bool is_fun) {
 | 
			
		||||
            SASSERT(curr_is_identifier());
 | 
			
		||||
            SASSERT(curr_id() == m_define_fun);
 | 
			
		||||
            SASSERT(curr_id() == (is_fun ? m_define_fun : m_model_add));
 | 
			
		||||
            SASSERT(m_num_bindings == 0);
 | 
			
		||||
            next();
 | 
			
		||||
            check_identifier("invalid function/constant definition, symbol expected");
 | 
			
		||||
| 
						 | 
				
			
			@ -2195,7 +2197,10 @@ namespace smt2 {
 | 
			
		|||
            parse_expr();
 | 
			
		||||
            if (m().get_sort(expr_stack().back()) != sort_stack().back())
 | 
			
		||||
                throw parser_exception("invalid function/constant definition, sort mismatch");
 | 
			
		||||
            m_ctx.insert(id, num_vars, sort_stack().c_ptr() + sort_spos, expr_stack().back());
 | 
			
		||||
            if (is_fun) 
 | 
			
		||||
                m_ctx.insert(id, num_vars, sort_stack().c_ptr() + sort_spos, expr_stack().back());
 | 
			
		||||
            else 
 | 
			
		||||
                m_ctx.model_add(id, num_vars, sort_stack().c_ptr() + sort_spos, expr_stack().back());
 | 
			
		||||
            check_rparen("invalid function/constant definition, ')' expected");
 | 
			
		||||
            // restore stacks & env
 | 
			
		||||
            symbol_stack().shrink(sym_spos);
 | 
			
		||||
| 
						 | 
				
			
			@ -2208,6 +2213,22 @@ namespace smt2 {
 | 
			
		|||
            next();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void parse_define_fun() {
 | 
			
		||||
            parse_define(true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void parse_model_add() {
 | 
			
		||||
            parse_define(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void parse_model_del() {
 | 
			
		||||
            func_decl* f = parse_func_decl_ref();
 | 
			
		||||
            check_rparen("invalid model-del, ')' expected");
 | 
			
		||||
            m_ctx.model_del(f);
 | 
			
		||||
            m_ctx.print_success();
 | 
			
		||||
            next();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void parse_define_fun_rec() {
 | 
			
		||||
            // ( define-fun-rec hfun_defi )
 | 
			
		||||
            SASSERT(curr_is_identifier());
 | 
			
		||||
| 
						 | 
				
			
			@ -2910,6 +2931,14 @@ namespace smt2 {
 | 
			
		|||
                parse_define_funs_rec();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (s == m_model_add) {
 | 
			
		||||
                parse_model_add();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (s == m_model_del) {
 | 
			
		||||
                parse_model_del();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            parse_ext_cmd(line, pos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2941,6 +2970,8 @@ namespace smt2 {
 | 
			
		|||
            m_check_sat("check-sat"),
 | 
			
		||||
            m_define_fun("define-fun"),
 | 
			
		||||
            m_define_const("define-const"),
 | 
			
		||||
            m_model_add("model-add"),
 | 
			
		||||
            m_model_del("model-del"),
 | 
			
		||||
            m_declare_fun("declare-fun"),
 | 
			
		||||
            m_declare_const("declare-const"),
 | 
			
		||||
            m_define_sort("define-sort"),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -295,51 +295,6 @@ namespace sat {
 | 
			
		|||
        return out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void model_converter::validate_is_blocked(entry const& e, clause const& c) {
 | 
			
		||||
        if (c.is_blocked() || c.is_learned()) return;
 | 
			
		||||
        unsigned index = 0;
 | 
			
		||||
        literal lit = null_literal;
 | 
			
		||||
        bool_var v = e.var();
 | 
			
		||||
        for (literal l : c) {
 | 
			
		||||
            if (l.var() == v) {
 | 
			
		||||
                lit = l;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (lit == null_literal) return;
 | 
			
		||||
 | 
			
		||||
        bool sat = false;
 | 
			
		||||
        for (literal l : e.m_clauses) {
 | 
			
		||||
            if (l == null_literal) {
 | 
			
		||||
                if (!sat) {
 | 
			
		||||
                    display(std::cout << "clause is not blocked\n", e) << "\n";
 | 
			
		||||
                    std::cout << c << "\n";
 | 
			
		||||
                }
 | 
			
		||||
                sat = false;
 | 
			
		||||
                elim_stack* st = e.m_elim_stack[index];
 | 
			
		||||
                if (st) {
 | 
			
		||||
                    elim_stackv const& stack = st->stack();
 | 
			
		||||
                    unsigned sz = stack.size();
 | 
			
		||||
                    for (unsigned i = sz; i-- > 0; ) {
 | 
			
		||||
                        // verify ...
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                ++index;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (sat) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (l.var() == v) {
 | 
			
		||||
                sat = l == lit;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                sat = c.contains(~l);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void model_converter::copy(model_converter const & src) {
 | 
			
		||||
        reset();
 | 
			
		||||
        m_entries.append(src.m_entries);
 | 
			
		||||
| 
						 | 
				
			
			@ -362,4 +317,45 @@ namespace sat {
 | 
			
		|||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void model_converter::expand(vector<literal_vector>& update_stack) {
 | 
			
		||||
        literal_vector clause;
 | 
			
		||||
        for (entry const& e : m_entries) {
 | 
			
		||||
            clause.reset();
 | 
			
		||||
            unsigned index = 0;
 | 
			
		||||
            bool var_sign = false;
 | 
			
		||||
            for (literal l : e.m_clauses) {
 | 
			
		||||
                if (l == null_literal) {
 | 
			
		||||
                    elim_stack* st = e.m_elim_stack[index];                    
 | 
			
		||||
                    if (st) {
 | 
			
		||||
                        // clause sizes increase
 | 
			
		||||
                        elim_stackv const& stack = st->stack();
 | 
			
		||||
                        unsigned sz = stack.size();
 | 
			
		||||
                        for (unsigned i = 0; i < sz; ++i) {
 | 
			
		||||
                            unsigned csz = stack[i].first;
 | 
			
		||||
                            literal lit = stack[i].second;
 | 
			
		||||
                            BOOL found = false;
 | 
			
		||||
                            unsigned j = 0;
 | 
			
		||||
                            for (j = 0; j < csz; ++j) {
 | 
			
		||||
                                if (clause[j] == lit) {
 | 
			
		||||
                                    std::swap(clause[j], clause[0]);
 | 
			
		||||
                                    found = true;
 | 
			
		||||
                                    break;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            SASSERT(found);
 | 
			
		||||
                            update_stack.push_back(literal_vector(csz, clause.c_ptr()));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    update_stack.push_back(clause);
 | 
			
		||||
                    clause.reset();
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                clause.push_back(l);
 | 
			
		||||
                if (l.var() == e.var()) {
 | 
			
		||||
                    std::swap(clause[0], clause.back());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,8 +84,6 @@ namespace sat {
 | 
			
		|||
 | 
			
		||||
        std::ostream& display(std::ostream & out, entry const& entry) const;
 | 
			
		||||
 | 
			
		||||
        void validate_is_blocked(entry const& e, clause const& c);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        model_converter();
 | 
			
		||||
        ~model_converter();
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +107,15 @@ namespace sat {
 | 
			
		|||
        void copy(model_converter const & src);
 | 
			
		||||
        void collect_vars(bool_var_set & s) const;
 | 
			
		||||
        unsigned max_var(unsigned min) const;
 | 
			
		||||
        /*
 | 
			
		||||
         * \brief expand entries to a list of clauses, such that
 | 
			
		||||
         *  the first literal in each clause is the literal whose
 | 
			
		||||
         *  truth value is updated as follows:
 | 
			
		||||
         *  
 | 
			
		||||
         *     lit0 := lit0 or (~lit1 & ~lit2 & ... & ~lit_k)
 | 
			
		||||
         *  
 | 
			
		||||
         */
 | 
			
		||||
        void expand(vector<literal_vector>& update_stack);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1318,7 +1318,7 @@ namespace sat {
 | 
			
		|||
 | 
			
		||||
        void prepare_block_clause(clause& c, literal l, model_converter::entry*& new_entry, model_converter::kind k) {
 | 
			
		||||
            TRACE("blocked_clause", tout << "new blocked clause: " << c << "\n";);
 | 
			
		||||
            if (new_entry == 0)
 | 
			
		||||
            if (new_entry == 0 && !s.m_retain_blocked_clauses)
 | 
			
		||||
                new_entry = &(mc.mk(k, l.var()));
 | 
			
		||||
            m_to_remove.push_back(&c);
 | 
			
		||||
            for (literal lit : c) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1330,17 +1330,19 @@ namespace sat {
 | 
			
		|||
 | 
			
		||||
        void block_clause(clause& c, literal l, model_converter::entry *& new_entry) {
 | 
			
		||||
            prepare_block_clause(c, l, new_entry, model_converter::BLOCK_LIT);
 | 
			
		||||
            mc.insert(*new_entry, c);
 | 
			
		||||
            if (!s.m_retain_blocked_clauses) 
 | 
			
		||||
                mc.insert(*new_entry, c);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void block_covered_clause(clause& c, literal l, model_converter::kind k) {
 | 
			
		||||
            model_converter::entry * new_entry = 0;
 | 
			
		||||
            prepare_block_clause(c, l, new_entry, k);
 | 
			
		||||
            mc.insert(*new_entry, m_covered_clause, m_elim_stack);
 | 
			
		||||
            if (!s.m_retain_blocked_clauses) 
 | 
			
		||||
                mc.insert(*new_entry, m_covered_clause, m_elim_stack);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        void prepare_block_binary(watch_list::iterator it, literal l1, literal blocked, model_converter::entry*& new_entry, model_converter::kind k) {
 | 
			
		||||
            if (new_entry == 0) 
 | 
			
		||||
            if (new_entry == 0 && !s.m_retain_blocked_clauses) 
 | 
			
		||||
                new_entry = &(mc.mk(k, blocked.var()));
 | 
			
		||||
            literal l2 = it->get_literal();
 | 
			
		||||
            TRACE("blocked_clause", tout << "new blocked clause: " << l2 << " " << l1 << "\n";);
 | 
			
		||||
| 
						 | 
				
			
			@ -1356,13 +1358,15 @@ namespace sat {
 | 
			
		|||
        
 | 
			
		||||
        void block_binary(watch_list::iterator it, literal l, model_converter::entry *& new_entry) {
 | 
			
		||||
            prepare_block_binary(it, l, l, new_entry, model_converter::BLOCK_LIT);
 | 
			
		||||
            mc.insert(*new_entry, l, it->get_literal());
 | 
			
		||||
            if (!s.m_retain_blocked_clauses) 
 | 
			
		||||
                mc.insert(*new_entry, l, it->get_literal());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void block_covered_binary(watch_list::iterator it, literal l, literal blocked, model_converter::kind k) {
 | 
			
		||||
            model_converter::entry * new_entry = 0;
 | 
			
		||||
            prepare_block_binary(it, l, blocked, new_entry, k);
 | 
			
		||||
            mc.insert(*new_entry, m_covered_clause, m_elim_stack);
 | 
			
		||||
            if (!s.m_retain_blocked_clauses) 
 | 
			
		||||
                mc.insert(*new_entry, m_covered_clause, m_elim_stack);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void bca() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -114,6 +114,7 @@ public:
 | 
			
		|||
        if (m_mc0.get()) result->m_mc0 = m_mc0->translate(tr);
 | 
			
		||||
        result->m_internalized = m_internalized;
 | 
			
		||||
        result->m_internalized_converted = m_internalized_converted;
 | 
			
		||||
        if (mc0()) result->set_model_converter(mc0()->translate(tr));
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +300,7 @@ public:
 | 
			
		|||
        r.reset();
 | 
			
		||||
        r.append(m_core.size(), m_core.c_ptr());
 | 
			
		||||
    }
 | 
			
		||||
    virtual void get_model(model_ref & mdl) {
 | 
			
		||||
    virtual void get_model_core(model_ref & mdl) {
 | 
			
		||||
        if (!m_model.get()) {
 | 
			
		||||
            extract_model();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -442,6 +443,18 @@ public:
 | 
			
		|||
        return m_asmsf[idx];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual model_converter_ref get_model_converter() const {
 | 
			
		||||
        if (m_internalized && m_internalized_converted) {
 | 
			
		||||
            NOT_IMPLEMENTED_YET();
 | 
			
		||||
            model_converter_ref mc = concat(m_mc0.get(), mk_bit_blaster_model_converter(m, m_bb_rewriter->const2bits()));
 | 
			
		||||
            mc = concat(solver::get_model_converter().get(), mc.get());
 | 
			
		||||
            return mc;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            return solver::get_model_converter();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void convert_internalized() {
 | 
			
		||||
        if (!m_internalized) return;
 | 
			
		||||
        sat2goal s2g;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -968,21 +968,31 @@ struct sat2goal::imp {
 | 
			
		|||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        void display(std::ostream & out) {
 | 
			
		||||
            out << "(sat-model-converter\n";
 | 
			
		||||
            m_mc.display(out);
 | 
			
		||||
            sat::bool_var_set vars;
 | 
			
		||||
            m_mc.collect_vars(vars);
 | 
			
		||||
            out << "(atoms";
 | 
			
		||||
            unsigned sz = m_var2expr.size();
 | 
			
		||||
            for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
                if (vars.contains(i)) {
 | 
			
		||||
                    out << "\n (" << i << "\n  " << mk_ismt2_pp(m_var2expr.get(i), m(), 2) << ")";
 | 
			
		||||
                }
 | 
			
		||||
        expr_ref lit2expr(sat::literal l) {
 | 
			
		||||
            expr_ref result(m_var2expr.get(l.var()), m());
 | 
			
		||||
            if (l.sign()) {
 | 
			
		||||
                result = m().mk_not(result);
 | 
			
		||||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void display(std::ostream & out) {
 | 
			
		||||
            vector<sat::literal_vector> updates;
 | 
			
		||||
            m_mc.expand(updates);
 | 
			
		||||
            for (sat::literal_vector const& clause : updates) {
 | 
			
		||||
                expr_ref_vector tail(m());
 | 
			
		||||
                sat::literal lit0 = clause[0];
 | 
			
		||||
                for (unsigned i = 1; i < clause.size(); ++i) {
 | 
			
		||||
                    tail.push_back(lit2expr(~clause[i]));
 | 
			
		||||
                }
 | 
			
		||||
                expr_ref def(m().mk_or(lit2expr(lit0), mk_and(tail)), m());
 | 
			
		||||
                if (lit0.sign()) {
 | 
			
		||||
                    lit0.neg();
 | 
			
		||||
                    def = m().mk_not(def);
 | 
			
		||||
                }
 | 
			
		||||
                display_add(out, m(), to_app(lit2expr(lit0))->get_decl(), def);
 | 
			
		||||
            }
 | 
			
		||||
            out << ")\n";
 | 
			
		||||
            m_fmc->display(out);
 | 
			
		||||
            out << ")\n";
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,6 +70,8 @@ namespace smt {
 | 
			
		|||
                result->m_name2assertion.insert(translator(kv.m_key),
 | 
			
		||||
                                                translator(kv.m_value));
 | 
			
		||||
 | 
			
		||||
            if (mc0()) 
 | 
			
		||||
                result->set_model_converter(mc0()->translate(translator));
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -186,7 +188,7 @@ namespace smt {
 | 
			
		|||
                add_nonlocal_pattern_literals_to_core(r);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void get_model(model_ref & m) {
 | 
			
		||||
        virtual void get_model_core(model_ref & m) {
 | 
			
		||||
            m_context.get_model(m);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ void simple_check_sat_result::get_unsat_core(ptr_vector<expr> & r) {
 | 
			
		|||
        r.append(m_core.size(), m_core.c_ptr()); 
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
void simple_check_sat_result::get_model(model_ref & m) { 
 | 
			
		||||
void simple_check_sat_result::get_model_core(model_ref & m) { 
 | 
			
		||||
    if (m_status != l_false) 
 | 
			
		||||
        m = m_model; 
 | 
			
		||||
    else 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ Notes:
 | 
			
		|||
#include "util/lbool.h"
 | 
			
		||||
#include "util/statistics.h"
 | 
			
		||||
#include "util/event_handler.h"
 | 
			
		||||
#include "tactic/model_converter.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   \brief Abstract interface for the result of a (check-sat) like command.
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +41,7 @@ class check_sat_result {
 | 
			
		|||
protected:
 | 
			
		||||
    unsigned    m_ref_count;
 | 
			
		||||
    lbool       m_status; 
 | 
			
		||||
    model_converter_ref m_mc0;
 | 
			
		||||
public:
 | 
			
		||||
    check_sat_result():m_ref_count(0), m_status(l_undef) {}
 | 
			
		||||
    virtual ~check_sat_result() {}
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +56,13 @@ public:
 | 
			
		|||
        get_unsat_core(core);
 | 
			
		||||
        r.append(core.size(), core.c_ptr());
 | 
			
		||||
    }
 | 
			
		||||
    virtual void get_model(model_ref & m) = 0;
 | 
			
		||||
    void set_model_converter(model_converter* mc) { m_mc0 = mc; }
 | 
			
		||||
    model_converter* mc0() { return m_mc0.get(); }
 | 
			
		||||
    virtual void get_model_core(model_ref & m) = 0;
 | 
			
		||||
    void get_model(model_ref & m) {
 | 
			
		||||
        get_model_core(m);
 | 
			
		||||
        if (m && mc0()) (*mc0())(m);
 | 
			
		||||
    }
 | 
			
		||||
    virtual proof * get_proof() = 0;
 | 
			
		||||
    virtual std::string reason_unknown() const = 0;
 | 
			
		||||
    virtual void set_reason_unknown(char const* msg) = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +88,7 @@ struct simple_check_sat_result : public check_sat_result {
 | 
			
		|||
    virtual ast_manager& get_manager() const { return m_proof.get_manager(); }
 | 
			
		||||
    virtual void collect_statistics(statistics & st) const;
 | 
			
		||||
    virtual void get_unsat_core(ptr_vector<expr> & r);
 | 
			
		||||
    virtual void get_model(model_ref & m);
 | 
			
		||||
    virtual void get_model_core(model_ref & m);
 | 
			
		||||
    virtual proof * get_proof();
 | 
			
		||||
    virtual std::string reason_unknown() const;
 | 
			
		||||
    virtual void get_labels(svector<symbol> & r);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -307,7 +307,7 @@ public:
 | 
			
		|||
            m_solver2->get_unsat_core(r);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void get_model(model_ref & m) {
 | 
			
		||||
    virtual void get_model_core(model_ref & m) {
 | 
			
		||||
        if (m_use_solver1_results)
 | 
			
		||||
            m_solver1->get_model(m);
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ Notes:
 | 
			
		|||
#include "ast/ast_pp.h"
 | 
			
		||||
#include "ast/ast_pp_util.h"
 | 
			
		||||
#include "util/common_msgs.h"
 | 
			
		||||
#include "tactic/model_converter.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
unsigned solver::get_num_assertions() const {
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +42,11 @@ std::ostream& solver::display(std::ostream & out) const {
 | 
			
		|||
    visitor.collect(fmls);
 | 
			
		||||
    visitor.display_decls(out);
 | 
			
		||||
    visitor.display_asserts(out, fmls, true);
 | 
			
		||||
    model_converter_ref mc = get_model_converter();
 | 
			
		||||
    if (mc.get()) {
 | 
			
		||||
        mc->set_pp_env(&visitor.env());
 | 
			
		||||
        mc->display(out);
 | 
			
		||||
    }
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ Notes:
 | 
			
		|||
#include "util/params.h"
 | 
			
		||||
 | 
			
		||||
class solver;
 | 
			
		||||
class model_converter;
 | 
			
		||||
 | 
			
		||||
class solver_factory {
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			@ -184,25 +185,17 @@ public:
 | 
			
		|||
 | 
			
		||||
    virtual expr_ref cube() = 0;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
    /**
 | 
			
		||||
       \brief extract a lookahead candidates for branching.
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    virtual expr_ref lookahead(expr_ref_vector const& assumptions, expr_ref_vector const& candidates) = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief extract learned lemmas.
 | 
			
		||||
    */
 | 
			
		||||
    virtual void get_lemmas(expr_ref_vector& lemmas) {}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief Display the content of this solver.
 | 
			
		||||
    */
 | 
			
		||||
    virtual std::ostream& display(std::ostream & out) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
       \brief expose model converter when solver produces partially reduced set of assertions.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    virtual model_converter_ref get_model_converter() const { return m_mc0; }
 | 
			
		||||
 | 
			
		||||
    class scoped_push {
 | 
			
		||||
        solver& s;
 | 
			
		||||
        bool    m_nopop;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,6 +122,7 @@ public:
 | 
			
		|||
                local_solver->get_model(mdl);
 | 
			
		||||
                mc = model2model_converter(mdl.get());
 | 
			
		||||
                mc = concat(fmc.get(), mc.get());
 | 
			
		||||
                mc = concat(local_solver->mc0(), mc.get());
 | 
			
		||||
            }
 | 
			
		||||
            in->reset();
 | 
			
		||||
            result.push_back(in.get());
 | 
			
		||||
| 
						 | 
				
			
			@ -150,14 +151,8 @@ public:
 | 
			
		|||
            if (m.canceled()) {
 | 
			
		||||
                throw tactic_exception(Z3_CANCELED_MSG);
 | 
			
		||||
            }
 | 
			
		||||
            if (in->models_enabled()) {
 | 
			
		||||
                model_ref mdl;
 | 
			
		||||
                local_solver->get_model(mdl);
 | 
			
		||||
                if (mdl) {
 | 
			
		||||
                    mc = model2model_converter(mdl.get());
 | 
			
		||||
                    mc = concat(fmc.get(), mc.get());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            mc = local_solver->get_model_converter();                
 | 
			
		||||
            mc = concat(fmc.get(), mc.get());            
 | 
			
		||||
            in->reset();
 | 
			
		||||
            unsigned sz = local_solver->get_num_assertions();
 | 
			
		||||
            for (unsigned i = 0; i < sz; ++i) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,7 @@ class tactic2solver : public solver_na2as {
 | 
			
		|||
    unsigned_vector              m_scopes;
 | 
			
		||||
    ref<simple_check_sat_result> m_result;
 | 
			
		||||
    tactic_ref                   m_tactic;
 | 
			
		||||
    ref<model_converter>         m_mc;
 | 
			
		||||
    symbol                       m_logic;
 | 
			
		||||
    params_ref                   m_params;
 | 
			
		||||
    bool                         m_produce_models;
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +65,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    virtual void collect_statistics(statistics & st) const;
 | 
			
		||||
    virtual void get_unsat_core(ptr_vector<expr> & r);
 | 
			
		||||
    virtual void get_model(model_ref & m);
 | 
			
		||||
    virtual void get_model_core(model_ref & m);
 | 
			
		||||
    virtual proof * get_proof();
 | 
			
		||||
    virtual std::string reason_unknown() const;
 | 
			
		||||
    virtual void set_reason_unknown(char const* msg);
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +83,8 @@ public:
 | 
			
		|||
        return expr_ref(m.mk_true(), m);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual model_converter* get_model_converter() { return m_mc.get(); }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ast_manager& tactic2solver::get_manager() const { return m_assertions.get_manager(); }
 | 
			
		||||
| 
						 | 
				
			
			@ -153,12 +156,12 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    model_ref           md;
 | 
			
		||||
    proof_ref           pr(m);
 | 
			
		||||
    proof_ref           pr(m);    
 | 
			
		||||
    expr_dependency_ref core(m);
 | 
			
		||||
    std::string         reason_unknown = "unknown";
 | 
			
		||||
    labels_vec labels;
 | 
			
		||||
    try {
 | 
			
		||||
        switch (::check_sat(*m_tactic, g, md, labels, pr, core, reason_unknown)) {
 | 
			
		||||
        switch (::check_sat(*m_tactic, g, md, m_mc, labels, pr, core, reason_unknown)) {
 | 
			
		||||
        case l_true: 
 | 
			
		||||
            m_result->set_status(l_true);
 | 
			
		||||
            break;
 | 
			
		||||
| 
						 | 
				
			
			@ -226,9 +229,9 @@ void tactic2solver::get_unsat_core(ptr_vector<expr> & r) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tactic2solver::get_model(model_ref & m) {
 | 
			
		||||
void tactic2solver::get_model_core(model_ref & m) {
 | 
			
		||||
    if (m_result.get())
 | 
			
		||||
        m_result->get_model(m);
 | 
			
		||||
        m_result->get_model_core(m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
proof * tactic2solver::get_proof() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ z3_add_component(tactic
 | 
			
		|||
    equiv_proof_converter.cpp
 | 
			
		||||
    extension_model_converter.cpp
 | 
			
		||||
    filter_model_converter.cpp
 | 
			
		||||
    generic_model_converter.cpp
 | 
			
		||||
    goal.cpp
 | 
			
		||||
    goal_num_occurs.cpp
 | 
			
		||||
    goal_shared_occs.cpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ Revision History:
 | 
			
		|||
--*/
 | 
			
		||||
#include "tactic/tactical.h"
 | 
			
		||||
#include "tactic/filter_model_converter.h"
 | 
			
		||||
#include "tactic/extension_model_converter.h"
 | 
			
		||||
#include "tactic/generic_model_converter.h"
 | 
			
		||||
#include "util/cooperate.h"
 | 
			
		||||
#include "ast/arith_decl_plugin.h"
 | 
			
		||||
#include "tactic/core/simplify_tactic.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -127,9 +127,7 @@ class degree_shift_tactic : public tactic {
 | 
			
		|||
 | 
			
		||||
        void visit_args(expr * t, expr_fast_mark1 & visited) {
 | 
			
		||||
            if (is_app(t)) {
 | 
			
		||||
                unsigned num_args = to_app(t)->get_num_args();
 | 
			
		||||
                for (unsigned i = 0; i < num_args; i++) {
 | 
			
		||||
                    expr * arg = to_app(t)->get_arg(i);
 | 
			
		||||
                for (expr * arg : *to_app(t)) {
 | 
			
		||||
                    save_degree(arg, m_one);
 | 
			
		||||
                    visit(arg, visited);
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -166,11 +164,9 @@ class degree_shift_tactic : public tactic {
 | 
			
		|||
 | 
			
		||||
        void display_candidates(std::ostream & out) {
 | 
			
		||||
            out << "candidates:\n";
 | 
			
		||||
            obj_map<app, rational>::iterator it  = m_var2degree.begin();
 | 
			
		||||
            obj_map<app, rational>::iterator end = m_var2degree.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                if (!it->m_value.is_one()) {
 | 
			
		||||
                    out << "POWER: " << it->m_value << "\n" << mk_ismt2_pp(it->m_key, m) << "\n";
 | 
			
		||||
            for (auto const& kv : m_var2degree) {
 | 
			
		||||
                if (!kv.m_value.is_one()) {
 | 
			
		||||
                    out << "POWER: " << kv.m_value << "\n" << mk_ismt2_pp(kv.m_key, m) << "\n";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -189,48 +185,42 @@ class degree_shift_tactic : public tactic {
 | 
			
		|||
        void discard_non_candidates() {
 | 
			
		||||
            m_pinned.reset();
 | 
			
		||||
            ptr_vector<app> to_delete;
 | 
			
		||||
            obj_map<app, rational>::iterator it  = m_var2degree.begin();
 | 
			
		||||
            obj_map<app, rational>::iterator end = m_var2degree.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                if (it->m_value.is_one())
 | 
			
		||||
                    to_delete.push_back(it->m_key);
 | 
			
		||||
            for (auto const& kv : m_var2degree) {
 | 
			
		||||
                if (kv.m_value.is_one())
 | 
			
		||||
                    to_delete.push_back(kv.m_key);
 | 
			
		||||
                else
 | 
			
		||||
                    m_pinned.push_back(it->m_key); // make sure it is not deleted during simplifications
 | 
			
		||||
                    m_pinned.push_back(kv.m_key); // make sure it is not deleted during simplifications
 | 
			
		||||
            }
 | 
			
		||||
            ptr_vector<app>::iterator it2  = to_delete.begin();
 | 
			
		||||
            ptr_vector<app>::iterator end2 = to_delete.end();
 | 
			
		||||
            for (; it2 != end2; ++it2) 
 | 
			
		||||
                m_var2degree.erase(*it2);
 | 
			
		||||
            for (app* a : to_delete) 
 | 
			
		||||
                m_var2degree.erase(a);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void prepare_substitution(model_converter_ref & mc) {
 | 
			
		||||
            SASSERT(!m_var2degree.empty());
 | 
			
		||||
            filter_model_converter * fmc = 0;
 | 
			
		||||
            extension_model_converter * xmc = 0;
 | 
			
		||||
            generic_model_converter * xmc = 0;
 | 
			
		||||
            if (m_produce_models) {
 | 
			
		||||
                fmc = alloc(filter_model_converter, m);
 | 
			
		||||
                xmc = alloc(extension_model_converter, m);
 | 
			
		||||
                xmc = alloc(generic_model_converter, m);
 | 
			
		||||
                mc = concat(fmc, xmc);
 | 
			
		||||
            }
 | 
			
		||||
            obj_map<app, rational>::iterator it  = m_var2degree.begin();
 | 
			
		||||
            obj_map<app, rational>::iterator end = m_var2degree.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                SASSERT(it->m_value.is_int());
 | 
			
		||||
                SASSERT(it->m_value >= rational(2));
 | 
			
		||||
                app * fresh = m.mk_fresh_const(0, it->m_key->get_decl()->get_range());
 | 
			
		||||
            for (auto const& kv : m_var2degree) {
 | 
			
		||||
                SASSERT(kv.m_value.is_int());
 | 
			
		||||
                SASSERT(kv.m_value >= rational(2));
 | 
			
		||||
                app * fresh = m.mk_fresh_const(0, kv.m_key->get_decl()->get_range());
 | 
			
		||||
                m_pinned.push_back(fresh);
 | 
			
		||||
                m_var2var.insert(it->m_key, fresh);
 | 
			
		||||
                m_var2var.insert(kv.m_key, fresh);
 | 
			
		||||
                if (m_produce_models) {
 | 
			
		||||
                    fmc->insert(fresh->get_decl());
 | 
			
		||||
                    xmc->insert(it->m_key->get_decl(), mk_power(fresh, rational(1)/it->m_value));
 | 
			
		||||
                    xmc->add(kv.m_key->get_decl(), mk_power(fresh, rational(1)/kv.m_value));
 | 
			
		||||
                }
 | 
			
		||||
                if (m_produce_proofs) {
 | 
			
		||||
                    expr * s  = mk_power(it->m_key, it->m_value);
 | 
			
		||||
                    expr * s  = mk_power(kv.m_key, kv.m_value);
 | 
			
		||||
                    expr * eq = m.mk_eq(fresh, s);
 | 
			
		||||
                    proof * pr1 = m.mk_def_intro(eq);
 | 
			
		||||
                    proof * result_pr = m.mk_apply_def(fresh, s, pr1);
 | 
			
		||||
                    m_pinned.push_back(result_pr);
 | 
			
		||||
                    m_var2pr.insert(it->m_key, result_pr);
 | 
			
		||||
                    m_var2pr.insert(kv.m_key, result_pr);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -267,17 +257,15 @@ class degree_shift_tactic : public tactic {
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
                // add >= 0 constraints for variables with even degree
 | 
			
		||||
                obj_map<app, rational>::iterator it  = m_var2degree.begin();
 | 
			
		||||
                obj_map<app, rational>::iterator end = m_var2degree.end();
 | 
			
		||||
                for (; it != end; ++it) {
 | 
			
		||||
                    SASSERT(it->m_value.is_int());
 | 
			
		||||
                    SASSERT(it->m_value >= rational(2));
 | 
			
		||||
                    if (it->m_value.is_even()) {
 | 
			
		||||
                        app * new_var  = m_var2var.find(it->m_key);
 | 
			
		||||
                for (auto const& kv : m_var2degree) {
 | 
			
		||||
                    SASSERT(kv.m_value.is_int());
 | 
			
		||||
                    SASSERT(kv.m_value >= rational(2));
 | 
			
		||||
                    if (kv.m_value.is_even()) {
 | 
			
		||||
                        app * new_var  = m_var2var.find(kv.m_key);
 | 
			
		||||
                        app * new_c    = m_autil.mk_ge(new_var, m_autil.mk_numeral(rational(0), false));
 | 
			
		||||
                        proof * new_pr = 0;
 | 
			
		||||
                        if (m_produce_proofs) {
 | 
			
		||||
                            proof * pr = m_var2pr.find(it->m_key);
 | 
			
		||||
                            proof * pr = m_var2pr.find(kv.m_key);
 | 
			
		||||
                            new_pr     = m.mk_th_lemma(m_autil.get_family_id(), new_c, 1, &pr);
 | 
			
		||||
                        }
 | 
			
		||||
                        g->assert_expr(new_c, new_pr, 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -113,6 +113,11 @@ public:
 | 
			
		|||
        }
 | 
			
		||||
        return mc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void display(std::ostream & out) {
 | 
			
		||||
        out << "(elim01-model-converter)\n";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,12 +107,18 @@ class eq2bv_tactic : public tactic {
 | 
			
		|||
        
 | 
			
		||||
        virtual model_converter* translate(ast_translation & translator) {
 | 
			
		||||
            bvmc* v = alloc(bvmc);
 | 
			
		||||
            obj_map<func_decl, func_decl*>::iterator it = m_map.begin(), end = m_map.end();
 | 
			
		||||
            for (; it != end; ++it) {
 | 
			
		||||
                v->m_map.insert(translator(it->m_key), translator(it->m_value));
 | 
			
		||||
            for (auto const& kv : m_map) {
 | 
			
		||||
                v->m_map.insert(translator(kv.m_key), translator(kv.m_value));
 | 
			
		||||
            }
 | 
			
		||||
            return v;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream & out) {
 | 
			
		||||
            for (auto const& kv : m_map) {
 | 
			
		||||
                out << "(model-set " << kv.m_key->get_name() << " " << kv.m_value->get_name() << ")\n";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,10 +131,8 @@ public:
 | 
			
		|||
        for (unsigned i = 0; i < size; ++i) {
 | 
			
		||||
            quick_for_each_expr(proc, visited, g->form(i));
 | 
			
		||||
        }
 | 
			
		||||
        obj_hashtable<sort>::iterator it = m_non_fd_sorts.begin(), end = m_non_fd_sorts.end();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            m_fd_sorts.remove(*it);
 | 
			
		||||
        }
 | 
			
		||||
        for (sort* s : m_non_fd_sorts) 
 | 
			
		||||
            m_fd_sorts.remove(s);
 | 
			
		||||
        if (!m_fd_sorts.empty()) {
 | 
			
		||||
            ref<extension_model_converter> ext = alloc(extension_model_converter, m);
 | 
			
		||||
            ref<filter_model_converter> filter = alloc(filter_model_converter, m);
 | 
			
		||||
| 
						 | 
				
			
			@ -152,21 +150,12 @@ public:
 | 
			
		|||
            }
 | 
			
		||||
            expr_ref_vector bounds(m);
 | 
			
		||||
            rw.flush_side_constraints(bounds);
 | 
			
		||||
            for (unsigned i = 0; i < bounds.size(); ++i) {
 | 
			
		||||
                g->assert_expr(bounds[i].get());
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
                obj_map<func_decl, func_decl*>::iterator it = rw.enum2bv().begin(), end = rw.enum2bv().end();
 | 
			
		||||
                for (; it != end; ++it) {
 | 
			
		||||
                    filter->insert(it->m_value);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
                obj_map<func_decl, expr*>::iterator it = rw.enum2def().begin(), end = rw.enum2def().end();
 | 
			
		||||
                for (; it != end; ++it) {
 | 
			
		||||
                    ext->insert(it->m_key, it->m_value);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (expr* b : bounds) 
 | 
			
		||||
                g->assert_expr(b);
 | 
			
		||||
            for (auto const& kv : rw.enum2bv()) 
 | 
			
		||||
                filter->insert(kv.m_value);
 | 
			
		||||
            for (auto const& kv : rw.enum2def()) 
 | 
			
		||||
                ext->insert(kv.m_key, kv.m_value);
 | 
			
		||||
            
 | 
			
		||||
            mc = concat(filter.get(), ext.get());
 | 
			
		||||
            report_tactic_progress(":fd-num-translated", rw.num_translated());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,8 +38,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    virtual void cancel() {}
 | 
			
		||||
    
 | 
			
		||||
    // for debugging purposes
 | 
			
		||||
    virtual void display(std::ostream & out) {}
 | 
			
		||||
    virtual void display(std::ostream & out) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
| 
						 | 
				
			
			@ -68,10 +67,8 @@ public:
 | 
			
		|||
    virtual char const * get_name() const = 0;
 | 
			
		||||
    
 | 
			
		||||
    virtual void display(std::ostream & out) {
 | 
			
		||||
        out << "(" << get_name() << "\n";
 | 
			
		||||
        m_c1->display(out);
 | 
			
		||||
        m_c2->display(out);
 | 
			
		||||
        out << ")\n";
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,10 +83,9 @@ protected:
 | 
			
		|||
    T * translate_core(ast_translation & translator) {
 | 
			
		||||
        T * t1 = m_c1 ? m_c1->translate(translator) : 0;
 | 
			
		||||
        ptr_buffer<T> t2s;
 | 
			
		||||
        unsigned num = m_c2s.size();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++)
 | 
			
		||||
            t2s.push_back(m_c2s[i] ? m_c2s[i]->translate(translator) : 0);
 | 
			
		||||
        return alloc(T2, t1, num, t2s.c_ptr(), m_szs.c_ptr());
 | 
			
		||||
        for (T* c : m_c2s)
 | 
			
		||||
            t2s.push_back(c ? c->translate(translator) : 0);
 | 
			
		||||
        return alloc(T2, t1, m_c2s.size(), t2s.c_ptr(), m_szs.c_ptr());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			@ -105,36 +101,24 @@ public:
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~concat_star_converter() {
 | 
			
		||||
        unsigned sz = m_c2s.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; i++) {
 | 
			
		||||
            T * c2 = m_c2s[i];
 | 
			
		||||
            if (c2)
 | 
			
		||||
                c2->dec_ref();
 | 
			
		||||
        }
 | 
			
		||||
        for (T* c : m_c2s)
 | 
			
		||||
            if (c) c->dec_ref();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void cancel() {
 | 
			
		||||
        if (m_c1)
 | 
			
		||||
            m_c1->cancel();
 | 
			
		||||
        unsigned num = m_c2s.size();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++) {
 | 
			
		||||
            if (m_c2s[i])
 | 
			
		||||
                m_c2s[i]->cancel();
 | 
			
		||||
        }
 | 
			
		||||
        for (T* c : m_c2s)
 | 
			
		||||
            if (c) c->cancel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual char const * get_name() const = 0;
 | 
			
		||||
    
 | 
			
		||||
    virtual void display(std::ostream & out) {
 | 
			
		||||
        out << "(" << get_name() << "\n";
 | 
			
		||||
        if (m_c1)
 | 
			
		||||
            m_c1->display(out);
 | 
			
		||||
        out << "(\n";
 | 
			
		||||
        unsigned num = m_c2s.size();
 | 
			
		||||
        for (unsigned i = 0; i < num; i++)
 | 
			
		||||
            if (m_c2s[i])
 | 
			
		||||
                m_c2s[i]->display(out);
 | 
			
		||||
        out << "))\n";
 | 
			
		||||
        for (T* c : m_c2s) 
 | 
			
		||||
            if (c) c->display(out);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ Notes:
 | 
			
		|||
 | 
			
		||||
--*/
 | 
			
		||||
#include "tactic/tactical.h"
 | 
			
		||||
#include "tactic/extension_model_converter.h"
 | 
			
		||||
#include "tactic/generic_model_converter.h"
 | 
			
		||||
#include "tactic/filter_model_converter.h"
 | 
			
		||||
#include "ast/rewriter/rewriter_def.h"
 | 
			
		||||
#include "ast/arith_decl_plugin.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ class elim_uncnstr_tactic : public tactic {
 | 
			
		|||
    struct imp {
 | 
			
		||||
        // unconstrained vars collector
 | 
			
		||||
 | 
			
		||||
        typedef extension_model_converter mc;
 | 
			
		||||
        typedef generic_model_converter mc;
 | 
			
		||||
 | 
			
		||||
        struct rw_cfg : public default_rewriter_cfg {
 | 
			
		||||
            bool                   m_produce_proofs;
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +120,7 @@ class elim_uncnstr_tactic : public tactic {
 | 
			
		|||
                SASSERT(uncnstr(v));
 | 
			
		||||
                SASSERT(to_app(v)->get_num_args() == 0);
 | 
			
		||||
                if (m_mc)
 | 
			
		||||
                    m_mc->insert(to_app(v)->get_decl(), def);
 | 
			
		||||
                    m_mc->add(to_app(v)->get_decl(), def);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            void add_defs(unsigned num, expr * const * args, expr * u, expr * identity) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,8 +50,8 @@ public:
 | 
			
		|||
 | 
			
		||||
    virtual void operator()(model_ref & mdl, unsigned goal_idx) {
 | 
			
		||||
        SASSERT(goal_idx == 0);
 | 
			
		||||
        for (unsigned i = 0; i < m_const.size(); ++i) {
 | 
			
		||||
            mdl->register_decl(m_const[i].first->get_decl(), m_const[i].second);
 | 
			
		||||
        for (auto const& kv : m_const) {
 | 
			
		||||
            mdl->register_decl(kv.first->get_decl(), kv.second);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,12 +65,18 @@ public:
 | 
			
		|||
 | 
			
		||||
    virtual model_converter * translate(ast_translation & translator) {
 | 
			
		||||
        pb_preproc_model_converter* mc = alloc(pb_preproc_model_converter, translator.to());
 | 
			
		||||
        for (unsigned i = 0; i < m_const.size(); ++i) {
 | 
			
		||||
            mc->set_value_p(translator(m_const[i].first), translator(m_const[i].second));
 | 
			
		||||
        for (auto const& kv : m_const) {
 | 
			
		||||
            mc->set_value_p(translator(kv.first), translator(kv.second));
 | 
			
		||||
        }
 | 
			
		||||
        return mc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void display(std::ostream & out) {
 | 
			
		||||
        for (auto const& kv : m_const) {
 | 
			
		||||
            out << "(model-set " << mk_pp(kv.first, m) << " " << mk_pp(kv.second, m) << ")\n";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void set_value_p(app* e, expr* v) {
 | 
			
		||||
        SASSERT(e->get_num_args() == 0);  
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,6 +79,8 @@ class split_clause_tactic : public tactic {
 | 
			
		|||
        virtual proof_converter * translate(ast_translation & translator) {
 | 
			
		||||
            return alloc(split_pc, translator.to(), translator(m_clause), translator(m_clause_pr));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        virtual void display(std::ostream & out) { out << "(split-clause-pc)\n"; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,6 +47,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    ast_manager& get_manager() { return m; }
 | 
			
		||||
 | 
			
		||||
    virtual void display(std::ostream & out) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ Module Name:
 | 
			
		|||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Model converter that introduces eliminated variables in a model.
 | 
			
		||||
Model converter that introduces eliminated variables in a model.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16,11 +16,11 @@ Author:
 | 
			
		|||
Notes:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include "tactic/extension_model_converter.h"
 | 
			
		||||
#include "model/model_evaluator.h"
 | 
			
		||||
#include "ast/ast_smt2_pp.h"
 | 
			
		||||
#include "model/model_v2_pp.h"
 | 
			
		||||
#include "ast/ast_pp.h"
 | 
			
		||||
#include "ast/ast_smt2_pp.h"
 | 
			
		||||
#include "model/model_evaluator.h"
 | 
			
		||||
#include "model/model_v2_pp.h"
 | 
			
		||||
#include "tactic/extension_model_converter.h"
 | 
			
		||||
 | 
			
		||||
extension_model_converter::~extension_model_converter() {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -78,20 +78,17 @@ void extension_model_converter::insert(func_decl * v, expr * def) {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void extension_model_converter::display(std::ostream & out) {
 | 
			
		||||
    out << "(extension-model-converter";
 | 
			
		||||
    for (unsigned i = 0; i < m_vars.size(); i++) {
 | 
			
		||||
        out << "\n  (" << m_vars.get(i)->get_name() << " ";
 | 
			
		||||
        unsigned indent = m_vars.get(i)->get_name().size() + 4;
 | 
			
		||||
        out << mk_ismt2_pp(m_defs.get(i), m(), indent) << ")";
 | 
			
		||||
        display_add(out, m(), m_vars.get(i), m_defs.get(i));
 | 
			
		||||
    }
 | 
			
		||||
    out << ")" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
model_converter * extension_model_converter::translate(ast_translation & translator) {
 | 
			
		||||
    extension_model_converter * res = alloc(extension_model_converter, translator.to());
 | 
			
		||||
    for (unsigned i = 0; i < m_vars.size(); i++)
 | 
			
		||||
        res->m_vars.push_back(translator(m_vars[i].get()));
 | 
			
		||||
    for (unsigned i = 0; i < m_defs.size(); i++)
 | 
			
		||||
        res->m_defs.push_back(translator(m_defs[i].get()));
 | 
			
		||||
    for (func_decl* v : m_vars)
 | 
			
		||||
        res->m_vars.push_back(translator(v));
 | 
			
		||||
    for (expr* d : m_defs) 
 | 
			
		||||
        res->m_defs.push_back(translator(d));
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,12 +23,11 @@ Notes:
 | 
			
		|||
#include "ast/ast.h"
 | 
			
		||||
#include "tactic/model_converter.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class extension_model_converter : public model_converter {
 | 
			
		||||
    func_decl_ref_vector  m_vars;
 | 
			
		||||
    expr_ref_vector       m_defs;
 | 
			
		||||
public:
 | 
			
		||||
    extension_model_converter(ast_manager & m):m_vars(m), m_defs(m) {
 | 
			
		||||
    extension_model_converter(ast_manager & m): m_vars(m), m_defs(m) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~extension_model_converter();
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +43,4 @@ public:
 | 
			
		|||
 | 
			
		||||
    virtual model_converter * translate(ast_translation & translator);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,11 +55,9 @@ void filter_model_converter::operator()(svector<symbol> & labels, unsigned goal_
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void filter_model_converter::display(std::ostream & out) {
 | 
			
		||||
    out << "(filter-model-converter";
 | 
			
		||||
    for (unsigned i = 0; i < m_decls.size(); i++) {
 | 
			
		||||
        out << " " << m_decls.get(i)->get_name();
 | 
			
		||||
    for (func_decl* f : m_decls) {
 | 
			
		||||
        display_del(out, f);
 | 
			
		||||
    }
 | 
			
		||||
    out << ")" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
model_converter * filter_model_converter::translate(ast_translation & translator) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ Notes:
 | 
			
		|||
class filter_model_converter : public model_converter {
 | 
			
		||||
    func_decl_ref_vector  m_decls;
 | 
			
		||||
public:
 | 
			
		||||
    filter_model_converter(ast_manager & m):m_decls(m) {}
 | 
			
		||||
    filter_model_converter(ast_manager & m): m_decls(m) {}
 | 
			
		||||
    
 | 
			
		||||
    virtual ~filter_model_converter();
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,6 +78,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    ast_manager& get_manager() { return m; }
 | 
			
		||||
 | 
			
		||||
    virtual void display(std::ostream & out) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,10 +18,53 @@ Notes:
 | 
			
		|||
--*/
 | 
			
		||||
#include "tactic/model_converter.h"
 | 
			
		||||
#include "model/model_v2_pp.h"
 | 
			
		||||
#include "ast/ast_smt2_pp.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Add or overwrite value in model.
 | 
			
		||||
 */
 | 
			
		||||
void model_converter::display_add(std::ostream& out, ast_manager& m, func_decl* f, expr* e) const {
 | 
			
		||||
    // TBD: for arity > 0, requires signature of arguments.
 | 
			
		||||
    if (m_env) {
 | 
			
		||||
        ast_smt2_pp(out, f, e, *m_env, params_ref(), 0, "model-add");        
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        unsigned indent = f->get_name().size() + 4;
 | 
			
		||||
        out << "(model-add " << f->get_name() << " " << mk_ismt2_pp(e, m, indent) << ")\n";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A value is removed from the model.
 | 
			
		||||
 */
 | 
			
		||||
void model_converter::display_del(std::ostream& out, func_decl* f) const {
 | 
			
		||||
    if (m_env) {
 | 
			
		||||
        ast_smt2_pp(out, f, *m_env, params_ref(), 0, "model-del");
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        out << "(model-del " << f->get_name() << ")\n";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void model_converter::display_add(std::ostream& out, ast_manager& m) {
 | 
			
		||||
    // default printer for converter that adds entries
 | 
			
		||||
    model_ref mdl = alloc(model, m);
 | 
			
		||||
    (*this)(mdl);
 | 
			
		||||
    for (unsigned i = 0, sz = mdl->get_num_constants(); i < sz; ++i) {
 | 
			
		||||
        func_decl* f = mdl->get_constant(i);
 | 
			
		||||
        display_add(out, m, f, mdl->get_const_interp(f));
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned i = 0, sz = mdl->get_num_functions(); i < sz; ++i) {
 | 
			
		||||
        func_decl* f = mdl->get_function(i);
 | 
			
		||||
        func_interp* fi = mdl->get_func_interp(f);
 | 
			
		||||
        display_add(out, m, f, fi->get_interp());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class concat_model_converter : public concat_converter<model_converter> {
 | 
			
		||||
public:
 | 
			
		||||
    concat_model_converter(model_converter * mc1, model_converter * mc2):concat_converter<model_converter>(mc1, mc2) {}
 | 
			
		||||
    concat_model_converter(model_converter * mc1, model_converter * mc2): concat_converter<model_converter>(mc1, mc2) {}
 | 
			
		||||
 | 
			
		||||
    virtual void operator()(model_ref & m) {
 | 
			
		||||
        this->m_c2->operator()(m);
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +80,6 @@ public:
 | 
			
		|||
        this->m_c2->operator()(r, goal_idx);
 | 
			
		||||
        this->m_c1->operator()(r, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
    virtual char const * get_name() const { return "concat-model-converter"; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -90,9 +132,9 @@ public:
 | 
			
		|||
                // found the model converter that should be used
 | 
			
		||||
                model_converter * c2 = this->m_c2s[i];
 | 
			
		||||
                if (c2)
 | 
			
		||||
                  c2->operator()(r, goal_idx);
 | 
			
		||||
                    c2->operator()(r, goal_idx);
 | 
			
		||||
                if (m_c1)
 | 
			
		||||
                  this->m_c1->operator()(r, i);
 | 
			
		||||
                    this->m_c1->operator()(r, i);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // invalid goal
 | 
			
		||||
| 
						 | 
				
			
			@ -143,10 +185,10 @@ public:
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void operator()(labels_vec & r, unsigned goal_idx) {
 | 
			
		||||
      r.append(m_labels.size(), m_labels.c_ptr());
 | 
			
		||||
        r.append(m_labels.size(), m_labels.c_ptr());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  virtual void cancel() {
 | 
			
		||||
    virtual void cancel() {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    virtual void display(std::ostream & out) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,19 @@ Notes:
 | 
			
		|||
#include "util/ref.h"
 | 
			
		||||
 | 
			
		||||
class labels_vec : public svector<symbol> {};
 | 
			
		||||
class smt2_pp_environment; 
 | 
			
		||||
 | 
			
		||||
class model_converter : public converter {
 | 
			
		||||
protected:
 | 
			
		||||
    smt2_pp_environment* m_env;
 | 
			
		||||
    void display_add(std::ostream& out, ast_manager& m, func_decl* f, expr* e) const;
 | 
			
		||||
    void display_del(std::ostream& out, func_decl* f) const;
 | 
			
		||||
    void display_add(std::ostream& out, ast_manager& m);
 | 
			
		||||
    
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    model_converter(): m_env(0) {}
 | 
			
		||||
 | 
			
		||||
    virtual void operator()(model_ref & m) {}  // TODO: delete
 | 
			
		||||
 | 
			
		||||
    virtual void operator()(model_ref & m, unsigned goal_idx) {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,10 +44,12 @@ public:
 | 
			
		|||
        SASSERT(goal_idx == 0);
 | 
			
		||||
        operator()(m);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void operator()(labels_vec & r, unsigned goal_idx) {}
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    virtual model_converter * translate(ast_translation & translator) = 0;
 | 
			
		||||
 | 
			
		||||
    void set_pp_env(smt2_pp_environment* env) { m_env = env; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef ref<model_converter> model_converter_ref;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,7 +150,7 @@ public:
 | 
			
		|||
    virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback);  }
 | 
			
		||||
    virtual void collect_statistics(statistics & st) const { m_solver->collect_statistics(st); }
 | 
			
		||||
    virtual void get_unsat_core(ptr_vector<expr> & r) { m_solver->get_unsat_core(r); }
 | 
			
		||||
    virtual void get_model(model_ref & mdl) {
 | 
			
		||||
    virtual void get_model_core(model_ref & mdl) {
 | 
			
		||||
        m_solver->get_model(mdl);
 | 
			
		||||
        if (mdl) {
 | 
			
		||||
            extend_model(mdl);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ public:
 | 
			
		|||
    virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback);  }
 | 
			
		||||
    virtual void collect_statistics(statistics & st) const { m_solver->collect_statistics(st); }
 | 
			
		||||
    virtual void get_unsat_core(ptr_vector<expr> & r) { m_solver->get_unsat_core(r); }
 | 
			
		||||
    virtual void get_model(model_ref & mdl) { 
 | 
			
		||||
    virtual void get_model_core(model_ref & mdl) { 
 | 
			
		||||
        m_solver->get_model(mdl);
 | 
			
		||||
        if (mdl) {
 | 
			
		||||
            extend_model(mdl);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ public:
 | 
			
		|||
        m_solver->collect_statistics(st); 
 | 
			
		||||
    }
 | 
			
		||||
    virtual void get_unsat_core(ptr_vector<expr> & r) { m_solver->get_unsat_core(r); }
 | 
			
		||||
    virtual void get_model(model_ref & mdl) { 
 | 
			
		||||
    virtual void get_model_core(model_ref & mdl) { 
 | 
			
		||||
        m_solver->get_model(mdl);
 | 
			
		||||
        if (mdl) {
 | 
			
		||||
            filter_model(mdl);            
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,8 @@ public:
 | 
			
		|||
    // run the replacements the inverse direction.
 | 
			
		||||
    void invert() { m_proofs.reverse(); }
 | 
			
		||||
 | 
			
		||||
    virtual void display(std::ostream & out) {}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -175,7 +175,7 @@ void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_conve
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown) {
 | 
			
		||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& mc, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown) {
 | 
			
		||||
    bool models_enabled = g->models_enabled();
 | 
			
		||||
    bool proofs_enabled = g->proofs_enabled();
 | 
			
		||||
    bool cores_enabled  = g->unsat_core_enabled();
 | 
			
		||||
| 
						 | 
				
			
			@ -184,7 +184,6 @@ lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, p
 | 
			
		|||
    core = 0;
 | 
			
		||||
    ast_manager & m = g->m();
 | 
			
		||||
    goal_ref_buffer r;
 | 
			
		||||
    model_converter_ref mc;
 | 
			
		||||
    proof_converter_ref pc;
 | 
			
		||||
    try {
 | 
			
		||||
        exec(t, g, r, mc, pc, core);
 | 
			
		||||
| 
						 | 
				
			
			@ -219,9 +218,9 @@ lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, p
 | 
			
		|||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        if (models_enabled) {
 | 
			
		||||
          model_converter2model(m, mc.get(), md);
 | 
			
		||||
          if (mc)
 | 
			
		||||
              (*mc)(labels, 0);
 | 
			
		||||
            model_converter2model(m, mc.get(), md);
 | 
			
		||||
            if (mc)
 | 
			
		||||
                (*mc)(labels, 0);
 | 
			
		||||
        }
 | 
			
		||||
        reason_unknown = "incomplete";
 | 
			
		||||
        return l_undef;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,7 +153,7 @@ public:
 | 
			
		|||
#define MK_SIMPLE_TACTIC_FACTORY(NAME, ST)  MK_TACTIC_FACTORY(NAME, return ST;)
 | 
			
		||||
 | 
			
		||||
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core);
 | 
			
		||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown);
 | 
			
		||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, model_converter_ref& mc, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown);
 | 
			
		||||
 | 
			
		||||
// Throws an exception if goal \c in requires proof generation.
 | 
			
		||||
void fail_if_proof_generation(char const * tactic_name, goal_ref const & in);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue