3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-12-03 18:46:44 +00:00

Rewrite spacer::sym_mux

Simpler implementation that only provides functionality actually used
by spacer
This commit is contained in:
Arie Gurfinkel 2018-06-03 16:05:29 -07:00
parent 268274911a
commit 38c2b56f0e
4 changed files with 138 additions and 282 deletions

View file

@ -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;
};