mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 13:29:11 +00:00 
			
		
		
		
	Add simplification customization for SMTLIB2
Add the ability to customize incremental pre-processing simplification for the SMTLIB2 front-end. The main new capability is to use pre-processing tactics in incremental mode that were previously not available. The main new capabilities are - solve-eqs - reduce-args - elim-unconstrained There are several more. Documentation and exposed simplifiers are populated incrementally. The current set of supported simplifiers can be inspected by using z3 with the --simplifiers flag or referring to https://microsoft.github.io/z3guide/docs/strategies/simplifiers Some pending features are: - add the ability to update parameters to simplifiers similar to how tactics can be controlled using parameters. - expose simplification solvers over the binary API.
This commit is contained in:
		
							parent
							
								
									dd0decfe5d
								
							
						
					
					
						commit
						6022c17131
					
				
					 32 changed files with 370 additions and 69 deletions
				
			
		| 
						 | 
				
			
			@ -672,6 +672,7 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
 | 
			
		|||
        components.
 | 
			
		||||
    """
 | 
			
		||||
    ADD_TACTIC_DATA = []
 | 
			
		||||
    ADD_SIMPLIFIER_DATA = []
 | 
			
		||||
    ADD_PROBE_DATA = []
 | 
			
		||||
    def ADD_TACTIC(name, descr, cmd):
 | 
			
		||||
        ADD_TACTIC_DATA.append((name, descr, cmd))
 | 
			
		||||
| 
						 | 
				
			
			@ -679,9 +680,13 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
 | 
			
		|||
    def ADD_PROBE(name, descr, cmd):
 | 
			
		||||
        ADD_PROBE_DATA.append((name, descr, cmd))
 | 
			
		||||
 | 
			
		||||
    def ADD_SIMPLIFIER(name, descr, cmd):
 | 
			
		||||
        ADD_SIMPLIFIER_DATA.append((name, descr, cmd))
 | 
			
		||||
 | 
			
		||||
    eval_globals = {
 | 
			
		||||
        'ADD_TACTIC': ADD_TACTIC,
 | 
			
		||||
        'ADD_PROBE': ADD_PROBE,
 | 
			
		||||
        'ADD_SIMPLIFIER': ADD_SIMPLIFIER
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assert isinstance(h_files_full_path, list)
 | 
			
		||||
| 
						 | 
				
			
			@ -691,9 +696,11 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
 | 
			
		|||
    fout.write('// Automatically generated file.\n')
 | 
			
		||||
    fout.write('#include "tactic/tactic.h"\n')
 | 
			
		||||
    fout.write('#include "cmd_context/tactic_cmds.h"\n')
 | 
			
		||||
    fout.write('#include "cmd_context/simplifier_cmds.h"\n')
 | 
			
		||||
    fout.write('#include "cmd_context/cmd_context.h"\n')
 | 
			
		||||
    tactic_pat   = re.compile('[ \t]*ADD_TACTIC\(.*\)')
 | 
			
		||||
    probe_pat    = re.compile('[ \t]*ADD_PROBE\(.*\)')
 | 
			
		||||
    simplifier_pat = re.compile('[ \t]*ADD_SIMPLIFIER\(.*\)')
 | 
			
		||||
    for h_file in sorted_headers_by_component(h_files_full_path):
 | 
			
		||||
        added_include = False
 | 
			
		||||
        try:
 | 
			
		||||
| 
						 | 
				
			
			@ -719,17 +726,31 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
 | 
			
		|||
                            _logger.error("Failed processing ADD_PROBE command at '{}'\n{}".format(
 | 
			
		||||
                                fullname, line))
 | 
			
		||||
                            raise e
 | 
			
		||||
                    if simplifier_pat.match(line):
 | 
			
		||||
                        if not added_include:
 | 
			
		||||
                            added_include = True
 | 
			
		||||
                            fout.write('#include "%s"\n' % path_after_src(h_file))
 | 
			
		||||
                        try:
 | 
			
		||||
                            eval(line.strip('\n '), eval_globals, None)
 | 
			
		||||
                        except Exception as e:
 | 
			
		||||
                            _logger.error("Failed processing ADD_SIMPLIFIER command at '{}'\n{}".format(
 | 
			
		||||
                                fullname, line))
 | 
			
		||||
                            raise e
 | 
			
		||||
                        
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
           _logger.error("Failed to read file {}\n".format(h_file))
 | 
			
		||||
           raise e
 | 
			
		||||
    # First pass will just generate the tactic factories
 | 
			
		||||
    fout.write('#define ADD_TACTIC_CMD(NAME, DESCR, CODE) ctx.insert(alloc(tactic_cmd, symbol(NAME), DESCR, [](ast_manager &m, const params_ref &p) { return CODE; }))\n')
 | 
			
		||||
    fout.write('#define ADD_PROBE(NAME, DESCR, PROBE) ctx.insert(alloc(probe_info, symbol(NAME), DESCR, PROBE))\n')
 | 
			
		||||
    fout.write('#define ADD_SIMPLIFIER_CMD(NAME, DESCR, FUNCTION) ctx.insert(alloc(simplifier_cmd, symbol(NAME), DESCR, FUNCTION))\n')
 | 
			
		||||
    fout.write('void install_tactics(tactic_manager & ctx) {\n')
 | 
			
		||||
    for data in ADD_TACTIC_DATA:
 | 
			
		||||
        fout.write('  ADD_TACTIC_CMD("%s", "%s", %s);\n' % data)
 | 
			
		||||
    for data in ADD_PROBE_DATA:
 | 
			
		||||
        fout.write('  ADD_PROBE("%s", "%s", %s);\n' % data)
 | 
			
		||||
    for data in ADD_SIMPLIFIER_DATA:
 | 
			
		||||
        fout.write('  ADD_SIMPLIFIER_CMD("%s", "%s", %s);\n' % data)
 | 
			
		||||
    fout.write('}\n')
 | 
			
		||||
    fout.close()
 | 
			
		||||
    return fullname
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,4 +29,8 @@ z3_add_component(simplifiers
 | 
			
		|||
    normal_forms
 | 
			
		||||
    rewriter
 | 
			
		||||
    substitution
 | 
			
		||||
  TACTIC_HEADERS
 | 
			
		||||
    bit_blaster.h
 | 
			
		||||
    rewriter_simplifier.h
 | 
			
		||||
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,3 +49,6 @@ public:
 | 
			
		|||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_SIMPLIFIER("bit-blaster", "reduce bit-vector expressions into SAT.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(bit_blaster_simplifier, m, p, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ Author:
 | 
			
		|||
#include "util/trail.h"
 | 
			
		||||
#include "util/statistics.h"
 | 
			
		||||
#include "util/params.h"
 | 
			
		||||
#include "util/z3_exception.h"
 | 
			
		||||
#include "ast/converters/model_converter.h"
 | 
			
		||||
#include "ast/simplifiers/dependent_expr.h"
 | 
			
		||||
#include "ast/simplifiers/model_reconstruction_trail.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -98,6 +99,17 @@ public:
 | 
			
		|||
    bool has_quantifiers();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class default_dependent_expr_state : public dependent_expr_state {
 | 
			
		||||
public:
 | 
			
		||||
    default_dependent_expr_state(ast_manager& m): dependent_expr_state(m) {}
 | 
			
		||||
    virtual unsigned qtail() const { return 0; }
 | 
			
		||||
    virtual dependent_expr const& operator[](unsigned i) { throw default_exception("unexpected access"); }
 | 
			
		||||
    virtual void update(unsigned i, dependent_expr const& j) { throw default_exception("unexpected update"); }
 | 
			
		||||
    virtual void add(dependent_expr const& j) { throw default_exception("unexpected addition"); }
 | 
			
		||||
    virtual bool inconsistent() { return false; }
 | 
			
		||||
    virtual model_reconstruction_trail& model_trail() { throw default_exception("unexpected access to model reconstruction"); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline std::ostream& operator<<(std::ostream& out, dependent_expr_state& st) {
 | 
			
		||||
    return st.display(out);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -150,3 +162,5 @@ public:
 | 
			
		|||
    ast_manager& get_manager() { return m; }
 | 
			
		||||
    dependent_expr_state& get_fmls() { return m_fmls; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef std::function<dependent_expr_simplifier*(ast_manager&, const params_ref&, dependent_expr_state& s)> simplifier_factory;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,18 +139,15 @@ void model_reconstruction_trail::replay(unsigned qhead, expr_ref_vector& assumpt
 | 
			
		|||
 */
 | 
			
		||||
model_converter_ref model_reconstruction_trail::get_model_converter() {
 | 
			
		||||
    generic_model_converter_ref mc = alloc(generic_model_converter, m, "dependent-expr-model");
 | 
			
		||||
    unsigned i = 0;
 | 
			
		||||
    append(*mc, i);
 | 
			
		||||
    append(*mc);
 | 
			
		||||
    return model_converter_ref(mc.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* Append model conversions starting at index i
 | 
			
		||||
*/
 | 
			
		||||
void model_reconstruction_trail::append(generic_model_converter& mc, unsigned& i) {
 | 
			
		||||
    TRACE("simplifier", display(tout));
 | 
			
		||||
    for (; i < m_trail.size(); ++i) {
 | 
			
		||||
        auto* t = m_trail[i];
 | 
			
		||||
void model_reconstruction_trail::append(generic_model_converter& mc) {
 | 
			
		||||
    for (auto* t : m_trail) {
 | 
			
		||||
        if (!t->m_active)
 | 
			
		||||
            continue;
 | 
			
		||||
        else if (t->is_hide())
 | 
			
		||||
| 
						 | 
				
			
			@ -163,13 +160,10 @@ void model_reconstruction_trail::append(generic_model_converter& mc, unsigned& i
 | 
			
		|||
                mc.add(v, def);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    TRACE("simplifier", display(tout); mc.display(tout));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void model_reconstruction_trail::append(generic_model_converter& mc) {
 | 
			
		||||
    m_trail_stack.push(value_trail(m_trail_index));
 | 
			
		||||
    append(mc, m_trail_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::ostream& model_reconstruction_trail::display(std::ostream& out) const {
 | 
			
		||||
    for (auto* t : m_trail) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,7 +84,6 @@ class model_reconstruction_trail {
 | 
			
		|||
    ast_manager&             m;
 | 
			
		||||
    trail_stack&             m_trail_stack;
 | 
			
		||||
    scoped_ptr_vector<entry> m_trail;
 | 
			
		||||
    unsigned                 m_trail_index = 0;
 | 
			
		||||
 | 
			
		||||
    void add_vars(expr* e, ast_mark& free_vars) {
 | 
			
		||||
        for (expr* t : subterms::all(expr_ref(e, m)))
 | 
			
		||||
| 
						 | 
				
			
			@ -108,10 +107,6 @@ class model_reconstruction_trail {
 | 
			
		|||
        return any_of(added, [&](dependent_expr const& d) { return intersects(free_vars, d); });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Append new updates to model converter, update the current index into the trail in the process.
 | 
			
		||||
    */
 | 
			
		||||
    void append(generic_model_converter& mc, unsigned& index);
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    model_reconstruction_trail(ast_manager& m, trail_stack& tr): 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,3 +53,7 @@ public:
 | 
			
		|||
    void updt_params(params_ref const& p) override { m_params.append(p); m_rewriter.updt_params(m_params); }
 | 
			
		||||
    void collect_param_descrs(param_descrs& r) override { th_rewriter::get_param_descrs(r); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_SIMPLIFIER("simplify", "apply simplification rules.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(rewriter_simplifier, m, p, s); }")
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ z3_add_component(cmd_context
 | 
			
		|||
    parametric_cmd.cpp
 | 
			
		||||
    pdecl.cpp
 | 
			
		||||
    simplify_cmd.cpp
 | 
			
		||||
    simplifier_cmds.cpp
 | 
			
		||||
    tactic_cmds.cpp
 | 
			
		||||
    tactic_manager.cpp
 | 
			
		||||
  COMPONENT_DEPENDENCIES
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -546,6 +546,7 @@ cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l):
 | 
			
		|||
    install_basic_cmds(*this);
 | 
			
		||||
    install_ext_basic_cmds(*this);
 | 
			
		||||
    install_core_tactic_cmds(*this);
 | 
			
		||||
    install_core_simplifier_cmds(*this);
 | 
			
		||||
    m_mcs.push_back(nullptr);
 | 
			
		||||
    SASSERT(m != 0 || !has_manager());
 | 
			
		||||
    if (m_main_ctx) {
 | 
			
		||||
| 
						 | 
				
			
			@ -559,8 +560,7 @@ cmd_context::~cmd_context() {
 | 
			
		|||
    }
 | 
			
		||||
    pop(m_scopes.size());
 | 
			
		||||
    finalize_cmds();
 | 
			
		||||
    finalize_tactic_cmds();
 | 
			
		||||
    finalize_probes();
 | 
			
		||||
    finalize_tactic_manager();
 | 
			
		||||
    m_proof_cmds = nullptr;
 | 
			
		||||
    reset(true);
 | 
			
		||||
    m_mcs.reset();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -318,7 +318,7 @@ protected:
 | 
			
		|||
    void register_builtin_ops(decl_plugin * p);
 | 
			
		||||
    void load_plugin(symbol const & name, bool install_names, svector<family_id>& fids);
 | 
			
		||||
    void init_manager_core(bool new_manager);
 | 
			
		||||
    void init_manager();
 | 
			
		||||
 | 
			
		||||
    void init_external_manager();
 | 
			
		||||
    void reset_cmds();
 | 
			
		||||
    void finalize_cmds();
 | 
			
		||||
| 
						 | 
				
			
			@ -414,7 +414,9 @@ public:
 | 
			
		|||
    sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast<cmd_context*>(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; }
 | 
			
		||||
 | 
			
		||||
    proof_cmds* get_proof_cmds() { return m_proof_cmds.get(); }
 | 
			
		||||
    void init_manager();
 | 
			
		||||
    solver* get_solver() { return m_solver.get(); }
 | 
			
		||||
    void set_solver(solver* s) { m_solver = s; }
 | 
			
		||||
    void set_proof_cmds(proof_cmds* pc) { m_proof_cmds = pc; }
 | 
			
		||||
 | 
			
		||||
    void set_solver_factory(solver_factory * s);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										158
									
								
								src/cmd_context/simplifier_cmds.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/cmd_context/simplifier_cmds.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,158 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2023 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    simplifier_cmds.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
    Support for simplifier commands in SMT 2.0 front-end
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2023-01-30
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#include<sstream>
 | 
			
		||||
#include "cmd_context/simplifier_cmds.h"
 | 
			
		||||
#include "cmd_context/cmd_context.h"
 | 
			
		||||
#include "cmd_context/cmd_util.h"
 | 
			
		||||
#include "cmd_context/parametric_cmd.h"
 | 
			
		||||
#include "model/model_smt2_pp.h"
 | 
			
		||||
#include "ast/ast_smt2_pp.h"
 | 
			
		||||
#include "ast/simplifiers/seq_simplifier.h"
 | 
			
		||||
#include "solver/simplifier_solver.h"
 | 
			
		||||
 | 
			
		||||
typedef dependent_expr_simplifier simplifier;
 | 
			
		||||
 | 
			
		||||
static simplifier_factory mk_and_then(cmd_context & ctx, sexpr * n) {
 | 
			
		||||
    SASSERT(n->is_composite());
 | 
			
		||||
    unsigned num_children = n->get_num_children();
 | 
			
		||||
    if (num_children < 2)
 | 
			
		||||
        throw cmd_exception("invalid and-then combinator, at least one argument expected", n->get_line(), n->get_pos());
 | 
			
		||||
    if (num_children == 2)
 | 
			
		||||
        return sexpr2simplifier(ctx, n->get_child(1));
 | 
			
		||||
    vector<simplifier_factory> args;
 | 
			
		||||
    for (unsigned i = 1; i < num_children; i++)
 | 
			
		||||
        args.push_back(sexpr2simplifier(ctx, n->get_child(i)));
 | 
			
		||||
    simplifier_factory result = [args](ast_manager& m, const params_ref& p, dependent_expr_state& st) {
 | 
			
		||||
        scoped_ptr<seq_simplifier> s = alloc(seq_simplifier, m, p, st);
 | 
			
		||||
        for (auto &  simp : args)
 | 
			
		||||
            s->add_simplifier(simp(m, p, st));
 | 
			
		||||
        return s.detach();
 | 
			
		||||
    };
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static simplifier_factory mk_using_params(cmd_context & ctx, sexpr * n) {
 | 
			
		||||
    SASSERT(n->is_composite());
 | 
			
		||||
    unsigned num_children = n->get_num_children();
 | 
			
		||||
    if (num_children < 2)
 | 
			
		||||
        throw cmd_exception("invalid using-params combinator, at least one argument expected", n->get_line(), n->get_pos());
 | 
			
		||||
    if (num_children == 2)
 | 
			
		||||
        return sexpr2simplifier(ctx, n->get_child(1));
 | 
			
		||||
    simplifier_factory t = sexpr2simplifier(ctx, n->get_child(1));
 | 
			
		||||
#if 0
 | 
			
		||||
    // hoist parameter parsing code from tactic_cmds to share.
 | 
			
		||||
    param_descrs descrs;
 | 
			
		||||
    t->collect_param_descrs(descrs);
 | 
			
		||||
       
 | 
			
		||||
#endif
 | 
			
		||||
    return t;
 | 
			
		||||
//    return using_params(t.detach(), p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
simplifier_factory sexpr2simplifier(cmd_context & ctx, sexpr * n) {
 | 
			
		||||
    if (n->is_symbol()) {
 | 
			
		||||
        simplifier_cmd * cmd = ctx.find_simplifier_cmd(n->get_symbol());
 | 
			
		||||
        if (cmd != nullptr)
 | 
			
		||||
            return cmd->factory();
 | 
			
		||||
        throw cmd_exception("invalid tactic, unknown tactic ", n->get_symbol(), n->get_line(), n->get_pos());
 | 
			
		||||
    }
 | 
			
		||||
    else if (n->is_composite()) {
 | 
			
		||||
        unsigned num_children = n->get_num_children();
 | 
			
		||||
        if (num_children == 0)
 | 
			
		||||
            throw cmd_exception("invalid tactic, arguments expected", n->get_line(), n->get_pos());
 | 
			
		||||
        sexpr * head = n->get_child(0);
 | 
			
		||||
        if (!head->is_symbol())
 | 
			
		||||
            throw cmd_exception("invalid tactic, symbol expected", n->get_line(), n->get_pos());
 | 
			
		||||
        symbol const & cmd_name = head->get_symbol();
 | 
			
		||||
        if (cmd_name == "and-then" || cmd_name == "then")
 | 
			
		||||
            return mk_and_then(ctx, n);
 | 
			
		||||
        else
 | 
			
		||||
            throw cmd_exception("invalid tactic, unknown tactic combinator ", cmd_name, n->get_line(), n->get_pos());
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        throw cmd_exception("invalid tactic, unexpected input", n->get_line(), n->get_pos());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void help_simplifier(cmd_context & ctx) {
 | 
			
		||||
    std::ostringstream buf;
 | 
			
		||||
    buf << "combinators:\n";
 | 
			
		||||
    buf << "- (and-then <simplifier>+) executes the given simplifiers sequentially.\n";
 | 
			
		||||
    // buf << "- (using-params <tactic> <attribute>*) executes the given tactic using the given attributes, where <attribute> ::= <keyword> <value>. ! is a syntax sugar for using-params.\n";
 | 
			
		||||
    buf << "builtin simplifiers:\n";
 | 
			
		||||
    for (simplifier_cmd* cmd : ctx.simplifiers()) {
 | 
			
		||||
        buf << "- " << cmd->get_name() << " " << cmd->get_descr() << "\n";
 | 
			
		||||
        auto fac = cmd->factory();
 | 
			
		||||
        param_descrs descrs;
 | 
			
		||||
        ast_manager& m = ctx.get_ast_manager();
 | 
			
		||||
        default_dependent_expr_state st(m);
 | 
			
		||||
        params_ref p;
 | 
			
		||||
        scoped_ptr<dependent_expr_simplifier> s = fac(m, p, st);
 | 
			
		||||
        s->collect_param_descrs(descrs);
 | 
			
		||||
        descrs.display(buf, 4);
 | 
			
		||||
    }
 | 
			
		||||
    ctx.regular_stream() << '"' << escaped(buf.str()) << "\"\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ATOMIC_CMD(help_simplifier_cmd, "help-simplifier", "display the simplifier combinators and primitives.", help_simplifier(ctx););
 | 
			
		||||
 | 
			
		||||
class set_simplifier_cmd : public parametric_cmd {
 | 
			
		||||
protected:
 | 
			
		||||
    sexpr * m_simplifier;
 | 
			
		||||
public:
 | 
			
		||||
    set_simplifier_cmd():
 | 
			
		||||
        parametric_cmd("set-simplifier") {}
 | 
			
		||||
    
 | 
			
		||||
    char const * get_usage() const override { return "<tactic> (<keyword> <value>)*"; }
 | 
			
		||||
 | 
			
		||||
    void prepare(cmd_context & ctx) override {
 | 
			
		||||
        parametric_cmd::prepare(ctx);
 | 
			
		||||
        m_simplifier = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmd_arg_kind next_arg_kind(cmd_context & ctx) const override {
 | 
			
		||||
        if (m_simplifier == nullptr) return CPK_SEXPR;
 | 
			
		||||
        return parametric_cmd::next_arg_kind(ctx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_next_arg(cmd_context & ctx, sexpr * arg) override {
 | 
			
		||||
        m_simplifier = arg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char const * get_main_descr() const override { return "update main solver with simplification pre-processing."; }
 | 
			
		||||
 | 
			
		||||
    void init_pdescrs(cmd_context & ctx, param_descrs & p) override {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void execute(cmd_context & ctx) override {
 | 
			
		||||
        if (!m_simplifier) 
 | 
			
		||||
            throw cmd_exception("set-simplifier needs a simplifier argument");
 | 
			
		||||
        
 | 
			
		||||
        auto simplifier_factory = sexpr2simplifier(ctx, m_simplifier);
 | 
			
		||||
        ctx.init_manager();
 | 
			
		||||
        auto* s = ctx.get_solver();
 | 
			
		||||
        if (s)
 | 
			
		||||
            ctx.set_solver(mk_simplifier_solver(s, &simplifier_factory));        
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void install_core_simplifier_cmds(cmd_context & ctx) {
 | 
			
		||||
    ctx.insert(alloc(set_simplifier_cmd));    
 | 
			
		||||
    ctx.insert(alloc(help_simplifier_cmd));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/cmd_context/simplifier_cmds.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/cmd_context/simplifier_cmds.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2023 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    simplifier_cmds.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
    Support for simplifier commands in SMT 2.0 front-end
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Nikolaj Bjorner (nbjorner) 2023-01-30
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "ast/ast.h"
 | 
			
		||||
#include "ast/simplifiers/dependent_expr_state.h"
 | 
			
		||||
#include "util/params.h"
 | 
			
		||||
#include "util/cmd_context_types.h"
 | 
			
		||||
#include "util/ref.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class simplifier_cmd {
 | 
			
		||||
    symbol             m_name;
 | 
			
		||||
    char const *       m_descr;
 | 
			
		||||
    simplifier_factory m_factory;
 | 
			
		||||
public:
 | 
			
		||||
    simplifier_cmd(symbol const & n, char const * d, simplifier_factory f):
 | 
			
		||||
        m_name(n), m_descr(d), m_factory(f) {}
 | 
			
		||||
 | 
			
		||||
    symbol get_name() const { return m_name; }
 | 
			
		||||
    
 | 
			
		||||
    char const * get_descr() const { return m_descr; }
 | 
			
		||||
    
 | 
			
		||||
    simplifier_factory factory() { return m_factory; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
simplifier_factory sexpr2simplifier(cmd_context & ctx, sexpr * n);
 | 
			
		||||
 | 
			
		||||
void install_core_simplifier_cmds(cmd_context & ctx);
 | 
			
		||||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ Module Name:
 | 
			
		|||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
    Collection of tactics & probes
 | 
			
		||||
    Collection of tactics, simplifiers & probes
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,8 +19,21 @@ Notes:
 | 
			
		|||
#include "cmd_context/tactic_manager.h"
 | 
			
		||||
 | 
			
		||||
tactic_manager::~tactic_manager() {
 | 
			
		||||
    finalize_tactic_cmds();
 | 
			
		||||
    finalize_probes();
 | 
			
		||||
    finalize_tactic_manager();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tactic_manager::finalize_tactic_manager() {
 | 
			
		||||
    std::for_each(m_tactics.begin(), m_tactics.end(), delete_proc<tactic_cmd>());
 | 
			
		||||
    m_tactics.reset();
 | 
			
		||||
    m_name2tactic.reset();
 | 
			
		||||
 | 
			
		||||
    std::for_each(m_simplifiers.begin(), m_simplifiers.end(), delete_proc<simplifier_cmd>());
 | 
			
		||||
    m_simplifiers.reset();
 | 
			
		||||
    m_name2simplifier.reset();
 | 
			
		||||
 | 
			
		||||
    std::for_each(m_probes.begin(), m_probes.end(), delete_proc<probe_info>());
 | 
			
		||||
    m_probes.reset();
 | 
			
		||||
    m_name2probe.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tactic_manager::insert(tactic_cmd * c) {
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +43,13 @@ void tactic_manager::insert(tactic_cmd * c) {
 | 
			
		|||
    m_tactics.push_back(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tactic_manager::insert(simplifier_cmd * c) {
 | 
			
		||||
    symbol const & s = c->get_name();
 | 
			
		||||
    SASSERT(!m_name2simplifier.contains(s));
 | 
			
		||||
    m_name2simplifier.insert(s, c);
 | 
			
		||||
    m_simplifiers.push_back(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tactic_manager::insert(probe_info * p) {
 | 
			
		||||
    symbol const & s = p->get_name();
 | 
			
		||||
    SASSERT(!m_name2probe.contains(s));
 | 
			
		||||
| 
						 | 
				
			
			@ -43,20 +63,15 @@ tactic_cmd * tactic_manager::find_tactic_cmd(symbol const & s) const {
 | 
			
		|||
    return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
simplifier_cmd * tactic_manager::find_simplifier_cmd(symbol const & s) const {
 | 
			
		||||
    simplifier_cmd * c = nullptr;
 | 
			
		||||
    m_name2simplifier.find(s, c);
 | 
			
		||||
    return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
probe_info * tactic_manager::find_probe(symbol const & s) const {
 | 
			
		||||
    probe_info * p = nullptr;
 | 
			
		||||
    m_name2probe.find(s, p);
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tactic_manager::finalize_tactic_cmds() {
 | 
			
		||||
    std::for_each(m_tactics.begin(), m_tactics.end(), delete_proc<tactic_cmd>());
 | 
			
		||||
    m_tactics.reset();
 | 
			
		||||
    m_name2tactic.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tactic_manager::finalize_probes() {
 | 
			
		||||
    std::for_each(m_probes.begin(), m_probes.end(), delete_proc<probe_info>());
 | 
			
		||||
    m_probes.reset();
 | 
			
		||||
    m_name2probe.reset();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,54 +18,37 @@ Notes:
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "cmd_context/tactic_cmds.h"
 | 
			
		||||
#include "cmd_context/simplifier_cmds.h"
 | 
			
		||||
#include "util/dictionary.h"
 | 
			
		||||
 | 
			
		||||
class tactic_manager {
 | 
			
		||||
protected:
 | 
			
		||||
    dictionary<tactic_cmd*>  m_name2tactic;
 | 
			
		||||
    dictionary<probe_info*>  m_name2probe;
 | 
			
		||||
    dictionary<simplifier_cmd*> m_name2simplifier;
 | 
			
		||||
    ptr_vector<tactic_cmd>   m_tactics;
 | 
			
		||||
    ptr_vector<simplifier_cmd> m_simplifiers;
 | 
			
		||||
    ptr_vector<probe_info>   m_probes;
 | 
			
		||||
    void finalize_tactic_cmds();
 | 
			
		||||
    void finalize_probes();
 | 
			
		||||
    void finalize_tactic_manager();
 | 
			
		||||
public:
 | 
			
		||||
    ~tactic_manager();
 | 
			
		||||
 | 
			
		||||
    void insert(tactic_cmd * c);
 | 
			
		||||
    void insert(simplifier_cmd* c);
 | 
			
		||||
    void insert(probe_info * p);
 | 
			
		||||
    tactic_cmd * find_tactic_cmd(symbol const & s) const; 
 | 
			
		||||
    probe_info * find_probe(symbol const & s) const; 
 | 
			
		||||
    simplifier_cmd* find_simplifier_cmd(symbol const& s) const;
 | 
			
		||||
 | 
			
		||||
    unsigned num_tactics() const { return m_tactics.size(); }
 | 
			
		||||
    unsigned num_probes() const { return m_probes.size(); }
 | 
			
		||||
    tactic_cmd * get_tactic(unsigned i) const { return m_tactics[i]; }
 | 
			
		||||
    probe_info * get_probe(unsigned i) const { return m_probes[i]; }
 | 
			
		||||
 | 
			
		||||
    typedef ptr_vector<tactic_cmd>::const_iterator tactic_cmd_iterator;
 | 
			
		||||
    tactic_cmd_iterator begin_tactic_cmds() const { return m_tactics.begin(); }
 | 
			
		||||
    tactic_cmd_iterator end_tactic_cmds() const { return m_tactics.end(); }
 | 
			
		||||
    class tactics_iterator {
 | 
			
		||||
        tactic_manager const& m;
 | 
			
		||||
    public:
 | 
			
		||||
        tactics_iterator(tactic_manager const& m):m(m) {}
 | 
			
		||||
        tactic_cmd_iterator begin() const { return m.begin_tactic_cmds(); }
 | 
			
		||||
        tactic_cmd_iterator end() const { return m.end_tactic_cmds(); }
 | 
			
		||||
    };
 | 
			
		||||
    tactics_iterator tactics() const { return tactics_iterator(*this); }
 | 
			
		||||
    ptr_vector<simplifier_cmd> const& simplifiers() const { return m_simplifiers; }
 | 
			
		||||
    ptr_vector<tactic_cmd> const& tactics() const { return m_tactics; }
 | 
			
		||||
    ptr_vector<probe_info> const& probes() const { return m_probes; }
 | 
			
		||||
    
 | 
			
		||||
    typedef ptr_vector<probe_info>::const_iterator probe_iterator;
 | 
			
		||||
    probe_iterator begin_probes() const { return m_probes.begin(); }
 | 
			
		||||
    probe_iterator end_probes() const { return m_probes.end(); }
 | 
			
		||||
 | 
			
		||||
    class probes_iterator {
 | 
			
		||||
        tactic_manager const& m;
 | 
			
		||||
    public:
 | 
			
		||||
        probes_iterator(tactic_manager const& m):m(m) {}
 | 
			
		||||
        probe_iterator begin() const { return m.begin_probes(); }
 | 
			
		||||
        probe_iterator end() const { return m.end_probes(); }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    probes_iterator probes() const { return probes_iterator(*this); }
 | 
			
		||||
        
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -700,6 +700,6 @@ private:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
solver* mk_sat_smt_solver(ast_manager& m, params_ref const& p) {
 | 
			
		||||
    return mk_simplifier_solver(alloc(sat_smt_solver, m, p));
 | 
			
		||||
    return mk_simplifier_solver(alloc(sat_smt_solver, m, p), nullptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,6 +98,7 @@ void display_usage() {
 | 
			
		|||
    std::cout << "  -pmmd:name  display Z3 module ('name') parameters in Markdown format.\n";
 | 
			
		||||
    std::cout << "  -pp:name    display Z3 parameter description, if 'name' is not provided, then all module names are listed.\n";
 | 
			
		||||
    std::cout << "  -tactics[:name]  display built-in tactics or if argument is given, display detailed information on tactic.\n";
 | 
			
		||||
    std::cout << "  -simplifiers[:name]  display built-in simplifiers or if argument is given, display detailed information on simplifier.\n";
 | 
			
		||||
    std::cout << "  -probes     display avilable probes.\n";
 | 
			
		||||
    std::cout << "  --"      << "          all remaining arguments are assumed to be part of the input file name. This option allows Z3 to read files with strange names such as: -foo.smt2.\n";
 | 
			
		||||
    std::cout << "\nResources:\n";
 | 
			
		||||
| 
						 | 
				
			
			@ -295,6 +296,12 @@ static void parse_cmd_line_args(std::string& input_file, int argc, char ** argv)
 | 
			
		|||
                else
 | 
			
		||||
                    help_tactic(opt_arg, false);
 | 
			
		||||
            }
 | 
			
		||||
            else if (strcmp(opt_name, "simplifiers") == 0) {
 | 
			
		||||
                if (!opt_arg)
 | 
			
		||||
                    help_simplifiers();
 | 
			
		||||
                else
 | 
			
		||||
                    help_simplifier(opt_arg, false);
 | 
			
		||||
            }
 | 
			
		||||
            else if (strcmp(opt_name, "tacticsmd") == 0 && opt_arg) 
 | 
			
		||||
                help_tactic(opt_arg, true);
 | 
			
		||||
            else if (strcmp(opt_name, "probes") == 0) 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,6 +88,22 @@ void help_tactics() {
 | 
			
		|||
        std::cout << "- " << cmd->get_name() << " " << cmd->get_descr() << "\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void help_simplifiers() {
 | 
			
		||||
    struct cmp {
 | 
			
		||||
        bool operator()(simplifier_cmd* a, simplifier_cmd* b) const {
 | 
			
		||||
            return a->get_name().str() < b->get_name().str();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    cmd_context ctx;
 | 
			
		||||
    ptr_vector<simplifier_cmd> cmds;
 | 
			
		||||
    for (auto cmd : ctx.simplifiers()) 
 | 
			
		||||
        cmds.push_back(cmd);
 | 
			
		||||
    cmp lt;
 | 
			
		||||
    std::sort(cmds.begin(), cmds.end(), lt);
 | 
			
		||||
    for (auto cmd : cmds) 
 | 
			
		||||
        std::cout << "- " << cmd->get_name() << " " << cmd->get_descr() << "\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void help_tactic(char const* name, bool markdown) {
 | 
			
		||||
    cmd_context ctx;
 | 
			
		||||
    for (auto cmd : ctx.tactics()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +119,25 @@ void help_tactic(char const* name, bool markdown) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void help_simplifier(char const* name, bool markdown) {
 | 
			
		||||
    cmd_context ctx;
 | 
			
		||||
    for (auto cmd : ctx.simplifiers()) {
 | 
			
		||||
        if (cmd->get_name() == name) {
 | 
			
		||||
            auto fac = cmd->factory();
 | 
			
		||||
            param_descrs descrs;
 | 
			
		||||
            ast_manager& m = ctx.m();
 | 
			
		||||
            default_dependent_expr_state st(m);
 | 
			
		||||
            params_ref p;
 | 
			
		||||
            scoped_ptr<dependent_expr_simplifier> s = fac(m, p, st);
 | 
			
		||||
            s->collect_param_descrs(descrs);
 | 
			
		||||
            if (markdown)
 | 
			
		||||
                descrs.display_markdown(std::cout);
 | 
			
		||||
            else
 | 
			
		||||
                descrs.display(std::cout, 4);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void help_probes() {
 | 
			
		||||
    struct cmp {
 | 
			
		||||
        bool operator()(probe_info* a, probe_info* b) const {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,9 @@ Revision History:
 | 
			
		|||
unsigned read_smtlib_file(char const * benchmark_file);
 | 
			
		||||
unsigned read_smtlib2_commands(char const * command_file);
 | 
			
		||||
void help_tactics();
 | 
			
		||||
void help_simplifiers();
 | 
			
		||||
void help_probes();
 | 
			
		||||
void help_tactic(char const* name, bool markdown);
 | 
			
		||||
void help_simplifier(char const* name, bool markdown);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ class simplifier_solver : public solver {
 | 
			
		|||
    };   
 | 
			
		||||
 | 
			
		||||
    ast_manager& m;
 | 
			
		||||
    scoped_ptr<solver> s;
 | 
			
		||||
    solver_ref  s;
 | 
			
		||||
    vector<dependent_expr>      m_fmls;
 | 
			
		||||
    dep_expr_state              m_preprocess_state;
 | 
			
		||||
    seq_simplifier              m_preprocess;
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +143,7 @@ class simplifier_solver : public solver {
 | 
			
		|||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    simplifier_solver(solver* s) : 
 | 
			
		||||
    simplifier_solver(solver* s, simplifier_factory* fac) : 
 | 
			
		||||
        solver(s->get_manager()), 
 | 
			
		||||
        m(s->get_manager()), 
 | 
			
		||||
        s(s),
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +152,10 @@ public:
 | 
			
		|||
        m_assumptions(m),
 | 
			
		||||
        m_proof(m)
 | 
			
		||||
    {
 | 
			
		||||
        init_preprocess(m, s->get_params(), m_preprocess, m_preprocess_state);
 | 
			
		||||
        if (fac) 
 | 
			
		||||
            m_preprocess.add_simplifier((*fac)(m, s->get_params(), m_preprocess_state));
 | 
			
		||||
        else 
 | 
			
		||||
            init_preprocess(m, s->get_params(), m_preprocess, m_preprocess_state);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void assert_expr_core2(expr* t, expr* a) override {
 | 
			
		||||
| 
						 | 
				
			
			@ -198,6 +201,7 @@ public:
 | 
			
		|||
 | 
			
		||||
    model_ref m_cached_model;
 | 
			
		||||
    void get_model_core(model_ref& m) override {       
 | 
			
		||||
        CTRACE("simplifier", m_mc.get(), m_mc->display(tout));
 | 
			
		||||
        if (m_cached_model) {
 | 
			
		||||
            m = m_cached_model;
 | 
			
		||||
            return;
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +233,7 @@ public:
 | 
			
		|||
    solver* translate(ast_manager& m, params_ref const& p) override { 
 | 
			
		||||
        solver* new_s = s->translate(m, p);
 | 
			
		||||
        ast_translation tr(get_manager(), m);
 | 
			
		||||
        simplifier_solver* result = alloc(simplifier_solver, new_s);
 | 
			
		||||
        simplifier_solver* result = alloc(simplifier_solver, new_s, nullptr); // factory?
 | 
			
		||||
        for (dependent_expr const& f : m_fmls) 
 | 
			
		||||
            result->m_fmls.push_back(dependent_expr(tr, f));
 | 
			
		||||
        if (m_mc) 
 | 
			
		||||
| 
						 | 
				
			
			@ -311,7 +315,7 @@ public:
 | 
			
		|||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
solver* mk_simplifier_solver(solver* s) {
 | 
			
		||||
    return alloc(simplifier_solver, s);
 | 
			
		||||
solver* mk_simplifier_solver(solver* s, simplifier_factory* fac) {
 | 
			
		||||
    return alloc(simplifier_solver, s, fac);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,9 @@ Author:
 | 
			
		|||
 | 
			
		||||
class solver;
 | 
			
		||||
class solver_factory;
 | 
			
		||||
class dependent_expr_simplifier;
 | 
			
		||||
class dependent_expr_state;
 | 
			
		||||
typedef std::function<dependent_expr_simplifier*(ast_manager&, const params_ref&, dependent_expr_state& s)> simplifier_factory;
 | 
			
		||||
 | 
			
		||||
solver * mk_simplifier_solver(solver * s);
 | 
			
		||||
solver * mk_simplifier_solver(solver * s, simplifier_factory* fac);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,4 +38,5 @@ inline tactic* mk_bound_simplifier_tactic(ast_manager& m, params_ref const& p =
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("bound-simplifier", "Simplify arithmetical expressions modulo bounds.", "mk_bound_simplifier_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("bound-simplifier", "Simplify arithmetical expressions modulo bounds.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(bound_simplifier, m, p, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,4 +69,5 @@ inline tactic* mk_card2bv_tactic(ast_manager& m, params_ref const& p = params_re
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("card2bv", "convert pseudo-boolean constraints to bit-vectors.", "mk_card2bv_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("card2bv", "convert pseudo-boolean constraints to bit-vectors.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(card2bv, m, p, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,5 +64,6 @@ inline tactic* mk_propagate_ineqs_tactic(ast_manager& m, params_ref const& p = p
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("propagate-ineqs", "propagate ineqs/bounds, remove subsumed inequalities.", "mk_propagate_ineqs_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("propagate-ineqs", "propagate ineqs/bounds, remove subsumed inequalities.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(bound_simplifier, m, p, s); }")
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,7 @@ Contextual bounds simplification tactic.
 | 
			
		|||
--*/
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "tactic/tactic.h"
 | 
			
		||||
#include "ast/simplifiers/bv_bounds_simplifier.h"
 | 
			
		||||
 | 
			
		||||
tactic * mk_bv_bounds_tactic(ast_manager & m, params_ref const & p = params_ref());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +46,7 @@ tactic * mk_dom_bv_bounds_tactic(ast_manager & m, params_ref const & p = params_
 | 
			
		|||
/*
 | 
			
		||||
  ADD_TACTIC("propagate-bv-bounds", "propagate bit-vector bounds by simplifying implied or contradictory bounds.", "mk_bv_bounds_tactic(m, p)")
 | 
			
		||||
 | 
			
		||||
  ADD_SIMPLIFIER("propagate-bv-bounds", "propagate bit-vector bounds by simplifying implied or contradictory bounds.", "mk_bv_bounds_simplifier")
 | 
			
		||||
 | 
			
		||||
  ADD_TACTIC("propagate-bv-bounds2", "propagate bit-vector bounds by simplifying implied or contradictory bounds.", "mk_dom_bv_bounds_tactic(m, p)")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,4 +100,5 @@ inline tactic * mk_demodulator_tactic(ast_manager& m, params_ref const& p = para
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("demodulator", "extracts equalities from quantifiers and applies them to simplify.", "mk_demodulator_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("demodulator", "extracts equalities from quantifiers and applies them to simplify.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(demodulator_simplifier, m, p, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,5 +50,6 @@ inline tactic * mk_distribute_forall_tactic(ast_manager& m, params_ref const& p
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("distribute-forall", "distribute forall over conjunctions.", "mk_distribute_forall_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("distribute-forall", "distribute forall over conjunctions.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(distribute_forall_simplifier, m, p, s); }")
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,5 +56,6 @@ inline tactic* mk_dom_simplify_tactic(ast_manager& m, params_ref const& p) {
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
ADD_TACTIC("dom-simplify", "apply dominator simplification rules.", "mk_dom_simplify_tactic(m, p)")
 | 
			
		||||
ADD_SIMPLIFIER("dom-simplify", "apply dominator simplification rules.", "[](auto& m, auto& p, auto& s) -> dependent_expr_simplifier* { return alloc(dominator_simplifier, m, s, mk_expr_substitution_simplifier(m), p); }")
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,4 +118,5 @@ inline tactic * mk_elim_uncnstr2_tactic(ast_manager & m, params_ref const & p =
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("elim-uncnstr2", "eliminate unconstrained variables.", "mk_elim_uncnstr2_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("elim-unconstrained", "eliminate unconstrained variables.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(elim_unconstrained, m, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,4 +64,5 @@ inline tactic * mk_eliminate_predicates_tactic(ast_manager& m, params_ref const&
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("elim-predicates", "eliminate predicates.", "mk_eliminate_predicates_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("elim-predicates", "eliminate predicates.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(eliminate_predicates, m, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,4 +55,5 @@ inline tactic * mk_propagate_values2_tactic(ast_manager & m, params_ref const &
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("propagate-values2", "propagate constants.", "mk_propagate_values2_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("propagate-values", "propagate constants.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(propagate_values, m, p, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,5 +79,7 @@ inline tactic* mk_reduce_args_tactic2(ast_manager& m, params_ref const& p = para
 | 
			
		|||
}
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("reduce-args2", "reduce the number of arguments of function applications, when for all occurrences of a function f the i-th is a value.", "mk_reduce_args_tactic2(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("reduce-args", "reduce the number of arguments of function applications, when for all occurrences of a function f the i-th is a value.", "[](auto& m, auto& p, auto& s) -> dependent_expr_simplifier* { return mk_reduce_args_simplifier(m, s, p); }")
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,4 +79,5 @@ inline tactic * mk_solve_eqs_tactic(ast_manager& m, params_ref const& p = params
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
  ADD_TACTIC("solve-eqs", "solve for variables.", "mk_solve_eqs_tactic(m, p)")
 | 
			
		||||
  ADD_SIMPLIFIER("solve-eqs", "solve for variables.", "[](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return alloc(euf::solve_eqs, m, s); }")
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue