3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-07 18:05:21 +00:00
z3/lib/func_interp.h
Leonardo de Moura e9eab22e5c Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:35:25 -07:00

115 lines
3.7 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
func_interp.h
Abstract:
Support for function graphs (aka interpretations for functions).
They are used during model construction, and for evaluating expressions
modulo a model.
Main goal: Remove some code duplication and make the evaluator more efficient.
Example of code duplication that existed in Z3:
- smt_model_generator was creating func_values that were essentially partial func_interps
- smt_model_generator was creating if-then-else (lambda) exprs representing func_values
- the model object was converting these lambdas back into func_graphs (a limited version of func_interps).
- the smt_model_finder needs to manipulate func_interps, but the func_values in smt_model_generator
were private and too restrictive.
Author:
Leonardo de Moura (leonardo) 2010-12-30.
Revision History:
--*/
#ifndef _FUNC_INTERP_H
#define _FUNC_INTERP_H
#include"ast.h"
#include"ast_translation.h"
class func_interp;
class simplifier;
class func_entry {
bool m_args_are_values; //!< true if is_value(m_args[i]) is true for all i in [0, arity)
// m_result and m_args[i] must be ground terms.
expr * m_result;
expr * m_args[];
static unsigned get_obj_size(unsigned arity) { return sizeof(func_entry) + arity * sizeof(expr*); }
func_entry(ast_manager & m, unsigned arity, expr * const * args, expr * result);
friend class func_interp;
void set_result(ast_manager & m, expr * r);
bool args_are_values() const { return m_args_are_values; }
public:
static func_entry * mk(ast_manager & m, unsigned arity, expr * const * args, expr * result);
void deallocate(ast_manager & m, unsigned arity);
expr * get_result() const { return m_result; }
expr * get_arg(unsigned idx) const { return m_args[idx]; }
expr * const * get_args() const { return m_args; }
/**
\brief Return true if m_args[i] == args[i] for all i in [0, arity)
*/
bool eq_args(unsigned arity, expr * const * args) const;
};
class func_interp {
ast_manager & m_manager;
unsigned m_arity;
ptr_vector<func_entry> m_entries;
expr * m_else;
bool m_args_are_values; //!< true if forall e in m_entries e.args_are_values() == true
expr * m_interp; //!< cache for representing the whole interpretation as a single expression (it uses ite terms).
void reset_interp_cache();
expr * get_interp_core() const;
public:
func_interp(ast_manager & m, unsigned arity);
~func_interp();
func_interp * copy() const;
unsigned get_arity() const { return m_arity; }
bool is_partial() const { return m_else == 0; }
// A function interpretation is said to be simple if m_else is ground.
bool is_simple() const { return is_partial() || is_ground(m_else); }
bool is_constant() const;
expr * get_else() const { return m_else; }
void set_else(expr * e);
void insert_entry(expr * const * args, expr * r);
void insert_new_entry(expr * const * args, expr * r);
func_entry * get_entry(expr * const * args) const;
bool eval_else(expr * const * args, expr_ref & result) const;
bool eval(simplifier & s, expr * const * args, expr_ref & result);
unsigned num_entries() const { return m_entries.size(); }
func_entry const * const * get_entries() const { return m_entries.c_ptr(); }
func_entry const * get_entry(unsigned idx) const { return m_entries[idx]; }
expr * get_max_occ_result() const;
void compress();
expr * get_interp() const;
func_interp * translate(ast_translation & translator) const;
};
#endif