z3-z3-4.13.0.src.model.func_interp.h Maven / Gradle / Ivy
The newest version!
/*++
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:
--*/
#pragma once
#include "ast/ast.h"
#include "ast/ast_translation.h"
class func_interp;
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);
public:
static func_entry * mk(ast_manager & m, unsigned arity, expr * const * args, expr * result);
bool args_are_values() const { return m_args_are_values; }
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.are_equal(m_args[i], args[i]) for all i in [0, arity)
*/
bool eq_args(ast_manager & m, unsigned arity, expr * const * args) const;
};
class func_interp {
ast_manager & m_manager;
unsigned m_arity;
ptr_vector 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).
expr * m_array_interp; // ::const_iterator begin() const { return m_entries.begin(); }
ptr_vector::const_iterator end() const { return m_entries.end(); }
func_entry const * const * get_entries() const { return m_entries.data(); }
func_entry const * get_entry(unsigned idx) const { return m_entries[idx]; }
void del_entry(unsigned idx);
expr * get_max_occ_result() const;
void compress();
expr * get_interp() const;
expr_ref get_array_interp(func_decl* f) const;
func_interp * translate(ast_translation & translator) const;
private:
bool is_fi_entry_expr(expr * e, ptr_vector & args);
bool is_identity() const;
};