mirror of
https://github.com/Z3Prover/z3
synced 2025-04-22 16:45:31 +00:00
Rewrite spacer::sym_mux
Simpler implementation that only provides functionality actually used by spacer
This commit is contained in:
parent
268274911a
commit
38c2b56f0e
4 changed files with 138 additions and 282 deletions
|
@ -170,42 +170,25 @@ void inductive_property::display(datalog::rule_manager& rm, ptr_vector<datalog::
|
|||
}
|
||||
|
||||
|
||||
static std::vector<std::string> state_suffixes() {
|
||||
std::vector<std::string> res;
|
||||
res.push_back("_n");
|
||||
return res;
|
||||
}
|
||||
|
||||
manager::manager(ast_manager& manager) :
|
||||
m(manager), m_mux(m, state_suffixes()) {
|
||||
}
|
||||
manager::manager(ast_manager& manager) : m(manager), m_mux(m) {}
|
||||
|
||||
|
||||
void manager::add_new_state(func_decl * s)
|
||||
{
|
||||
SASSERT(s->get_arity() == 0); //we currently don't support non-constant states
|
||||
decl_vector vect;
|
||||
|
||||
SASSERT(o_index(0) == 1); //we assume this in the number of retrieved symbols
|
||||
m_mux.create_tuple(s, s->get_arity(), s->get_domain(), s->get_range(), 2, vect);
|
||||
}
|
||||
|
||||
func_decl * manager::get_o_pred(func_decl* s, unsigned idx)
|
||||
{
|
||||
func_decl * res = m_mux.try_get_by_prefix(s, o_index(idx));
|
||||
if (res) { return res; }
|
||||
add_new_state(s);
|
||||
res = m_mux.try_get_by_prefix(s, o_index(idx));
|
||||
func_decl * manager::get_o_pred(func_decl* s, unsigned idx) {
|
||||
func_decl * res = m_mux.find_by_decl(s, o_index(idx));
|
||||
if (!res) {
|
||||
m_mux.register_decl(s);
|
||||
res = m_mux.find_by_decl(s, o_index(idx));
|
||||
}
|
||||
SASSERT(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
func_decl * manager::get_n_pred(func_decl* s)
|
||||
{
|
||||
func_decl * res = m_mux.try_get_by_prefix(s, n_index());
|
||||
if (res) { return res; }
|
||||
add_new_state(s);
|
||||
res = m_mux.try_get_by_prefix(s, n_index());
|
||||
func_decl * manager::get_n_pred(func_decl* s) {
|
||||
func_decl * res = m_mux.find_by_decl(s, n_index());
|
||||
if (!res) {
|
||||
m_mux.register_decl(s);
|
||||
res = m_mux.find_by_decl(s, n_index());
|
||||
}
|
||||
SASSERT(res);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -83,8 +83,6 @@ class manager {
|
|||
unsigned n_index() const { return 0; }
|
||||
unsigned o_index(unsigned i) const { return i + 1; }
|
||||
|
||||
void add_new_state(func_decl * s);
|
||||
|
||||
public:
|
||||
manager(ast_manager & manager);
|
||||
|
||||
|
@ -100,27 +98,27 @@ public:
|
|||
{return m_mux.is_homogenous_formula(f, n_index());}
|
||||
|
||||
func_decl * o2n(func_decl * p, unsigned o_idx) const
|
||||
{return m_mux.conv(p, o_index(o_idx), n_index());}
|
||||
{return m_mux.shift_decl(p, o_index(o_idx), n_index());}
|
||||
func_decl * o2o(func_decl * p, unsigned src_idx, unsigned tgt_idx) const
|
||||
{return m_mux.conv(p, o_index(src_idx), o_index(tgt_idx));}
|
||||
{return m_mux.shift_decl(p, o_index(src_idx), o_index(tgt_idx));}
|
||||
func_decl * n2o(func_decl * p, unsigned o_idx) const
|
||||
{return m_mux.conv(p, n_index(), o_index(o_idx));}
|
||||
{return m_mux.shift_decl(p, n_index(), o_index(o_idx));}
|
||||
|
||||
void formula_o2n(expr * f, expr_ref & result, unsigned o_idx,
|
||||
bool homogenous = true) const
|
||||
{m_mux.conv_formula(f, o_index(o_idx), n_index(), result, homogenous);}
|
||||
{m_mux.shift_expr(f, o_index(o_idx), n_index(), result, homogenous);}
|
||||
|
||||
void formula_n2o(expr * f, expr_ref & result, unsigned o_idx,
|
||||
bool homogenous = true) const
|
||||
{m_mux.conv_formula(f, n_index(), o_index(o_idx), result, homogenous);}
|
||||
{m_mux.shift_expr(f, n_index(), o_index(o_idx), result, homogenous);}
|
||||
|
||||
void formula_n2o(unsigned o_idx, bool homogenous, expr_ref & result) const
|
||||
{m_mux.conv_formula(result.get(), n_index(), o_index(o_idx),
|
||||
{m_mux.shift_expr(result.get(), n_index(), o_index(o_idx),
|
||||
result, homogenous);}
|
||||
|
||||
void formula_o2o(expr * src, expr_ref & tgt, unsigned src_idx,
|
||||
unsigned tgt_idx, bool homogenous = true) const
|
||||
{m_mux.conv_formula(src, o_index(src_idx), o_index(tgt_idx),
|
||||
{m_mux.shift_expr(src, o_index(src_idx), o_index(tgt_idx),
|
||||
tgt, homogenous);}
|
||||
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
Copyright (c) 2018 Arie Gurfinkel and Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
|
@ -7,10 +7,12 @@ Module Name:
|
|||
|
||||
Abstract:
|
||||
|
||||
A symbol multiplexer that helps with having multiple versions of each of a set of symbols.
|
||||
A symbol multiplexer that helps with having multiple versions of
|
||||
each of a set of symbols.
|
||||
|
||||
Author:
|
||||
|
||||
Arie Gurfinkel
|
||||
Krystof Hoder (t-khoder) 2011-9-8.
|
||||
|
||||
Revision History:
|
||||
|
@ -22,166 +24,114 @@ Revision History:
|
|||
#include "ast/rewriter/rewriter.h"
|
||||
#include "ast/rewriter/rewriter_def.h"
|
||||
|
||||
#include "model/model.h"
|
||||
|
||||
#include "muz/spacer/spacer_util.h"
|
||||
#include "muz/spacer/spacer_sym_mux.h"
|
||||
|
||||
using namespace spacer;
|
||||
|
||||
sym_mux::sym_mux(ast_manager & m, const std::vector<std::string> & suffixes)
|
||||
: m(m), m_ref_holder(m), m_next_sym_suffix_idx(0), m_suffixes(suffixes)
|
||||
{
|
||||
for (std::string const& s : m_suffixes) {
|
||||
m_used_suffixes.insert(symbol(s.c_str()));
|
||||
sym_mux::sym_mux(ast_manager & m) : m(m) {}
|
||||
sym_mux::~sym_mux() {
|
||||
for (auto &entry : m_entries) {
|
||||
dealloc(entry.m_value);
|
||||
}
|
||||
}
|
||||
|
||||
std::string sym_mux::get_suffix(unsigned i) const
|
||||
{
|
||||
while (m_suffixes.size() <= i) {
|
||||
std::string new_suffix;
|
||||
symbol new_syffix_sym;
|
||||
do {
|
||||
std::stringstream stm;
|
||||
stm << '_' << m_next_sym_suffix_idx;
|
||||
m_next_sym_suffix_idx++;
|
||||
new_suffix = stm.str();
|
||||
new_syffix_sym = symbol(new_suffix.c_str());
|
||||
} while (m_used_suffixes.contains(new_syffix_sym));
|
||||
m_used_suffixes.insert(new_syffix_sym);
|
||||
m_suffixes.push_back(new_suffix);
|
||||
}
|
||||
return m_suffixes[i];
|
||||
func_decl_ref sym_mux::mk_variant(func_decl *fdecl, unsigned i) const {
|
||||
func_decl_ref v(m);
|
||||
std::string name = fdecl->get_name().str();
|
||||
std::string suffix = "_";
|
||||
suffix += i == 0 ? "n" : std::to_string(i - 1);
|
||||
name += suffix;
|
||||
v = m.mk_func_decl(symbol(name.c_str()), fdecl->get_arity(),
|
||||
fdecl->get_domain(), fdecl->get_range());
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
populates a vector called tuple with func_decl's
|
||||
tuple[0] is called primary and is used as key in various maps
|
||||
*/
|
||||
void sym_mux::create_tuple(func_decl* prefix, unsigned arity,
|
||||
sort * const * domain, sort * range,
|
||||
unsigned tuple_length, decl_vector & tuple)
|
||||
{
|
||||
SASSERT(tuple_length > 0);
|
||||
while (tuple.size() < tuple_length) {
|
||||
tuple.push_back(0);
|
||||
}
|
||||
SASSERT(tuple.size() == tuple_length);
|
||||
for (unsigned i = 0; i < tuple_length; i++) {
|
||||
void sym_mux::register_decl(func_decl *fdecl) {
|
||||
sym_mux_entry *entry = alloc(sym_mux_entry, m);
|
||||
entry->m_main = fdecl;
|
||||
entry->m_variants.push_back(mk_variant(fdecl, 0));
|
||||
entry->m_variants.push_back(mk_variant(fdecl, 1));
|
||||
|
||||
if (tuple[i] != 0) {
|
||||
SASSERT(tuple[i]->get_arity() == arity);
|
||||
SASSERT(tuple[i]->get_range() == range);
|
||||
//domain should match as well, but we won't bother
|
||||
//checking an array equality
|
||||
} else {
|
||||
std::string name = prefix->get_name().str();
|
||||
name += get_suffix(i);
|
||||
tuple[i] = m.mk_func_decl(symbol(name.c_str()), arity,
|
||||
domain, range);
|
||||
}
|
||||
m_ref_holder.push_back(tuple[i]);
|
||||
m_sym2idx.insert(tuple[i], i);
|
||||
m_sym2prim.insert(tuple[i], tuple[0]);
|
||||
}
|
||||
|
||||
m_prim2all.insert(tuple[0], tuple);
|
||||
m_prefix2prim.insert(prefix, tuple[0]);
|
||||
m_prim2prefix.insert(tuple[0], prefix);
|
||||
m_ref_holder.push_back(prefix);
|
||||
m_entries.insert(fdecl, entry);
|
||||
m_muxes.insert(entry->m_variants.get(0), std::make_pair(entry, 0));
|
||||
m_muxes.insert(entry->m_variants.get(1), std::make_pair(entry, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
extends a tuple in which prim is primary to the given size
|
||||
*/
|
||||
void sym_mux::ensure_tuple_size(func_decl * prim, unsigned sz) const
|
||||
{
|
||||
SASSERT(m_prim2all.contains(prim));
|
||||
decl_vector& tuple = m_prim2all.find_core(prim)->get_data().m_value;
|
||||
SASSERT(tuple[0] == prim);
|
||||
|
||||
if (sz <= tuple.size()) { return; }
|
||||
|
||||
func_decl * prefix;
|
||||
TRUSTME(m_prim2prefix.find(prim, prefix));
|
||||
std::string prefix_name = prefix->get_name().bare_str();
|
||||
for (unsigned i = tuple.size(); i < sz; ++i) {
|
||||
std::string name = prefix_name + get_suffix(i);
|
||||
func_decl * new_sym =
|
||||
m.mk_func_decl(symbol(name.c_str()), prefix->get_arity(),
|
||||
prefix->get_domain(), prefix->get_range());
|
||||
|
||||
tuple.push_back(new_sym);
|
||||
m_ref_holder.push_back(new_sym);
|
||||
m_sym2idx.insert(new_sym, i);
|
||||
m_sym2prim.insert(new_sym, prim);
|
||||
void sym_mux::ensure_capacity(sym_mux_entry &entry, unsigned sz) {
|
||||
while (entry.m_variants.size() < sz) {
|
||||
unsigned idx = entry.m_variants.size();
|
||||
entry.m_variants.push_back (mk_variant(entry.m_main, idx));
|
||||
m_muxes.insert(entry.m_variants.back(), std::make_pair(&entry, idx));
|
||||
}
|
||||
}
|
||||
|
||||
/** given a func_decl with src_idx returns its version with tgt_idx */
|
||||
func_decl * sym_mux::conv(func_decl * sym,
|
||||
unsigned src_idx, unsigned tgt_idx) const {
|
||||
if (src_idx == tgt_idx) { return sym; }
|
||||
func_decl * prim = (src_idx == 0) ? sym : get_primary(sym);
|
||||
if (tgt_idx > src_idx) {
|
||||
ensure_tuple_size(prim, tgt_idx + 1);
|
||||
}
|
||||
decl_vector & sym_vect = m_prim2all.find_core(prim)->get_data().m_value;
|
||||
SASSERT(sym_vect[src_idx] == sym);
|
||||
return sym_vect[tgt_idx];
|
||||
bool sym_mux::find_idx(func_decl * sym, unsigned & idx) const {
|
||||
std::pair<sym_mux_entry *, unsigned> entry;
|
||||
if (m_muxes.find(sym, entry)) {idx = entry.second; return true;}
|
||||
return false;
|
||||
}
|
||||
|
||||
func_decl * sym_mux::find_by_decl(func_decl* fdecl, unsigned idx) {
|
||||
sym_mux_entry *entry = nullptr;
|
||||
if (m_entries.find(fdecl, entry)) {
|
||||
ensure_capacity(*entry, idx+1);
|
||||
return entry->m_variants.get(idx);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct sym_mux::formula_checker {
|
||||
func_decl * sym_mux::shift_decl(func_decl * decl,
|
||||
unsigned src_idx, unsigned tgt_idx) const {
|
||||
std::pair<sym_mux_entry*,unsigned> entry;
|
||||
if (m_muxes.find(decl, entry)) {
|
||||
SASSERT(entry.second == src_idx);
|
||||
return entry.first->m_variants.get(tgt_idx);
|
||||
}
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct formula_checker {
|
||||
formula_checker(const sym_mux & parent, unsigned idx) :
|
||||
m_parent(parent), m_idx(idx),
|
||||
m_found_what_needed(false) {}
|
||||
m_parent(parent), m_idx(idx), m_found(false) {}
|
||||
|
||||
void operator()(expr * e)
|
||||
{
|
||||
if (m_found_what_needed || !is_app(e)) { return; }
|
||||
void operator()(expr * e) {
|
||||
if (m_found || !is_app(e)) { return; }
|
||||
|
||||
func_decl * sym = to_app(e)->get_decl();
|
||||
unsigned sym_idx;
|
||||
if (!m_parent.try_get_index(sym, sym_idx)) { return; }
|
||||
if (!m_parent.find_idx(sym, sym_idx)) { return; }
|
||||
|
||||
bool have_idx = sym_idx == m_idx;
|
||||
m_found_what_needed = !have_idx;
|
||||
|
||||
m_found = !have_idx;
|
||||
}
|
||||
|
||||
bool all_have_idx() const {return !m_found_what_needed;}
|
||||
|
||||
bool all_have_idx() const {return !m_found;}
|
||||
|
||||
private:
|
||||
const sym_mux & m_parent;
|
||||
unsigned m_idx;
|
||||
|
||||
/**
|
||||
If we check whether all muxed symbols are of given index, we look for
|
||||
counter-examples, checking whether form contains a muxed symbol of an index,
|
||||
we look for symbol of index m_idx.
|
||||
*/
|
||||
bool m_found_what_needed;
|
||||
bool m_found;
|
||||
};
|
||||
|
||||
|
||||
bool sym_mux::is_homogenous_formula(expr * e, unsigned idx) const
|
||||
{
|
||||
expr_mark visited;
|
||||
formula_checker chck(*this, idx);
|
||||
for_each_expr(chck, visited, e);
|
||||
return chck.all_have_idx();
|
||||
}
|
||||
|
||||
struct sym_mux::conv_rewriter_cfg : public default_rewriter_cfg {
|
||||
bool sym_mux::is_homogenous_formula(expr * e, unsigned idx) const {
|
||||
expr_mark visited;
|
||||
formula_checker fck(*this, idx);
|
||||
for_each_expr(fck, visited, e);
|
||||
return fck.all_have_idx();
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct conv_rewriter_cfg : public default_rewriter_cfg {
|
||||
private:
|
||||
ast_manager & m;
|
||||
const sym_mux & m_parent;
|
||||
unsigned m_from_idx;
|
||||
unsigned m_to_idx;
|
||||
bool m_homogenous;
|
||||
expr_ref_vector m_pinned;
|
||||
public:
|
||||
conv_rewriter_cfg(const sym_mux & parent, unsigned from_idx,
|
||||
unsigned to_idx, bool homogenous)
|
||||
|
@ -189,7 +139,7 @@ public:
|
|||
m_parent(parent),
|
||||
m_from_idx(from_idx),
|
||||
m_to_idx(to_idx),
|
||||
m_homogenous(homogenous) {}
|
||||
m_homogenous(homogenous), m_pinned(m) {(void) m_homogenous;}
|
||||
|
||||
bool get_subst(expr * s, expr * & t, proof * & t_pr)
|
||||
{
|
||||
|
@ -197,24 +147,23 @@ public:
|
|||
app * a = to_app(s);
|
||||
func_decl * sym = a->get_decl();
|
||||
if (!m_parent.has_index(sym, m_from_idx)) {
|
||||
(void) m_homogenous;
|
||||
SASSERT(!m_homogenous || !m_parent.is_muxed(sym));
|
||||
return false;
|
||||
}
|
||||
func_decl * tgt = m_parent.conv(sym, m_from_idx, m_to_idx);
|
||||
|
||||
func_decl * tgt = m_parent.shift_decl(sym, m_from_idx, m_to_idx);
|
||||
t = m.mk_app(tgt, a->get_args());
|
||||
m_pinned.push_back(t);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void sym_mux::conv_formula(expr * f, unsigned src_idx, unsigned tgt_idx,
|
||||
expr_ref & res, bool homogenous) const {
|
||||
if (src_idx == tgt_idx) {
|
||||
res = f;
|
||||
return;
|
||||
}
|
||||
conv_rewriter_cfg r_cfg(*this, src_idx, tgt_idx, homogenous);
|
||||
rewriter_tpl<conv_rewriter_cfg> rwr(m, false, r_cfg);
|
||||
rwr(f, res);
|
||||
}
|
||||
|
||||
void sym_mux::shift_expr(expr * f, unsigned src_idx, unsigned tgt_idx,
|
||||
expr_ref & res, bool homogenous) const {
|
||||
if (src_idx == tgt_idx) {res = f;}
|
||||
else {
|
||||
conv_rewriter_cfg r_cfg(*this, src_idx, tgt_idx, homogenous);
|
||||
rewriter_tpl<conv_rewriter_cfg> rwr(m, false, r_cfg);
|
||||
rwr(f, res);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
Copyright (c) 2018 Arie Gurfinkel and Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
|
@ -12,6 +12,7 @@ Abstract:
|
|||
|
||||
Author:
|
||||
|
||||
Arie Gurfinkel
|
||||
Krystof Hoder (t-khoder) 2011-9-8.
|
||||
|
||||
Revision History:
|
||||
|
@ -21,144 +22,69 @@ Revision History:
|
|||
#ifndef _SYM_MUX_H_
|
||||
#define _SYM_MUX_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "ast/ast.h"
|
||||
#include "util/map.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
class model_core;
|
||||
|
||||
namespace spacer {
|
||||
class sym_mux {
|
||||
private:
|
||||
typedef obj_map<func_decl, unsigned> sym2u;
|
||||
typedef obj_map<func_decl, decl_vector> sym2dv;
|
||||
typedef obj_map<func_decl, func_decl *> sym2sym;
|
||||
typedef obj_map<func_decl, func_decl *> sym2pred;
|
||||
typedef hashtable<symbol, symbol_hash_proc, symbol_eq_proc> symbols;
|
||||
class sym_mux_entry {
|
||||
public:
|
||||
func_decl_ref m_main;
|
||||
func_decl_ref_vector m_variants;
|
||||
sym_mux_entry(ast_manager &m) : m_main(m), m_variants(m) {};
|
||||
};
|
||||
|
||||
ast_manager & m;
|
||||
mutable ast_ref_vector m_ref_holder;
|
||||
typedef obj_map<func_decl, sym_mux_entry*> decl2entry_map;
|
||||
typedef obj_map<func_decl, std::pair<sym_mux_entry*, unsigned> > mux2entry_map;
|
||||
|
||||
mutable unsigned m_next_sym_suffix_idx;
|
||||
mutable symbols m_used_suffixes;
|
||||
/** Here we have default suffixes for each of the variants */
|
||||
mutable std::vector<std::string> m_suffixes;
|
||||
ast_manager &m;
|
||||
decl2entry_map m_entries;
|
||||
mux2entry_map m_muxes;
|
||||
|
||||
func_decl_ref mk_variant(func_decl *fdecl, unsigned i) const;
|
||||
void ensure_capacity(sym_mux_entry &entry, unsigned sz) ;
|
||||
|
||||
/**
|
||||
Primary symbol is the 0-th variant. This member maps from primary symbol
|
||||
to vector of all its variants (including the primary variant).
|
||||
*/
|
||||
sym2dv m_prim2all;
|
||||
|
||||
/**
|
||||
For each symbol contains its variant index
|
||||
*/
|
||||
mutable sym2u m_sym2idx;
|
||||
/**
|
||||
For each symbol contains its primary variant
|
||||
*/
|
||||
mutable sym2sym m_sym2prim;
|
||||
|
||||
/**
|
||||
Maps prefixes passed to the create_tuple to
|
||||
the primary symbol created from it.
|
||||
*/
|
||||
sym2pred m_prefix2prim;
|
||||
|
||||
/**
|
||||
Maps pripary symbols to prefixes that were used to create them.
|
||||
*/
|
||||
sym2sym m_prim2prefix;
|
||||
|
||||
|
||||
|
||||
struct formula_checker;
|
||||
struct conv_rewriter_cfg;
|
||||
|
||||
std::string get_suffix(unsigned i) const;
|
||||
void ensure_tuple_size(func_decl * prim, unsigned sz) const;
|
||||
|
||||
// expr_ref isolate_o_idx(expr* e, unsigned idx) const;
|
||||
public:
|
||||
sym_mux(ast_manager & m, const std::vector<std::string> & suffixes);
|
||||
|
||||
sym_mux(ast_manager & m);
|
||||
~sym_mux();
|
||||
ast_manager & get_manager() const { return m; }
|
||||
|
||||
bool is_muxed(func_decl * sym) const { return m_sym2idx.contains(sym); }
|
||||
|
||||
bool try_get_index(func_decl * sym, unsigned & idx) const
|
||||
{return m_sym2idx.find(sym, idx);}
|
||||
|
||||
void register_decl(func_decl *fdecl);
|
||||
bool find_idx(func_decl * sym, unsigned & idx) const;
|
||||
bool has_index(func_decl * sym, unsigned idx) const
|
||||
{
|
||||
unsigned actual_idx;
|
||||
return try_get_index(sym, actual_idx) && idx == actual_idx;
|
||||
}
|
||||
{unsigned v; return find_idx(sym, v) && idx == v;}
|
||||
|
||||
/** Return primary symbol. sym must be muxed. */
|
||||
func_decl * get_primary(func_decl * sym) const
|
||||
{
|
||||
func_decl * prim;
|
||||
TRUSTME(m_sym2prim.find(sym, prim));
|
||||
return prim;
|
||||
}
|
||||
|
||||
/**
|
||||
Return primary symbol created from prefix, or 0 if the prefix was never used.
|
||||
\brief Return symbol created from prefix, or 0 if the prefix
|
||||
was never used.
|
||||
*/
|
||||
func_decl * try_get_primary_by_prefix(func_decl* prefix) const
|
||||
{
|
||||
func_decl * res;
|
||||
if(!m_prefix2prim.find(prefix, res)) {
|
||||
return nullptr;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
func_decl * find_by_decl(func_decl* fdecl, unsigned idx);
|
||||
|
||||
/**
|
||||
Return symbol created from prefix, or 0 if the prefix was never used.
|
||||
*/
|
||||
func_decl * try_get_by_prefix(func_decl* prefix, unsigned idx) const
|
||||
{
|
||||
func_decl * prim = try_get_primary_by_prefix(prefix);
|
||||
if(!prim) {
|
||||
return nullptr;
|
||||
}
|
||||
return conv(prim, 0, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
Create a multiplexed tuple of propositional constants.
|
||||
Symbols may be suplied in the tuple vector,
|
||||
those beyond the size of the array and those with corresponding positions
|
||||
assigned to zero will be created using prefix.
|
||||
Tuple length must be at least one.
|
||||
*/
|
||||
void create_tuple(func_decl* prefix, unsigned arity, sort * const * domain, sort * range,
|
||||
unsigned tuple_length, decl_vector & tuple);
|
||||
|
||||
/**
|
||||
Return true if the only multiplexed symbols which e contains are of index idx.
|
||||
\brief Return true if the only multiplexed symbols which e contains are
|
||||
of index idx.
|
||||
*/
|
||||
bool is_homogenous_formula(expr * e, unsigned idx) const;
|
||||
|
||||
|
||||
/**
|
||||
Convert symbol sym which has to be of src_idx variant into variant tgt_idx.
|
||||
\brief Convert symbol sym which has to be of src_idx variant
|
||||
into variant tgt_idx.
|
||||
*/
|
||||
func_decl * conv(func_decl * sym, unsigned src_idx, unsigned tgt_idx) const;
|
||||
|
||||
func_decl * shift_decl(func_decl * sym, unsigned src_idx, unsigned tgt_idx) const;
|
||||
|
||||
/**
|
||||
Convert src_idx symbols in formula f variant into tgt_idx.
|
||||
If homogenous is true, formula cannot contain symbols of other variants.
|
||||
\brief Convert src_idx symbols in formula f variant into
|
||||
tgt_idx. If homogenous is true, formula cannot contain symbols
|
||||
of other variants.
|
||||
*/
|
||||
void conv_formula(expr * f, unsigned src_idx, unsigned tgt_idx,
|
||||
expr_ref & res, bool homogenous = true) const;
|
||||
void shift_expr(expr * f, unsigned src_idx, unsigned tgt_idx,
|
||||
expr_ref & res, bool homogenous = true) const;
|
||||
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue