mirror of
				https://github.com/Z3Prover/z3
				synced 2025-10-31 19:52:29 +00:00 
			
		
		
		
	parameters, local search, arithmetic propagation
add get-info parameters to print current parameters in scope of solver add interface to set values in int-blaster settle on propagation for arithmetic assignments
This commit is contained in:
		
							parent
							
								
									3456af425e
								
							
						
					
					
						commit
						edc3e0b05d
					
				
					 14 changed files with 124 additions and 28 deletions
				
			
		|  | @ -433,7 +433,7 @@ class set_option_cmd : public set_get_option_cmd { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void set_param(cmd_context & ctx, char const * value) { |     void set_param(cmd_context & ctx, char const * value) { | ||||||
|         try { |         try {             | ||||||
|             gparams::set(m_option, value); |             gparams::set(m_option, value); | ||||||
|             env_params::updt_params(); |             env_params::updt_params(); | ||||||
|             ctx.global_params_updated(); |             ctx.global_params_updated(); | ||||||
|  | @ -693,7 +693,7 @@ public: | ||||||
|         m_rlimit(":rlimit") { |         m_rlimit(":rlimit") { | ||||||
|     } |     } | ||||||
|     char const * get_usage() const override { return "<keyword>"; } |     char const * get_usage() const override { return "<keyword>"; } | ||||||
|     char const * get_descr(cmd_context & ctx) const override { return "get information."; } |     char const * get_descr(cmd_context & ctx) const override { return "(get-info :?) for options."; } | ||||||
|     unsigned get_arity() const override { return 1; } |     unsigned get_arity() const override { return 1; } | ||||||
|     cmd_arg_kind next_arg_kind(cmd_context & ctx) const override { return CPK_KEYWORD; } |     cmd_arg_kind next_arg_kind(cmd_context & ctx) const override { return CPK_KEYWORD; } | ||||||
|     void set_next_arg(cmd_context & ctx, symbol const & opt) override { |     void set_next_arg(cmd_context & ctx, symbol const & opt) override { | ||||||
|  | @ -707,7 +707,7 @@ public: | ||||||
|             ctx.regular_stream() << "(:name \"Z3\")" << std::endl; |             ctx.regular_stream() << "(:name \"Z3\")" << std::endl; | ||||||
|         } |         } | ||||||
|         else if (opt == m_authors) { |         else if (opt == m_authors) { | ||||||
|             ctx.regular_stream() << "(:authors \"Leonardo de Moura, Nikolaj Bjorner and Christoph Wintersteiger\")" << std::endl; |             ctx.regular_stream() << "(:authors \"Leonardo de Moura, Nikolaj Bjorner, Lev Nachmanson and Christoph Wintersteiger\")" << std::endl; | ||||||
|         } |         } | ||||||
|         else if (opt == m_version) { |         else if (opt == m_version) { | ||||||
|             ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER |             ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER | ||||||
|  | @ -731,8 +731,20 @@ public: | ||||||
|         else if (opt == m_assertion_stack_levels) { |         else if (opt == m_assertion_stack_levels) { | ||||||
|             ctx.regular_stream() << "(:assertion-stack-levels " << ctx.num_scopes() << ")" << std::endl; |             ctx.regular_stream() << "(:assertion-stack-levels " << ctx.num_scopes() << ")" << std::endl; | ||||||
|         } |         } | ||||||
|  |         else if (opt == symbol(":parameters")) { | ||||||
|  |             ctx.display_parameters(ctx.regular_stream()); | ||||||
|  |         } | ||||||
|         else { |         else { | ||||||
|             ctx.print_unsupported(opt, m_line, m_pos); |             if (opt != symbol(":?")) | ||||||
|  |                ctx.print_unsupported(opt, m_line, m_pos); | ||||||
|  |             ctx.regular_stream() << "; (get-info :reason-unknown)\n"; | ||||||
|  |             ctx.regular_stream() << "; (get-info :status)\n"; | ||||||
|  |             ctx.regular_stream() << "; (get-info :version)\n"; | ||||||
|  |             ctx.regular_stream() << "; (get-info :authors)\n"; | ||||||
|  |             ctx.regular_stream() << "; (get-info :error-behavior)\n"; | ||||||
|  |             ctx.regular_stream() << "; (get-info :parameters)\n"; | ||||||
|  |             ctx.regular_stream() << "; (get-info :rlimit)\n"; | ||||||
|  |             ctx.regular_stream() << "; (get-info :assertion-stack-levels)\n"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -1902,6 +1902,11 @@ void cmd_context::display_model(model_ref& mdl) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void cmd_context::display_parameters(std::ostream& out) { | ||||||
|  |     if (m_solver) | ||||||
|  |         m_solver->display_parameters(out); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void cmd_context::add_declared_functions(model& mdl) { | void cmd_context::add_declared_functions(model& mdl) { | ||||||
|     model_params p; |     model_params p; | ||||||
|     if (!p.user_functions()) |     if (!p.user_functions()) | ||||||
|  |  | ||||||
|  | @ -506,6 +506,7 @@ public: | ||||||
|     void display_assertions(); |     void display_assertions(); | ||||||
|     void display_statistics(bool show_total_time = false, double total_time = 0.0); |     void display_statistics(bool show_total_time = false, double total_time = 0.0); | ||||||
|     void display_dimacs(); |     void display_dimacs(); | ||||||
|  |     void display_parameters(std::ostream& out); | ||||||
|     void reset(bool finalize = false); |     void reset(bool finalize = false); | ||||||
|     void assert_expr(expr * t); |     void assert_expr(expr * t); | ||||||
|     void assert_expr(symbol const & name, expr * t); |     void assert_expr(symbol const & name, expr * t); | ||||||
|  |  | ||||||
|  | @ -2927,6 +2927,22 @@ namespace smt { | ||||||
|         push_trail(push_back_vector(m_values)); |         push_trail(push_back_vector(m_values)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void context::set_sls_value(expr* var, expr* value) { | ||||||
|  |         expr_ref _var(var, m); | ||||||
|  |         expr_ref _valueu(value, m); | ||||||
|  |         if (!e_internalized(var)) | ||||||
|  |             return; | ||||||
|  |         enode* n = get_enode(var); | ||||||
|  |         theory_var_list* l = n->get_th_var_list(); | ||||||
|  |         while (l) { | ||||||
|  |             theory_id tid = l->get_id(); | ||||||
|  |             auto* p = m_theories.get_plugin(tid); | ||||||
|  |             if (p) | ||||||
|  |                 p->initialize_value(var, value); | ||||||
|  |             l = l->get_next(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     void context::initialize_value(expr* var, expr* value) { |     void context::initialize_value(expr* var, expr* value) { | ||||||
|         IF_VERBOSE(10, verbose_stream() << "initialize " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); |         IF_VERBOSE(10, verbose_stream() << "initialize " << mk_pp(var, m) << " := " << mk_pp(value, m) << "\n"); | ||||||
|         sort* s = var->get_sort(); |         sort* s = var->get_sort(); | ||||||
|  |  | ||||||
|  | @ -1812,6 +1812,8 @@ namespace smt { | ||||||
| 
 | 
 | ||||||
|         void user_propagate_initialize_value(expr* var, expr* value); |         void user_propagate_initialize_value(expr* var, expr* value); | ||||||
| 
 | 
 | ||||||
|  |         void set_sls_value(expr* var, expr* value); | ||||||
|  | 
 | ||||||
|         bool watches_fixed(enode* n) const; |         bool watches_fixed(enode* n) const; | ||||||
| 
 | 
 | ||||||
|         bool has_split_candidate(bool_var& var, bool& is_pos); |         bool has_split_candidate(bool_var& var, bool& is_pos); | ||||||
|  |  | ||||||
|  | @ -187,5 +187,33 @@ namespace smt { | ||||||
|         return alloc(expr_wrapper_proc, m_factory->mk_num_value(r, bv.get_bv_size(e))); |         return alloc(expr_wrapper_proc, m_factory->mk_num_value(r, bv.get_bv_size(e))); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void theory_intblast::initialize_value(expr* var, expr* value) { | ||||||
|  |         auto avar = expr_ref(m_translator.translated(var), m); | ||||||
|  |         if (!avar) | ||||||
|  |             return; | ||||||
|  |         rational r; | ||||||
|  |         if (!bv.is_numeral(value, r)) | ||||||
|  |             return; | ||||||
|  |         auto aval = expr_ref(a.mk_numeral(r, true), m); | ||||||
|  |         ctx.set_sls_value(avar, aval); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool theory_intblast::get_value(enode* n, expr_ref& r) { | ||||||
|  |         auto avar = expr_ref(m_translator.translated(n->get_expr()), m); | ||||||
|  |         if (!avar) | ||||||
|  |             return false; | ||||||
|  |         if (!ctx.e_internalized(avar)) | ||||||
|  |             return false; | ||||||
|  |         enode* n2 = ctx.get_enode(avar); | ||||||
|  |         auto has_value = ctx.get_value(n2, r); | ||||||
|  |         if (!has_value) | ||||||
|  |             return false; | ||||||
|  |         rational val; | ||||||
|  |         if (!a.is_numeral(r, val)) | ||||||
|  |             return false; | ||||||
|  |         r = bv.mk_numeral(val, bv.get_bv_size(n->get_expr())); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -66,6 +66,8 @@ namespace smt { | ||||||
|         model_value_proc* mk_value(enode* n, model_generator& m) override; |         model_value_proc* mk_value(enode* n, model_generator& m) override; | ||||||
|         void new_eq_eh(theory_var v1, theory_var v2) override {} |         void new_eq_eh(theory_var v1, theory_var v2) override {} | ||||||
|         void new_diseq_eh(theory_var v1, theory_var v2) override {} |         void new_diseq_eh(theory_var v1, theory_var v2) override {} | ||||||
|  |         void initialize_value(expr* var, expr* value) override; | ||||||
|  |         bool get_value(enode* n, expr_ref& r) override; | ||||||
| 
 | 
 | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2411,6 +2411,7 @@ public: | ||||||
|                            ps.size(), ps.data()); |                            ps.size(), ps.data()); | ||||||
|             } |             } | ||||||
|             ctx().mk_clause(m_core2.size(), m_core2.data(), js, CLS_TH_LEMMA_RELEVANT, nullptr); |             ctx().mk_clause(m_core2.size(), m_core2.data(), js, CLS_TH_LEMMA_RELEVANT, nullptr); | ||||||
|  |             ctx().mk_clause(m_core2.size(), m_core2.data(), js, CLS_TH_LEMMA_LEARNED, nullptr); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             ctx().assign( |             ctx().assign( | ||||||
|  | @ -2465,12 +2466,12 @@ public: | ||||||
|         bool is_int; |         bool is_int; | ||||||
|         VERIFY(a.is_band(n, sz, _x, _y) || a.is_shl(n, sz, _x, _y) || a.is_ashr(n, sz, _x, _y) || a.is_lshr(n, sz, _x, _y)); |         VERIFY(a.is_band(n, sz, _x, _y) || a.is_shl(n, sz, _x, _y) || a.is_ashr(n, sz, _x, _y) || a.is_lshr(n, sz, _x, _y)); | ||||||
|         if (!get_value(ctx().get_enode(_x), vx) || !get_value(ctx().get_enode(_y), vy) || !get_value(ctx().get_enode(n), vn)) { |         if (!get_value(ctx().get_enode(_x), vx) || !get_value(ctx().get_enode(_y), vy) || !get_value(ctx().get_enode(n), vn)) { | ||||||
|             IF_VERBOSE(2, verbose_stream() << "could not get value of " << mk_pp(n, m) << "\n"); |             IF_VERBOSE(4, verbose_stream() << "could not get value of " << mk_pp(n, m) << "\n"); | ||||||
|             found_unsupported(n); |             found_unsupported(n); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         if (!a.is_numeral(vn, valn, is_int) || !is_int || !a.is_numeral(vx, valx, is_int) || !is_int || !a.is_numeral(vy, valy, is_int) || !is_int) { |         if (!a.is_numeral(vn, valn, is_int) || !is_int || !a.is_numeral(vx, valx, is_int) || !is_int || !a.is_numeral(vy, valy, is_int) || !is_int) { | ||||||
|             IF_VERBOSE(2, verbose_stream() << "could not get value of " << mk_pp(n, m) << "\n"); |             IF_VERBOSE(4, verbose_stream() << "could not get value of " << mk_pp(n, m) << "\n"); | ||||||
|             found_unsupported(n); |             found_unsupported(n); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  | @ -2489,7 +2490,7 @@ public: | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         if (a.is_band(n)) { |         if (a.is_band(n)) { | ||||||
|             IF_VERBOSE(2, verbose_stream() << "band: " << mk_bounded_pp(n, m) << " " << valn << " := " << valx << "&" << valy << "\n"); |             IF_VERBOSE(4, verbose_stream() << "band: " << mk_bounded_pp(n, m) << " " << valn << " := " << valx << "&" << valy << "\n"); | ||||||
|             for (unsigned i = 0; i < sz; ++i) { |             for (unsigned i = 0; i < sz; ++i) { | ||||||
|                 bool xb = valx.get_bit(i); |                 bool xb = valx.get_bit(i); | ||||||
|                 bool yb = valy.get_bit(i); |                 bool yb = valy.get_bit(i); | ||||||
|  | @ -2514,7 +2515,7 @@ public: | ||||||
|             if (ctx().get_assignment(eq) == l_true) |             if (ctx().get_assignment(eq) == l_true) | ||||||
|                 return true;             |                 return true;             | ||||||
|             ctx().mk_th_axiom(get_id(), ~th.mk_eq(y, a.mk_int(k), false), eq); |             ctx().mk_th_axiom(get_id(), ~th.mk_eq(y, a.mk_int(k), false), eq); | ||||||
|             IF_VERBOSE(2, verbose_stream() << "shl: " << mk_bounded_pp(n, m) << " " << valn << " := " << valx << " << " << valy << "\n"); |             IF_VERBOSE(4, verbose_stream() << "shl: " << mk_bounded_pp(n, m) << " " << valn << " := " << valx << " << " << valy << "\n"); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         if (a.is_lshr(n)) { |         if (a.is_lshr(n)) { | ||||||
|  | @ -2526,7 +2527,7 @@ public: | ||||||
|             if (ctx().get_assignment(eq) == l_true) |             if (ctx().get_assignment(eq) == l_true) | ||||||
|                 return true;             |                 return true;             | ||||||
|             ctx().mk_th_axiom(get_id(), ~th.mk_eq(y, a.mk_int(k), false), eq); |             ctx().mk_th_axiom(get_id(), ~th.mk_eq(y, a.mk_int(k), false), eq); | ||||||
|             IF_VERBOSE(2, verbose_stream() << "lshr: " << mk_bounded_pp(n, m) << " " << valn << " := " << valx << " >>l " << valy << "\n"); |             IF_VERBOSE(4, verbose_stream() << "lshr: " << mk_bounded_pp(n, m) << " " << valn << " := " << valx << " >>l " << valy << "\n"); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         if (a.is_ashr(n)) { |         if (a.is_ashr(n)) { | ||||||
|  | @ -3555,28 +3556,19 @@ public: | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool get_value(enode* n, rational& val) { |     bool get_value(enode* n, rational& val) { | ||||||
|         theory_var v = n->get_th_var(get_id());             |         theory_var v = n->get_th_var(get_id());     | ||||||
|         if (!is_registered_var(v)) return false; |         if (!is_registered_var(v))  | ||||||
|         lpvar vi = get_lpvar(v); |  | ||||||
|         if (lp().has_value(vi, val)) { |  | ||||||
|             TRACE("arith", tout << expr_ref(n->get_expr(), m) << " := " << val << "\n";); |  | ||||||
|             if (is_int(n) && !val.is_int()) return false; |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             return false; |             return false; | ||||||
|         } |         lpvar vi = get_lpvar(v); | ||||||
|  |         return lp().has_value(vi, val) && (!is_int(n) || val.is_int()); | ||||||
|     }     |     }     | ||||||
| 
 | 
 | ||||||
|     bool get_value(enode* n, expr_ref& r) { |     bool get_value(enode* n, expr_ref& r) { | ||||||
|         rational val; |         rational val; | ||||||
|         if (get_value(n, val)) { |         if (!get_value(n, val)) | ||||||
|             r = a.mk_numeral(val, is_int(n)); |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             return false; |             return false; | ||||||
|         } |         r = a.mk_numeral(val, is_int(n)); | ||||||
|  |         return true; | ||||||
|     }     |     }     | ||||||
| 
 | 
 | ||||||
|     bool include_func_interp(func_decl* f) { |     bool include_func_interp(func_decl* f) { | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ namespace smt { | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     void theory_sls::set_value(expr* t, expr* v) { |     void theory_sls::set_value(expr* t, expr* v) { | ||||||
|         ctx.user_propagate_initialize_value(t, v); |         ctx.set_sls_value(t, v); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     void theory_sls::force_phase(sat::literal lit) { |     void theory_sls::force_phase(sat::literal lit) { | ||||||
|  |  | ||||||
|  | @ -225,6 +225,18 @@ void solver::collect_param_descrs(param_descrs & r) { | ||||||
|     insert_ctrl_c(r); |     insert_ctrl_c(r); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::ostream& solver::display_parameters(std::ostream& out) { | ||||||
|  |     //
 | ||||||
|  |     // this is a partial patch. 
 | ||||||
|  |     // The modules should be present in 'p'.
 | ||||||
|  |     // if p has smt parameters that are updated, they may be visible.
 | ||||||
|  |     // parameters within sub-solvers will / may not be visible at this level.
 | ||||||
|  |     //
 | ||||||
|  |     auto const& p = get_params(); | ||||||
|  |     gparams::display_updated_parameters(out, p); | ||||||
|  |     return out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void solver::reset_params(params_ref const & p) { | void solver::reset_params(params_ref const & p) { | ||||||
|     m_params.append(p); |     m_params.append(p); | ||||||
|     solver_params sp(m_params); |     solver_params sp(m_params); | ||||||
|  |  | ||||||
|  | @ -81,6 +81,11 @@ public: | ||||||
|     */ |     */ | ||||||
|     virtual void collect_param_descrs(param_descrs & r); |     virtual void collect_param_descrs(param_descrs & r); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |     * \brief display parameters | ||||||
|  |     */ | ||||||
|  |     std::ostream& display_parameters(std::ostream& out); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|        \brief Push a parameter state. It is restored upon pop. |        \brief Push a parameter state. It is restored upon pop. | ||||||
|        Only a single scope of push is supported. |        Only a single scope of push is supported. | ||||||
|  |  | ||||||
|  | @ -412,7 +412,7 @@ public: | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::string get_value(params_ref const & ps, std::string const & p) { |     std::string get_value(params_ref const& ps, std::string const& p) { | ||||||
|         symbol sp(p.c_str()); |         symbol sp(p.c_str()); | ||||||
|         std::ostringstream buffer; |         std::ostringstream buffer; | ||||||
|         ps.display(buffer, sp); |         ps.display(buffer, sp); | ||||||
|  | @ -430,6 +430,19 @@ public: | ||||||
|         return r; |         return r; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void display_updated_parameters(std::ostream& out, params_ref const& p) { | ||||||
|  |         param_descrs* d = nullptr; | ||||||
|  |         for (auto const& [k, v] : m_module_params) { | ||||||
|  |             if (!get_module_param_descr(k, d)) | ||||||
|  |                 continue; | ||||||
|  |             params_ref* ps = nullptr; | ||||||
|  |             if (!m_module_params.find(k, ps)) | ||||||
|  |                 continue; | ||||||
|  |             ps->display_smt2(out, k, *d); | ||||||
|  |             p.display_smt2(out, k, *d); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     std::string get_value(char const * name) { |     std::string get_value(char const * name) { | ||||||
|         std::string m, p; |         std::string m, p; | ||||||
|         normalize(name, m, p); |         normalize(name, m, p); | ||||||
|  | @ -691,3 +704,7 @@ std::string& gparams::g_buffer() { | ||||||
|     SASSERT(g_imp); |     SASSERT(g_imp); | ||||||
|     return g_imp->m_buffer; |     return g_imp->m_buffer; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void gparams::display_updated_parameters(std::ostream& out, params_ref const& p) { | ||||||
|  |     g_imp->display_updated_parameters(out, p); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -118,9 +118,11 @@ public: | ||||||
|      |      | ||||||
|     // Auxiliary APIs for better command line support
 |     // Auxiliary APIs for better command line support
 | ||||||
|     static void display_modules(std::ostream & out); |     static void display_modules(std::ostream & out); | ||||||
|  |     static void display_updated_parameters(std::ostream& out, params_ref const& p); | ||||||
|     static void display_module(std::ostream & out, char const * module_name); |     static void display_module(std::ostream & out, char const * module_name); | ||||||
|     static void display_module_markdown(std::ostream & out, char const * module_name); |     static void display_module_markdown(std::ostream & out, char const * module_name); | ||||||
|     static void display_parameter(std::ostream & out, char const * name); |     static void display_parameter(std::ostream & out, char const * name); | ||||||
|  | 
 | ||||||
|     static param_descrs const& get_global_param_descrs(); |     static param_descrs const& get_global_param_descrs(); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|  |  | ||||||
|  | @ -476,7 +476,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void display_smt2(std::ostream & out, char const* module, param_descrs& descrs) const { |     void display_smt2(std::ostream & out, char const* module, param_descrs& descrs) const { | ||||||
|         for (params::entry const& e : m_entries) { |         for (params::entry const& e : m_entries) { | ||||||
|             if (!descrs.contains(e.first)) continue; |             if (!descrs.contains(e.first))  | ||||||
|  |                 continue; | ||||||
|             out << "(set-option :"; |             out << "(set-option :"; | ||||||
|             out << module << ".";         |             out << module << ".";         | ||||||
|             out << e.first; |             out << e.first; | ||||||
|  | @ -504,6 +505,7 @@ public: | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             out << ")\n"; |             out << ")\n"; | ||||||
|  |             out << "; " << descrs.get_descr(e.first) << "\n"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue