mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-30 19:22:28 +00:00 
			
		
		
		
	Add array plugin support and update bv_eval in ast_sls module
This commit is contained in:
		
							parent
							
								
									1d3891f8d6
								
							
						
					
					
						commit
						f9ec6b45c4
					
				
					 4 changed files with 188 additions and 2 deletions
				
			
		|  | @ -4,6 +4,7 @@ z3_add_component(ast_sls | ||||||
|     sat_ddfw.cpp |     sat_ddfw.cpp | ||||||
|     sls_arith_base.cpp |     sls_arith_base.cpp | ||||||
|     sls_arith_plugin.cpp |     sls_arith_plugin.cpp | ||||||
|  |     sls_array_plugin.cpp | ||||||
|     sls_basic_plugin.cpp |     sls_basic_plugin.cpp | ||||||
|     sls_bv_engine.cpp |     sls_bv_engine.cpp | ||||||
|     sls_bv_eval.cpp |     sls_bv_eval.cpp | ||||||
|  | @ -16,6 +17,7 @@ z3_add_component(ast_sls | ||||||
|     sls_smt_solver.cpp |     sls_smt_solver.cpp | ||||||
|   COMPONENT_DEPENDENCIES |   COMPONENT_DEPENDENCIES | ||||||
|     ast |     ast | ||||||
|  |     euf | ||||||
|     converters |     converters | ||||||
|     normal_forms |     normal_forms | ||||||
| ) | ) | ||||||
|  |  | ||||||
							
								
								
									
										104
									
								
								src/ast/sls/sls_array_plugin.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/ast/sls/sls_array_plugin.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,104 @@ | ||||||
|  | /*++
 | ||||||
|  | Copyright (c) 2020 Microsoft Corporation | ||||||
|  | 
 | ||||||
|  | Module Name: | ||||||
|  | 
 | ||||||
|  |     sls_array_plugin.cpp | ||||||
|  | 
 | ||||||
|  | Abstract: | ||||||
|  | 
 | ||||||
|  |     Theory plugin for arrays local search | ||||||
|  | 
 | ||||||
|  | Author: | ||||||
|  | 
 | ||||||
|  |     Nikolaj Bjorner (nbjorner) 2024-07-06 | ||||||
|  | 
 | ||||||
|  | --*/ | ||||||
|  | 
 | ||||||
|  | #include "ast/sls/sls_array_plugin.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | namespace sls { | ||||||
|  | 
 | ||||||
