mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	fix bugs reported by Filip Konecny <filip.konecny@epfl.ch> in PDR
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									780ad7cc17
								
							
						
					
					
						commit
						83add2bd9b
					
				
					 14 changed files with 176 additions and 34 deletions
				
			
		| 
						 | 
					@ -260,6 +260,7 @@ class smt_printer {
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            m_out << sym << "[";
 | 
					            m_out << sym << "[";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (unsigned i = 0; i < num_params; ++i) {
 | 
					        for (unsigned i = 0; i < num_params; ++i) {
 | 
				
			||||||
            parameter const& p = params[i];
 | 
					            parameter const& p = params[i];
 | 
				
			||||||
            if (p.is_ast()) {
 | 
					            if (p.is_ast()) {
 | 
				
			||||||
| 
						 | 
					@ -642,9 +643,7 @@ class smt_printer {
 | 
				
			||||||
            m_out << m_var_names[m_num_var_names - idx - 1];
 | 
					            m_out << m_var_names[m_num_var_names - idx - 1];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            if (!m_is_smt2) {
 | 
					            m_out << "?" << idx;
 | 
				
			||||||
                m_out << "?" << idx;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -709,8 +709,7 @@ namespace datalog {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PRT(_x_) ((_x_)?"T":"F")
 | 
					#define PRT(_x_) ((_x_)?"T":"F")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool mk_rule_inliner::inline_linear(rule_set const& source, scoped_ptr<rule_set>& rules) {
 | 
					    bool mk_rule_inliner::inline_linear(scoped_ptr<rule_set>& rules) {
 | 
				
			||||||
        scoped_ptr<rule_set> res = alloc(rule_set, m_context);
 | 
					 | 
				
			||||||
        bool done_something = false;        
 | 
					        bool done_something = false;        
 | 
				
			||||||
        unsigned sz = rules->get_num_rules();
 | 
					        unsigned sz = rules->get_num_rules();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -731,7 +730,7 @@ namespace datalog {
 | 
				
			||||||
        svector<bool>& can_expand = m_head_visitor.can_expand();
 | 
					        svector<bool>& can_expand = m_head_visitor.can_expand();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (unsigned i = 0; i < sz; ++i) {
 | 
					        for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
            add_rule(source, acc[i].get(), i);
 | 
					            add_rule(*rules, acc[i].get(), i);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // initialize substitution.
 | 
					        // initialize substitution.
 | 
				
			||||||
| 
						 | 
					@ -808,7 +807,7 @@ namespace datalog {
 | 
				
			||||||
                TRACE("dl", r->display(m_context, tout); r2->display(m_context, tout); rl_res->display(m_context, tout); );
 | 
					                TRACE("dl", r->display(m_context, tout); r2->display(m_context, tout); rl_res->display(m_context, tout); );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                del_rule(r, i);
 | 
					                del_rule(r, i);
 | 
				
			||||||
                add_rule(source, rl_res.get(), i);
 | 
					                add_rule(*rules, rl_res.get(), i);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                r = rl_res;
 | 
					                r = rl_res;
 | 
				
			||||||
| 
						 | 
					@ -828,13 +827,15 @@ namespace datalog {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (done_something) {
 | 
					        if (done_something) {
 | 
				
			||||||
            rules = alloc(rule_set, m_context);
 | 
					            scoped_ptr<rule_set> res = alloc(rule_set, m_context);
 | 
				
			||||||
            for (unsigned i = 0; i < sz; ++i) {
 | 
					            for (unsigned i = 0; i < sz; ++i) {
 | 
				
			||||||
                if (valid.get(i)) {
 | 
					                if (valid.get(i)) {
 | 
				
			||||||
                    rules->add_rule(acc[i].get());
 | 
					                    res->add_rule(acc[i].get());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TRACE("dl", rules->display(tout););
 | 
					            res->inherit_predicates(*rules);
 | 
				
			||||||
 | 
					            TRACE("dl", res->display(tout););
 | 
				
			||||||
 | 
					            rules = res.detach();
 | 
				
			||||||
        }        
 | 
					        }        
 | 
				
			||||||
        return done_something;
 | 
					        return done_something;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -871,11 +872,17 @@ namespace datalog {
 | 
				
			||||||
            // try eager inlining
 | 
					            // try eager inlining
 | 
				
			||||||
            if (do_eager_inlining(res)) {
 | 
					            if (do_eager_inlining(res)) {
 | 
				
			||||||
                something_done = true;
 | 
					                something_done = true;
 | 
				
			||||||
            }
 | 
					            }            
 | 
				
			||||||
            TRACE("dl", res->display(tout << "after eager inlining\n"););
 | 
					            TRACE("dl", res->display(tout << "after eager inlining\n"););
 | 
				
			||||||
 | 
					        }    
 | 
				
			||||||
 | 
					        if (something_done) {
 | 
				
			||||||
 | 
					            res->inherit_predicates(source);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            res = alloc(rule_set, source);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (m_context.get_params().inline_linear() && inline_linear(source, res)) {
 | 
					        if (m_context.get_params().inline_linear() && inline_linear(res)) {
 | 
				
			||||||
            something_done = true;
 | 
					            something_done = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -883,7 +890,6 @@ namespace datalog {
 | 
				
			||||||
            res = 0;
 | 
					            res = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            res->inherit_predicates(source);
 | 
					 | 
				
			||||||
            m_context.add_model_converter(hsmc.get());
 | 
					            m_context.add_model_converter(hsmc.get());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -172,7 +172,7 @@ namespace datalog {
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
           Inline predicates that are known to not be join-points.
 | 
					           Inline predicates that are known to not be join-points.
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        bool inline_linear(rule_set const& source, scoped_ptr<rule_set>& rules);
 | 
					        bool inline_linear(scoped_ptr<rule_set>& rules);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void add_rule(rule_set const& rule_set, rule* r, unsigned i);
 | 
					        void add_rule(rule_set const& rule_set, rule* r, unsigned i);
 | 
				
			||||||
        void del_rule(rule* r, unsigned i);
 | 
					        void del_rule(rule* r, unsigned i);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -241,6 +241,7 @@ namespace datalog {
 | 
				
			||||||
            tgt.add_rule(new_rule);
 | 
					            tgt.add_rule(new_rule);
 | 
				
			||||||
            subs_index.add(new_rule);
 | 
					            subs_index.add(new_rule);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        tgt.inherit_predicates(orig);
 | 
				
			||||||
        TRACE("dl",
 | 
					        TRACE("dl",
 | 
				
			||||||
            tout << "original set size: "<<orig.get_num_rules()<<"\n"
 | 
					            tout << "original set size: "<<orig.get_num_rules()<<"\n"
 | 
				
			||||||
                 << "reduced set size: "<<tgt.get_num_rules()<<"\n"; );
 | 
					                 << "reduced set size: "<<tgt.get_num_rules()<<"\n"; );
 | 
				
			||||||
| 
						 | 
					@ -338,7 +339,7 @@ namespace datalog {
 | 
				
			||||||
        rule_set * res = alloc(rule_set, m_context);
 | 
					        rule_set * res = alloc(rule_set, m_context);
 | 
				
			||||||
        bool modified = transform_rules(source, *res);
 | 
					        bool modified = transform_rules(source, *res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!m_have_new_total_rule && !modified) {
 | 
					        if (!m_have_new_total_rule && !modified) {
 | 
				
			||||||
            dealloc(res);
 | 
					            dealloc(res);
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -347,7 +348,7 @@ namespace datalog {
 | 
				
			||||||
        //During the construction of the new set we may discover new total relations
 | 
					        //During the construction of the new set we may discover new total relations
 | 
				
			||||||
        //(by quantifier elimination on the uninterpreted tails).
 | 
					        //(by quantifier elimination on the uninterpreted tails).
 | 
				
			||||||
        SASSERT(m_new_total_relation_discovery_during_transformation || !m_have_new_total_rule);
 | 
					        SASSERT(m_new_total_relation_discovery_during_transformation || !m_have_new_total_rule);
 | 
				
			||||||
        while(m_have_new_total_rule) {
 | 
					        while (m_have_new_total_rule) {
 | 
				
			||||||
            m_have_new_total_rule = false;
 | 
					            m_have_new_total_rule = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            rule_set * old = res;
 | 
					            rule_set * old = res;
 | 
				
			||||||
| 
						 | 
					@ -355,7 +356,6 @@ namespace datalog {
 | 
				
			||||||
            transform_rules(*old, *res);
 | 
					            transform_rules(*old, *res);
 | 
				
			||||||
            dealloc(old);
 | 
					            dealloc(old);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        res->inherit_predicates(source);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return res;
 | 
					        return res;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1004,16 +1004,14 @@ namespace datalog {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        svector<symbol> names;
 | 
					        svector<symbol> names;
 | 
				
			||||||
        used_symbols<> us;
 | 
					        used_symbols<> us;
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        us(fml);
 | 
					 | 
				
			||||||
        sorts.reverse();
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        for (unsigned i = 0; i < sorts.size(); ++i) {
 | 
					        for (unsigned i = 0; i < sorts.size(); ++i) {
 | 
				
			||||||
            if (!sorts[i]) {
 | 
					            if (!sorts[i]) {
 | 
				
			||||||
                sorts[i] = m.mk_bool_sort();
 | 
					                sorts[i] = m.mk_bool_sort();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					               
 | 
				
			||||||
 | 
					        us(fml);
 | 
				
			||||||
 | 
					        sorts.reverse();
 | 
				
			||||||
        for (unsigned j = 0, i = 0; i < sorts.size(); ++j) {
 | 
					        for (unsigned j = 0, i = 0; i < sorts.size(); ++j) {
 | 
				
			||||||
            for (char c = 'A'; i < sorts.size() && c <= 'Z'; ++c) {
 | 
					            for (char c = 'A'; i < sorts.size() && c <= 'Z'; ++c) {
 | 
				
			||||||
                func_decl_ref f(m);
 | 
					                func_decl_ref f(m);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,12 +125,13 @@ class horn_tactic : public tactic {
 | 
				
			||||||
        enum formula_kind { IS_RULE, IS_QUERY, IS_NONE };
 | 
					        enum formula_kind { IS_RULE, IS_QUERY, IS_NONE };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        formula_kind get_formula_kind(expr_ref& f) {
 | 
					        formula_kind get_formula_kind(expr_ref& f) {
 | 
				
			||||||
            normalize(f);
 | 
					            expr_ref tmp(f);
 | 
				
			||||||
 | 
					            normalize(tmp);
 | 
				
			||||||
            ast_mark mark;
 | 
					            ast_mark mark;
 | 
				
			||||||
            expr_ref_vector args(m), body(m);
 | 
					            expr_ref_vector args(m), body(m);
 | 
				
			||||||
            expr_ref head(m);
 | 
					            expr_ref head(m);
 | 
				
			||||||
            expr* a = 0, *a1 = 0;
 | 
					            expr* a = 0, *a1 = 0;
 | 
				
			||||||
            datalog::flatten_or(f, args);
 | 
					            datalog::flatten_or(tmp, args);
 | 
				
			||||||
            for (unsigned i = 0; i < args.size(); ++i) {
 | 
					            for (unsigned i = 0; i < args.size(); ++i) {
 | 
				
			||||||
                a = args[i].get(); 
 | 
					                a = args[i].get(); 
 | 
				
			||||||
                check_predicate(mark, a);
 | 
					                check_predicate(mark, a);
 | 
				
			||||||
| 
						 | 
					@ -147,12 +148,12 @@ class horn_tactic : public tactic {
 | 
				
			||||||
                    body.push_back(m.mk_not(a));
 | 
					                    body.push_back(m.mk_not(a));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            f = m.mk_and(body.size(), body.c_ptr());
 | 
					 | 
				
			||||||
            if (head) {
 | 
					            if (head) {
 | 
				
			||||||
                f = m.mk_implies(f, head);
 | 
					                // f = m.mk_implies(f, head);
 | 
				
			||||||
                return IS_RULE;
 | 
					                return IS_RULE;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
 | 
					                f = m.mk_and(body.size(), body.c_ptr());
 | 
				
			||||||
                return IS_QUERY;
 | 
					                return IS_QUERY;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -171,7 +172,7 @@ class horn_tactic : public tactic {
 | 
				
			||||||
            tactic_report report("horn", *g);
 | 
					            tactic_report report("horn", *g);
 | 
				
			||||||
            bool produce_proofs = g->proofs_enabled();
 | 
					            bool produce_proofs = g->proofs_enabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (produce_proofs) {
 | 
					            if (produce_proofs) {                
 | 
				
			||||||
                if (!m_ctx.get_params().generate_proof_trace()) {
 | 
					                if (!m_ctx.get_params().generate_proof_trace()) {
 | 
				
			||||||
                    params_ref params = m_ctx.get_params().p;
 | 
					                    params_ref params = m_ctx.get_params().p;
 | 
				
			||||||
                    params.set_bool("generate_proof_trace", true);
 | 
					                    params.set_bool("generate_proof_trace", true);
 | 
				
			||||||
| 
						 | 
					@ -239,10 +240,13 @@ class horn_tactic : public tactic {
 | 
				
			||||||
            switch (is_reachable) {
 | 
					            switch (is_reachable) {
 | 
				
			||||||
            case l_true: {
 | 
					            case l_true: {
 | 
				
			||||||
                // goal is unsat
 | 
					                // goal is unsat
 | 
				
			||||||
                g->assert_expr(m.mk_false());
 | 
					 | 
				
			||||||
                if (produce_proofs) {
 | 
					                if (produce_proofs) {
 | 
				
			||||||
                    proof_ref proof = m_ctx.get_proof();
 | 
					                    proof_ref proof = m_ctx.get_proof();
 | 
				
			||||||
                    pc = proof2proof_converter(m, proof);
 | 
					                    pc = proof2proof_converter(m, proof);
 | 
				
			||||||
 | 
					                    g->assert_expr(m.mk_false(), proof, 0);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    g->assert_expr(m.mk_false());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                break;    
 | 
					                break;    
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,7 @@ Notes:
 | 
				
			||||||
#include "ast_ll_pp.h"
 | 
					#include "ast_ll_pp.h"
 | 
				
			||||||
#include "proof_checker.h"
 | 
					#include "proof_checker.h"
 | 
				
			||||||
#include "smt_value_sort.h"
 | 
					#include "smt_value_sort.h"
 | 
				
			||||||
 | 
					#include "proof_utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace pdr {
 | 
					namespace pdr {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,7 +276,7 @@ namespace pdr {
 | 
				
			||||||
                src.pop_back();
 | 
					                src.pop_back();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (is_invariant(tgt_level, curr, false, assumes_level)) {
 | 
					            else if (is_invariant(tgt_level, curr, false, assumes_level)) {
 | 
				
			||||||
                
 | 
					
 | 
				
			||||||
                add_property(curr, assumes_level?tgt_level:infty_level);
 | 
					                add_property(curr, assumes_level?tgt_level:infty_level);
 | 
				
			||||||
                TRACE("pdr", tout << "is invariant: "<< pp_level(tgt_level) << " " << mk_pp(curr, m) << "\n";);              
 | 
					                TRACE("pdr", tout << "is invariant: "<< pp_level(tgt_level) << " " << mk_pp(curr, m) << "\n";);              
 | 
				
			||||||
                src[i] = src.back();
 | 
					                src[i] = src.back();
 | 
				
			||||||
| 
						 | 
					@ -1225,6 +1226,7 @@ namespace pdr {
 | 
				
			||||||
          m_search(m_params.bfs_model_search()),
 | 
					          m_search(m_params.bfs_model_search()),
 | 
				
			||||||
          m_last_result(l_undef),
 | 
					          m_last_result(l_undef),
 | 
				
			||||||
          m_inductive_lvl(0),
 | 
					          m_inductive_lvl(0),
 | 
				
			||||||
 | 
					          m_expanded_lvl(0),
 | 
				
			||||||
          m_cancel(false)
 | 
					          m_cancel(false)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1680,6 +1682,9 @@ namespace pdr {
 | 
				
			||||||
        proof = m_search.get_proof_trace(*this);
 | 
					        proof = m_search.get_proof_trace(*this);
 | 
				
			||||||
        TRACE("pdr", tout << "PDR trace: " << mk_pp(proof, m) << "\n";);
 | 
					        TRACE("pdr", tout << "PDR trace: " << mk_pp(proof, m) << "\n";);
 | 
				
			||||||
        apply(m, m_pc.get(), proof);
 | 
					        apply(m, m_pc.get(), proof);
 | 
				
			||||||
 | 
					        TRACE("pdr", tout << "PDR trace: " << mk_pp(proof, m) << "\n";);
 | 
				
			||||||
 | 
					        // proof_utils::push_instantiations_up(proof);
 | 
				
			||||||
 | 
					        // TRACE("pdr", tout << "PDR up: " << mk_pp(proof, m) << "\n";);
 | 
				
			||||||
        return proof;
 | 
					        return proof;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1711,6 +1716,7 @@ namespace pdr {
 | 
				
			||||||
        bool reachable;
 | 
					        bool reachable;
 | 
				
			||||||
        while (true) {
 | 
					        while (true) {
 | 
				
			||||||
            checkpoint();
 | 
					            checkpoint();
 | 
				
			||||||
 | 
					            m_expanded_lvl = lvl;
 | 
				
			||||||
            reachable = check_reachability(lvl);
 | 
					            reachable = check_reachability(lvl);
 | 
				
			||||||
            if (reachable) {
 | 
					            if (reachable) {
 | 
				
			||||||
                throw model_exception();
 | 
					                throw model_exception();
 | 
				
			||||||
| 
						 | 
					@ -1769,6 +1775,10 @@ namespace pdr {
 | 
				
			||||||
    void context::expand_node(model_node& n) {
 | 
					    void context::expand_node(model_node& n) {
 | 
				
			||||||
        SASSERT(n.is_open());
 | 
					        SASSERT(n.is_open());
 | 
				
			||||||
        expr_ref_vector cube(m);
 | 
					        expr_ref_vector cube(m);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (n.level() < m_expanded_lvl) {
 | 
				
			||||||
 | 
					            m_expanded_lvl = n.level();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (n.pt().is_reachable(n.state())) {
 | 
					        if (n.pt().is_reachable(n.state())) {
 | 
				
			||||||
            TRACE("pdr", tout << "reachable\n";);
 | 
					            TRACE("pdr", tout << "reachable\n";);
 | 
				
			||||||
| 
						 | 
					@ -1835,7 +1845,7 @@ namespace pdr {
 | 
				
			||||||
        if (m_params.simplify_formulas_pre()) {
 | 
					        if (m_params.simplify_formulas_pre()) {
 | 
				
			||||||
            simplify_formulas();
 | 
					            simplify_formulas();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (unsigned lvl = 0; lvl <= max_prop_lvl; lvl++) {
 | 
					        for (unsigned lvl = m_expanded_lvl; lvl <= max_prop_lvl; lvl++) {
 | 
				
			||||||
            checkpoint();
 | 
					            checkpoint();
 | 
				
			||||||
            bool all_propagated = true;
 | 
					            bool all_propagated = true;
 | 
				
			||||||
            decl2rel::iterator it = m_rels.begin(), end = m_rels.end();
 | 
					            decl2rel::iterator it = m_rels.begin(), end = m_rels.end();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,6 +303,7 @@ namespace pdr {
 | 
				
			||||||
        mutable model_search m_search;
 | 
					        mutable model_search m_search;
 | 
				
			||||||
        lbool                m_last_result;
 | 
					        lbool                m_last_result;
 | 
				
			||||||
        unsigned             m_inductive_lvl;
 | 
					        unsigned             m_inductive_lvl;
 | 
				
			||||||
 | 
					        unsigned             m_expanded_lvl;
 | 
				
			||||||
        ptr_vector<core_generalizer>  m_core_generalizers;
 | 
					        ptr_vector<core_generalizer>  m_core_generalizers;
 | 
				
			||||||
        stats                m_stats;
 | 
					        stats                m_stats;
 | 
				
			||||||
        volatile bool        m_cancel;
 | 
					        volatile bool        m_cancel;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1081,6 +1081,7 @@ namespace pdr {
 | 
				
			||||||
        arith_util a;
 | 
					        arith_util a;
 | 
				
			||||||
        bv_util    bv;
 | 
					        bv_util    bv;
 | 
				
			||||||
        bool m_is_dl;
 | 
					        bool m_is_dl;
 | 
				
			||||||
 | 
					        bool m_test_for_utvpi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool is_numeric(expr* e) const {
 | 
					        bool is_numeric(expr* e) const {
 | 
				
			||||||
            if (a.is_numeral(e)) {
 | 
					            if (a.is_numeral(e)) {
 | 
				
			||||||
| 
						 | 
					@ -1115,6 +1116,16 @@ namespace pdr {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            if (m_test_for_utvpi) {
 | 
				
			||||||
 | 
					                if (a.is_mul(e, e1, e2)) {
 | 
				
			||||||
 | 
					                    if (is_minus_one(e1)) {
 | 
				
			||||||
 | 
					                        return is_offset(e2);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (is_minus_one(e2)) {
 | 
				
			||||||
 | 
					                        return is_offset(e1);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return !is_arith_expr(e);
 | 
					            return !is_arith_expr(e);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1140,6 +1151,9 @@ namespace pdr {
 | 
				
			||||||
            if (!a.is_add(lhs, arg1, arg2)) 
 | 
					            if (!a.is_add(lhs, arg1, arg2)) 
 | 
				
			||||||
                return false;    
 | 
					                return false;    
 | 
				
			||||||
            // x
 | 
					            // x
 | 
				
			||||||
 | 
					            if (m_test_for_utvpi) {
 | 
				
			||||||
 | 
					                return is_offset(arg1) && is_offset(arg2);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (is_arith_expr(arg1)) 
 | 
					            if (is_arith_expr(arg1)) 
 | 
				
			||||||
                std::swap(arg1, arg2);
 | 
					                std::swap(arg1, arg2);
 | 
				
			||||||
            if (is_arith_expr(arg1))
 | 
					            if (is_arith_expr(arg1))
 | 
				
			||||||
| 
						 | 
					@ -1209,8 +1223,10 @@ namespace pdr {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        test_diff_logic(ast_manager& m): m(m), a(m), bv(m), m_is_dl(true) {}
 | 
					        test_diff_logic(ast_manager& m): m(m), a(m), bv(m), m_is_dl(true), m_test_for_utvpi(false) {}
 | 
				
			||||||
        
 | 
					       
 | 
				
			||||||
 | 
					        void test_for_utvpi() { m_test_for_utvpi = true; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void operator()(expr* e) {
 | 
					        void operator()(expr* e) {
 | 
				
			||||||
            if (!m_is_dl) {
 | 
					            if (!m_is_dl) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
| 
						 | 
					@ -1248,6 +1264,16 @@ namespace pdr {
 | 
				
			||||||
        return test.is_dl();
 | 
					        return test.is_dl();
 | 
				
			||||||
    }  
 | 
					    }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_utvpi_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) {
 | 
				
			||||||
 | 
					        test_diff_logic test(m);
 | 
				
			||||||
 | 
					        test.test_for_utvpi();
 | 
				
			||||||
 | 
					        expr_fast_mark1 mark;
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < num_fmls; ++i) {
 | 
				
			||||||
 | 
					            quick_for_each_expr(test, mark, fmls[i]);
 | 
				
			||||||
 | 
					        } 
 | 
				
			||||||
 | 
					        return test.is_dl();
 | 
				
			||||||
 | 
					    }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template class rewriter_tpl<pdr::ite_hoister_cfg>;
 | 
					template class rewriter_tpl<pdr::ite_hoister_cfg>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,6 +151,8 @@ namespace pdr {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool is_difference_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls);
 | 
					    bool is_difference_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool is_utvpi_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#include "dl_util.h"
 | 
					#include "dl_util.h"
 | 
				
			||||||
#include "proof_utils.h"
 | 
					#include "proof_utils.h"
 | 
				
			||||||
#include "ast_smt2_pp.h"
 | 
					#include "ast_smt2_pp.h"
 | 
				
			||||||
 | 
					#include "var_subst.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class reduce_hypotheses {
 | 
					class reduce_hypotheses {
 | 
				
			||||||
    typedef obj_hashtable<expr> expr_set;
 | 
					    typedef obj_hashtable<expr> expr_set;
 | 
				
			||||||
| 
						 | 
					@ -517,3 +518,93 @@ void proof_utils::permute_unit_resolution(proof_ref& pr) {
 | 
				
			||||||
    obj_map<proof,proof*> cache;
 | 
					    obj_map<proof,proof*> cache;
 | 
				
			||||||
    ::permute_unit_resolution(refs, cache, pr);
 | 
					    ::permute_unit_resolution(refs, cache, pr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class push_instantiations_up_cl {
 | 
				
			||||||
 | 
					    ast_manager& m;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    push_instantiations_up_cl(ast_manager& m): m(m) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void operator()(proof_ref& p) {
 | 
				
			||||||
 | 
					        expr_ref_vector s0(m);
 | 
				
			||||||
 | 
					        p = push(p, s0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    proof* push(proof* p, expr_ref_vector const& sub) {
 | 
				
			||||||
 | 
					        proof_ref_vector premises(m);
 | 
				
			||||||
 | 
					        expr_ref conclusion(m);
 | 
				
			||||||
 | 
					        svector<std::pair<unsigned, unsigned> >  positions;
 | 
				
			||||||
 | 
					        vector<expr_ref_vector> substs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (m.is_hyper_resolve(p, premises, conclusion, positions, substs)) {
 | 
				
			||||||
 | 
					            for (unsigned i = 0; i < premises.size(); ++i) {
 | 
				
			||||||
 | 
					                compose(substs[i], sub);
 | 
				
			||||||
 | 
					                premises[i] = push(premises[i].get(), substs[i]);
 | 
				
			||||||
 | 
					                substs[i].reset();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            instantiate(sub, conclusion);
 | 
				
			||||||
 | 
					            return 
 | 
				
			||||||
 | 
					                m.mk_hyper_resolve(premises.size(), premises.c_ptr(), conclusion, 
 | 
				
			||||||
 | 
					                                   positions, 
 | 
				
			||||||
 | 
					                                   substs);
 | 
				
			||||||
 | 
					        }        
 | 
				
			||||||
 | 
					        if (sub.empty()) {
 | 
				
			||||||
 | 
					            return p;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (m.is_modus_ponens(p)) {
 | 
				
			||||||
 | 
					            SASSERT(m.get_num_parents(p) == 2);
 | 
				
			||||||
 | 
					            proof* p0 = m.get_parent(p, 0);
 | 
				
			||||||
 | 
					            proof* p1 = m.get_parent(p, 1);
 | 
				
			||||||
 | 
					            if (m.get_fact(p0) == m.get_fact(p)) {
 | 
				
			||||||
 | 
					                return push(p0, sub);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            expr* e1, *e2;
 | 
				
			||||||
 | 
					            if (m.is_rewrite(p1, e1, e2) && 
 | 
				
			||||||
 | 
					                is_quantifier(e1) && is_quantifier(e2) &&
 | 
				
			||||||
 | 
					                to_quantifier(e1)->get_num_decls() == to_quantifier(e2)->get_num_decls()) {
 | 
				
			||||||
 | 
					                expr_ref r1(e1,m), r2(e2,m);
 | 
				
			||||||
 | 
					                instantiate(sub, r1);
 | 
				
			||||||
 | 
					                instantiate(sub, r2);
 | 
				
			||||||
 | 
					                p1 = m.mk_rewrite(r1, r2);
 | 
				
			||||||
 | 
					                return m.mk_modus_ponens(push(p0, sub), p1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        premises.push_back(p);
 | 
				
			||||||
 | 
					        substs.push_back(sub);
 | 
				
			||||||
 | 
					        conclusion = m.get_fact(p);
 | 
				
			||||||
 | 
					        instantiate(sub, conclusion);
 | 
				
			||||||
 | 
					        return m.mk_hyper_resolve(premises.size(), premises.c_ptr(), conclusion, positions, substs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void compose(expr_ref_vector& sub, expr_ref_vector const& s0) {
 | 
				
			||||||
 | 
					        for (unsigned i = 0; i < sub.size(); ++i) {
 | 
				
			||||||
 | 
					            expr_ref e(m);
 | 
				
			||||||
 | 
					            var_subst(m, false)(sub[i].get(), s0.size(), s0.c_ptr(), e);
 | 
				
			||||||
 | 
					            sub[i] = e;            
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void instantiate(expr_ref_vector const& sub, expr_ref& fml) {
 | 
				
			||||||
 | 
					        if (sub.empty()) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!is_forall(fml)) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        quantifier* q = to_quantifier(fml);
 | 
				
			||||||
 | 
					        if (q->get_num_decls() != sub.size()) {
 | 
				
			||||||
 | 
					            TRACE("proof_utils", tout << "quantifier has different number of variables than substitution";
 | 
				
			||||||
 | 
					                  tout << mk_pp(q, m) << "\n";
 | 
				
			||||||
 | 
					                  tout << sub.size() << "\n";);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        var_subst(m, false)(q->get_expr(), sub.size(), sub.c_ptr(), fml);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void proof_utils::push_instantiations_up(proof_ref& pr) {
 | 
				
			||||||
 | 
					    push_instantiations_up_cl push(pr.get_manager());
 | 
				
			||||||
 | 
					    push(pr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,12 @@ public:
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    static void permute_unit_resolution(proof_ref& pr);
 | 
					    static void permute_unit_resolution(proof_ref& pr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					       \brief Push instantiations created in hyper-resolutions up to leaves.
 | 
				
			||||||
 | 
					       This produces a "ground" proof where leaves are annotated by instantiations.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    static void push_instantiations_up(proof_ref& pr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1159,7 +1159,7 @@ namespace smt2 {
 | 
				
			||||||
            m_num_expr_frames++;
 | 
					            m_num_expr_frames++;
 | 
				
			||||||
            unsigned num_vars = parse_sorted_vars();
 | 
					            unsigned num_vars = parse_sorted_vars();
 | 
				
			||||||
            if (num_vars == 0)
 | 
					            if (num_vars == 0)
 | 
				
			||||||
                throw parser_exception("invalied quantifier, list of sorted variables is empty");
 | 
					                throw parser_exception("invalid quantifier, list of sorted variables is empty");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        symbol parse_indexed_identifier_core() {
 | 
					        symbol parse_indexed_identifier_core() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,6 @@ public:
 | 
				
			||||||
    smt_strategic_solver_factory(symbol const & logic):m_logic(logic) {}
 | 
					    smt_strategic_solver_factory(symbol const & logic):m_logic(logic) {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    virtual ~smt_strategic_solver_factory() {}
 | 
					    virtual ~smt_strategic_solver_factory() {}
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    virtual solver * operator()(ast_manager & m, params_ref const & p, bool proofs_enabled, bool models_enabled, bool unsat_core_enabled, symbol const & logic) {
 | 
					    virtual solver * operator()(ast_manager & m, params_ref const & p, bool proofs_enabled, bool models_enabled, bool unsat_core_enabled, symbol const & logic) {
 | 
				
			||||||
        symbol l;
 | 
					        symbol l;
 | 
				
			||||||
        if (m_logic != symbol::null)
 | 
					        if (m_logic != symbol::null)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue