All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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





© 2015 - 2024 Weber Informatics LLC | Privacy Policy