|  |          | ||||||
|  |     array_plugin::array_plugin(context& ctx): | ||||||
|  |         plugin(ctx), | ||||||
|  |         a(m) | ||||||
|  |     { | ||||||
|  |         m_fid = a.get_family_id(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     bool array_plugin::is_sat() { | ||||||
|  |         euf::egraph g(m); | ||||||
|  |         init_egraph(g); | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void array_plugin::init_kv(euf::egraph& g, kv& kv) { | ||||||
|  |         for (auto n : g.nodes()) { | ||||||
|  |             if (!n->is_root() || !a.is_array(n->get_expr())) | ||||||
|  |                 continue; | ||||||
|  |             kv.insert(n, obj_map<euf::enode, euf::enode*>()); | ||||||
|  |             for (auto p : euf::enode_parents(n)) { | ||||||
|  |                 if (!a.is_select(p->get_expr())) | ||||||
|  |                     continue; | ||||||
|  |                 SASSERT(n->num_args() == 2); | ||||||
|  |                 if (p->get_arg(0)->get_root() != n->get_root()) | ||||||
|  |                     continue; | ||||||
|  |                 auto idx = n->get_arg(1)->get_root(); | ||||||
|  |                 auto val = p->get_root(); | ||||||
|  |                 kv[n].insert(idx, val); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void array_plugin::saturate_store(euf::egraph& g, kv& kv) { | ||||||
|  |         for (auto n : g.nodes()) { | ||||||
|  |             if (!a.is_store(n->get_expr())) | ||||||
|  |                 continue; | ||||||
|  |             SASSERT(n->num_args() == 3); | ||||||
|  |             auto idx = n->get_arg(1)->get_root(); | ||||||
|  |             auto val = n->get_arg(2)->get_root(); | ||||||
|  |             auto arr = n->get_arg(0)->get_root(); | ||||||
|  | #if 0 | ||||||
|  |             auto it = kv.find(arr); | ||||||
|  |             if (it == kv.end()) | ||||||
|  |                 continue; | ||||||
|  |             auto it2 = it->get_value().find(idx); | ||||||
|  |             if (it2 == nullptr) | ||||||
|  |                 continue; | ||||||
|  |             g.merge(val, it2->get_value(), nullptr); | ||||||
|  | #endif | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void array_plugin::init_egraph(euf::egraph& g) { | ||||||
|  |         ptr_vector<euf::enode> args; | ||||||
|  |         for (auto t : ctx.subterms()) { | ||||||
|  |             args.reset(); | ||||||
|  |             if (is_app(t)) { | ||||||
|  |                 for (auto* arg : *to_app(t)) { | ||||||
|  |                     args.push_back(g.find(arg)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             auto n = g.mk(t, 0, args.size(), args.data()); | ||||||
|  |             if (a.is_array(t)) | ||||||
|  |                 continue; | ||||||
|  |             auto v = ctx.get_value(t); | ||||||
|  |             auto n2 = g.mk(v, 0, 0, nullptr); | ||||||
|  |             g.merge(n, n2, nullptr); | ||||||
|  |         } | ||||||
|  |         for (auto lit : ctx.root_literals()) { | ||||||
|  |             if (!ctx.is_true(lit)) | ||||||
|  |                 continue; | ||||||
|  |             auto e = ctx.atom(lit.var()); | ||||||
|  |             expr* x, * y; | ||||||
|  |             if (e && m.is_eq(e, x, y)) | ||||||
|  |                 g.merge(g.find(x), g.find(y), nullptr); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										56
									
								
								src/ast/sls/sls_array_plugin.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/ast/sls/sls_array_plugin.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | ||||||
|  | /*++
 | ||||||
|  | Copyright (c) 2020 Microsoft Corporation | ||||||
|  | 
 | ||||||
|  | Module Name: | ||||||
|  | 
 | ||||||
|  |     sls_array_plugin.h | ||||||
|  | 
 | ||||||
|  | Abstract: | ||||||
|  | 
 | ||||||
|  |     Theory plugin for arrays local search | ||||||
|  | 
 | ||||||
|  | Author: | ||||||
|  | 
 | ||||||
|  |     Nikolaj Bjorner (nbjorner) 2024-07-06 | ||||||
|  | 
 | ||||||
|  | --*/ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "ast/sls/sls_context.h" | ||||||
|  | #include "ast/array_decl_plugin.h" | ||||||
|  | #include "ast/euf/euf_egraph.h" | ||||||
|  | 
 | ||||||
|  | namespace sls { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     class array_plugin : public plugin { | ||||||
|  |         array_util     a; | ||||||
|  | 
 | ||||||
|  |         typedef obj_map<euf::enode, obj_map<euf::enode, euf::enode*>> kv; | ||||||
|  |         void init_egraph(euf::egraph& g); | ||||||
|  |         void init_kv(euf::egraph& g, kv& kv); | ||||||
|  |         void saturate_store(euf::egraph& g, kv& kv); | ||||||
|  |          | ||||||
|  |     public: | ||||||
|  |         array_plugin(context& ctx); | ||||||
|  |         ~array_plugin() override {} | ||||||
|  |         void register_term(expr* e) override { } | ||||||
|  |         expr_ref get_value(expr* e) override { return expr_ref(m); } | ||||||
|  |         void initialize() override {} | ||||||
|  |         void propagate_literal(sat::literal lit) override {} | ||||||
|  |         bool propagate() override { return false; } | ||||||
|  |         bool repair_down(app* e) override { return false; } | ||||||
|  |         void repair_up(app* e) override {} | ||||||
|  |         void repair_literal(sat::literal lit) override {} | ||||||
|  |         bool is_sat() override; | ||||||
|  | 
 | ||||||
|  |         void on_rescale() override {} | ||||||
|  |         void on_restart() override {} | ||||||
|  |         std::ostream& display(std::ostream& out) const override { return out; } | ||||||
|  |         void mk_model(model& mdl) override {} | ||||||
|  |         bool set_value(expr* e, expr* v) override { return false; } | ||||||
|  |         void collect_statistics(statistics& st) const override {} | ||||||
|  |         void reset_statistics() override {} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -881,6 +881,7 @@ namespace sls { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool bv_eval::try_repair_eq_lookahead(app* e) { |     bool bv_eval::try_repair_eq_lookahead(app* e) { | ||||||
|  |         return false; | ||||||
|         auto is_true = bval0(e); |         auto is_true = bval0(e); | ||||||
|         if (!is_true) |         if (!is_true) | ||||||
|             return false; |             return false; | ||||||
|  | @ -913,6 +914,27 @@ namespace sls { | ||||||
| 
 | 
 | ||||||
|     bool bv_eval::try_repair_eq(bool is_true, bvval& a, bvval const& b) { |     bool bv_eval::try_repair_eq(bool is_true, bvval& a, bvval const& b) { | ||||||
|         if (is_true) { |         if (is_true) { | ||||||
|  | #if 0 | ||||||
|  |             if (bv.is_bv_add(t)) { | ||||||
|  |                 bvval tmp(b); | ||||||
|  |                 unsigned start = m_rand(); | ||||||
|  |                 unsigned sz = to_app(t)->get_num_args(); | ||||||
|  |                 for (unsigned i = 0; i < sz; ++i) { | ||||||
|  |                     unsigned j = (start + i) % sz; | ||||||
|  |                     for (unsigned k = 0; k < sz; ++k) { | ||||||
|  |                         if (k == j) | ||||||
|  |                             continue; | ||||||
|  |                         auto& c = wval(to_app(t)->get_arg(k)); | ||||||
|  |                         set_sub(tmp, tmp, c.bits()); | ||||||
|  |                     } | ||||||
|  |                      | ||||||
|  |                     auto& c = wval(to_app(t)->get_arg(j)); | ||||||
|  |                     verbose_stream() << "TRY " << c << " := " << tmp << "\n"; | ||||||
|  |                      | ||||||
|  | 
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | #endif | ||||||
|             if (m_rand(20) != 0)  |             if (m_rand(20) != 0)  | ||||||
|                 if (a.try_set(b.bits())) |                 if (a.try_set(b.bits())) | ||||||
|                     return true; |                     return true; | ||||||
|  | @ -1931,8 +1953,10 @@ namespace sls { | ||||||
|             m_tmp.set(i + lo, e.get(i)); |             m_tmp.set(i + lo, e.get(i)); | ||||||
|         m_tmp.set_bw(a.bw); |         m_tmp.set_bw(a.bw); | ||||||
|         // verbose_stream() << a << " := " << m_tmp << "\n";
 |         // verbose_stream() << a << " := " << m_tmp << "\n";
 | ||||||
|         if (m_rand(5) != 0 && a.try_set(m_tmp)) |         if (m_rand(20) != 0 && a.try_set(m_tmp)) | ||||||
|             return true; |             return true; | ||||||
|  |         if (m_rand(20) != 0) | ||||||
|  |             return false; | ||||||
|         bool ok = a.set_random(m_rand); |         bool ok = a.set_random(m_rand); | ||||||
|         // verbose_stream() << "set random " << ok << " " << a << "\n";
 |         // verbose_stream() << "set random " << ok << " " << a << "\n";
 | ||||||
|         return ok; |         return ok; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue