mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 13:29:11 +00:00 
			
		
		
		
	throttle ackerman on arrays
This commit is contained in:
		
							parent
							
								
									a20b577b2f
								
							
						
					
					
						commit
						84f514a4f4
					
				
					 8 changed files with 54 additions and 6 deletions
				
			
		| 
						 | 
					@ -189,10 +189,10 @@ namespace euf {
 | 
				
			||||||
            add_th_diseq(id, v1, v2, n->get_expr());
 | 
					            add_th_diseq(id, v1, v2, n->get_expr());
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (auto p : euf::enode_th_vars(r1)) {
 | 
					        for (auto const& p : euf::enode_th_vars(r1)) {
 | 
				
			||||||
            if (!th_propagates_diseqs(p.get_id()))
 | 
					            if (!th_propagates_diseqs(p.get_id()))
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            for (auto q : euf::enode_th_vars(r2))
 | 
					            for (auto const& q : euf::enode_th_vars(r2))
 | 
				
			||||||
                if (p.get_id() == q.get_id()) 
 | 
					                if (p.get_id() == q.get_id()) 
 | 
				
			||||||
                    add_th_diseq(p.get_id(), p.get_var(), q.get_var(), n->get_expr());
 | 
					                    add_th_diseq(p.get_id(), p.get_var(), q.get_var(), n->get_expr());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -506,7 +506,7 @@ namespace euf {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void egraph::merge_th_eq(enode* n, enode* root) {
 | 
					    void egraph::merge_th_eq(enode* n, enode* root) {
 | 
				
			||||||
        SASSERT(n != root);
 | 
					        SASSERT(n != root);
 | 
				
			||||||
        for (auto iv : enode_th_vars(n)) {
 | 
					        for (auto const& iv : enode_th_vars(n)) {
 | 
				
			||||||
            theory_id id = iv.get_id();
 | 
					            theory_id id = iv.get_id();
 | 
				
			||||||
            theory_var v = root->get_th_var(id);
 | 
					            theory_var v = root->get_th_var(id);
 | 
				
			||||||
            if (v == null_theory_var) {                
 | 
					            if (v == null_theory_var) {                
 | 
				
			||||||
| 
						 | 
					@ -789,7 +789,7 @@ namespace euf {
 | 
				
			||||||
            out << "[b" << n->bool_var() << " := " << (n->value() == l_true ? "T":"F") << (n->merge_tf()?"":" no merge") << "] ";
 | 
					            out << "[b" << n->bool_var() << " := " << (n->value() == l_true ? "T":"F") << (n->merge_tf()?"":" no merge") << "] ";
 | 
				
			||||||
        if (n->has_th_vars()) {
 | 
					        if (n->has_th_vars()) {
 | 
				
			||||||
            out << "[t";
 | 
					            out << "[t";
 | 
				
			||||||
            for (auto v : enode_th_vars(n))
 | 
					            for (auto const& v : enode_th_vars(n))
 | 
				
			||||||
                out << " " << v.get_id() << ":" << v.get_var();
 | 
					                out << " " << v.get_id() << ":" << v.get_var();
 | 
				
			||||||
            out << "] ";
 | 
					            out << "] ";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -445,6 +445,7 @@ namespace arith {
 | 
				
			||||||
        bool is_shared(theory_var v) const override;
 | 
					        bool is_shared(theory_var v) const override;
 | 
				
			||||||
        lbool get_phase(bool_var v) override;
 | 
					        lbool get_phase(bool_var v) override;
 | 
				
			||||||
        bool include_func_interp(func_decl* f) const override;
 | 
					        bool include_func_interp(func_decl* f) const override;
 | 
				
			||||||
 | 
					        bool enable_ackerman_axioms(euf::enode* n) const override { return !a.is_add(n->get_expr()); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // bounds and equality propagation callbacks
 | 
					        // bounds and equality propagation callbacks
 | 
				
			||||||
        lp::lar_solver& lp() { return *m_solver; }
 | 
					        lp::lar_solver& lp() { return *m_solver; }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -261,6 +261,7 @@ namespace array {
 | 
				
			||||||
        bool is_shared(theory_var v) const override;
 | 
					        bool is_shared(theory_var v) const override;
 | 
				
			||||||
        bool enable_self_propagate() const override { return true; }
 | 
					        bool enable_self_propagate() const override { return true; }
 | 
				
			||||||
        void relevant_eh(euf::enode* n) override;
 | 
					        void relevant_eh(euf::enode* n) override;
 | 
				
			||||||
 | 
					        bool enable_ackerman_axioms(euf::enode* n) const override { return !a.is_array(n->get_sort()); }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
        void merge_eh(theory_var, theory_var, theory_var v1, theory_var v2);
 | 
					        void merge_eh(theory_var, theory_var, theory_var v1, theory_var v2);
 | 
				
			||||||
        void after_merge_eh(theory_var r1, theory_var r2, theory_var v1, theory_var v2) {}
 | 
					        void after_merge_eh(theory_var r1, theory_var r2, theory_var v1, theory_var v2) {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,14 +99,38 @@ namespace euf {
 | 
				
			||||||
        m_tmp_inference->init(m_tmp_inference);
 | 
					        m_tmp_inference->init(m_tmp_inference);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool ackerman::enable_cc(app* a, app* b) {
 | 
				
			||||||
 | 
					        if (!s.enable_ackerman_axioms(a))
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        if (!s.enable_ackerman_axioms(b))
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        for (expr* arg : *a)
 | 
				
			||||||
 | 
					            if (!s.enable_ackerman_axioms(arg))
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					        for (expr* arg : *b)
 | 
				
			||||||
 | 
					            if (!s.enable_ackerman_axioms(arg))
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool ackerman::enable_eq(expr* a, expr* b, expr* c) {
 | 
				
			||||||
 | 
					        return s.enable_ackerman_axioms(a) && 
 | 
				
			||||||
 | 
					            s.enable_ackerman_axioms(b) && 
 | 
				
			||||||
 | 
					            s.enable_ackerman_axioms(c);           
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ackerman::cg_conflict_eh(expr * n1, expr * n2) {
 | 
					    void ackerman::cg_conflict_eh(expr * n1, expr * n2) {
 | 
				
			||||||
        if (!is_app(n1) || !is_app(n2))
 | 
					        if (!is_app(n1) || !is_app(n2))
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					        if (!s.enable_ackerman_axioms(n1))
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        SASSERT(!s.m_drating);
 | 
					        SASSERT(!s.m_drating);
 | 
				
			||||||
        app* a = to_app(n1);
 | 
					        app* a = to_app(n1);
 | 
				
			||||||
        app* b = to_app(n2);
 | 
					        app* b = to_app(n2);
 | 
				
			||||||
        if (a->get_decl() != b->get_decl() || a->get_num_args() != b->get_num_args())
 | 
					        if (a->get_decl() != b->get_decl() || a->get_num_args() != b->get_num_args())
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					        if (!enable_cc(a, b))
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        TRACE("ack", tout << "conflict eh: " << mk_pp(a, m) << " == " << mk_pp(b, m) << "\n";);
 | 
					        TRACE("ack", tout << "conflict eh: " << mk_pp(a, m) << " == " << mk_pp(b, m) << "\n";);
 | 
				
			||||||
        insert(a, b);
 | 
					        insert(a, b);
 | 
				
			||||||
        gc();
 | 
					        gc();
 | 
				
			||||||
| 
						 | 
					@ -117,6 +141,8 @@ namespace euf {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        if (s.m_drating)
 | 
					        if (s.m_drating)
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					        if (!enable_eq(a, b, c))
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        TRACE("ack", tout << mk_pp(a, m) << " " << mk_pp(b, m) << " " << mk_pp(c, m) << "\n";);
 | 
					        TRACE("ack", tout << mk_pp(a, m) << " " << mk_pp(b, m) << " " << mk_pp(c, m) << "\n";);
 | 
				
			||||||
        insert(a, b, c);
 | 
					        insert(a, b, c);
 | 
				
			||||||
        gc();
 | 
					        gc();
 | 
				
			||||||
| 
						 | 
					@ -128,6 +154,8 @@ namespace euf {
 | 
				
			||||||
        TRACE("ack", tout << "used cc: " << mk_pp(a, m) << " == " << mk_pp(b, m) << "\n";);
 | 
					        TRACE("ack", tout << "used cc: " << mk_pp(a, m) << " == " << mk_pp(b, m) << "\n";);
 | 
				
			||||||
        SASSERT(a->get_decl() == b->get_decl());
 | 
					        SASSERT(a->get_decl() == b->get_decl());
 | 
				
			||||||
        SASSERT(a->get_num_args() == b->get_num_args());
 | 
					        SASSERT(a->get_num_args() == b->get_num_args());
 | 
				
			||||||
 | 
					        if (!enable_cc(a, b))
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        insert(a, b);
 | 
					        insert(a, b);
 | 
				
			||||||
        gc();
 | 
					        gc();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,9 @@ namespace euf {
 | 
				
			||||||
        void add_cc(expr* a, expr* b);
 | 
					        void add_cc(expr* a, expr* b);
 | 
				
			||||||
        void add_eq(expr* a, expr* b, expr* c);        
 | 
					        void add_eq(expr* a, expr* b, expr* c);        
 | 
				
			||||||
        void gc();
 | 
					        void gc();
 | 
				
			||||||
 | 
					        bool enable_cc(app* a, app* b);
 | 
				
			||||||
 | 
					        bool enable_eq(expr* a, expr* b, expr* c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        ackerman(solver& s, ast_manager& m);
 | 
					        ackerman(solver& s, ast_manager& m);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -751,6 +751,18 @@ namespace euf {
 | 
				
			||||||
        }       
 | 
					        }       
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool solver::enable_ackerman_axioms(expr* e) const {
 | 
				
			||||||
 | 
					        euf::enode* n = get_enode(e);
 | 
				
			||||||
 | 
					        if (!n)
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        for (auto const& thv : enode_th_vars(n)) {
 | 
				
			||||||
 | 
					            auto* th = m_id2solver.get(thv.get_id(), nullptr);
 | 
				
			||||||
 | 
					            if (th && !th->enable_ackerman_axioms(n))
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void solver::pre_simplify() {
 | 
					    void solver::pre_simplify() {
 | 
				
			||||||
        for (auto* e : m_solvers)
 | 
					        for (auto* e : m_solvers)
 | 
				
			||||||
            e->pre_simplify();
 | 
					            e->pre_simplify();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -372,6 +372,7 @@ namespace euf {
 | 
				
			||||||
        th_rewriter& get_rewriter() { return m_rewriter; }
 | 
					        th_rewriter& get_rewriter() { return m_rewriter; }
 | 
				
			||||||
        void rewrite(expr_ref& e) { m_rewriter(e); }
 | 
					        void rewrite(expr_ref& e) { m_rewriter(e); }
 | 
				
			||||||
        bool is_shared(euf::enode* n) const;
 | 
					        bool is_shared(euf::enode* n) const;
 | 
				
			||||||
 | 
					        bool enable_ackerman_axioms(expr* n) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // relevancy
 | 
					        // relevancy
 | 
				
			||||||
        bool m_relevancy_enabled = true;
 | 
					        bool m_relevancy_enabled = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,6 +111,8 @@ namespace euf {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual void new_diseq_eh(euf::th_eq const& eq) {}
 | 
					        virtual void new_diseq_eh(euf::th_eq const& eq) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual bool enable_ackerman_axioms(euf::enode* n) const { return true; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual void relevant_eh(euf::enode* n) {}
 | 
					        virtual void relevant_eh(euf::enode* n) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue