2015-09-25 19:45:16 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#pragma once
|
2015-10-31 01:14:34 +00:00
|
|
|
#include <memory>
|
2015-10-31 00:45:27 +00:00
|
|
|
#include "kernel/environment.h"
|
|
|
|
#include "library/io_state.h"
|
2015-11-01 06:57:34 +00:00
|
|
|
#include "library/tmp_type_context.h"
|
2015-11-18 02:44:11 +00:00
|
|
|
#include "library/relation_manager.h"
|
2015-11-08 01:42:58 +00:00
|
|
|
#include "library/congr_lemma_manager.h"
|
|
|
|
#include "library/fun_info_manager.h"
|
2015-10-31 00:45:27 +00:00
|
|
|
#include "library/blast/state.h"
|
2015-09-25 19:45:16 +00:00
|
|
|
|
|
|
|
namespace lean {
|
2015-10-31 00:45:27 +00:00
|
|
|
struct projection_info;
|
|
|
|
class goal;
|
2015-11-01 06:57:34 +00:00
|
|
|
typedef std::unique_ptr<tmp_type_context> tmp_type_context_ptr;
|
2015-10-31 00:45:27 +00:00
|
|
|
namespace blast {
|
|
|
|
/** \brief Return the thread local environment being used by the blast tactic. */
|
|
|
|
environment const & env();
|
|
|
|
/** \brief Return the thread local io_state being used by the blast tactic. */
|
|
|
|
io_state const & ios();
|
2015-11-08 21:09:48 +00:00
|
|
|
/** \brief Return reference to blast thread local app_builder */
|
|
|
|
app_builder & get_app_builder();
|
2015-11-12 00:11:51 +00:00
|
|
|
/** \brief Return reference to the main type context used by the blast tactic */
|
|
|
|
type_context & get_type_context();
|
2015-11-09 01:29:47 +00:00
|
|
|
/** \brief Return the thread local current state being processed by the blast tactic. */
|
2015-10-31 00:45:27 +00:00
|
|
|
state & curr_state();
|
2015-11-06 00:18:49 +00:00
|
|
|
/** \brief Return a thread local fresh local constant. */
|
2015-10-31 00:45:27 +00:00
|
|
|
expr mk_fresh_local(expr const & type, binder_info const & bi = binder_info());
|
2015-11-16 02:39:12 +00:00
|
|
|
bool is_fresh_local(expr const & e);
|
2015-10-31 00:45:27 +00:00
|
|
|
/** \brief Return true iff the given constant name is marked as reducible in env() */
|
|
|
|
bool is_reducible(name const & n);
|
|
|
|
/** \brief Return a nonnull projection_info object if \c n is the name of a projection in env() */
|
|
|
|
projection_info const * get_projection_info(name const & n);
|
2015-11-14 23:02:14 +00:00
|
|
|
/** \brief Return true iff \c e is a relation application,
|
|
|
|
and store the relation name, lhs and rhs in the output arguments. */
|
2015-11-18 02:44:11 +00:00
|
|
|
bool is_relation_app(expr const & e, name & rop, expr & lhs, expr & rhs);
|
|
|
|
bool is_relation_app(expr const & e);
|
|
|
|
optional<relation_info> get_relation_info(name const & rop);
|
|
|
|
inline optional<relation_info> is_relation(expr const & R) {
|
|
|
|
return is_constant(R) ? get_relation_info(const_name(R)) : optional<relation_info>();
|
|
|
|
}
|
2015-11-16 19:43:51 +00:00
|
|
|
bool is_reflexive(name const & rop);
|
2015-11-20 03:37:11 +00:00
|
|
|
bool is_symmetric(name const & rop);
|
2015-11-18 02:44:11 +00:00
|
|
|
|
2015-10-31 00:45:27 +00:00
|
|
|
/** \brief Put the given expression in weak-head-normal-form with respect to the
|
|
|
|
current state being processed by the blast tactic. */
|
|
|
|
expr whnf(expr const & e);
|
2015-11-16 02:00:32 +00:00
|
|
|
expr relaxed_whnf(expr const & e);
|
2015-11-13 04:38:54 +00:00
|
|
|
/** \brief Normalize the given expression using the blast type context.
|
|
|
|
This procedure caches results.
|
|
|
|
\remark This procedure is intended for normalizing instances that are not subsingletons. */
|
|
|
|
expr normalize(expr const & e);
|
|
|
|
|
2015-10-31 00:45:27 +00:00
|
|
|
/** \brief Return the type of the given expression with respect to the current state being
|
|
|
|
processed by the blast tactic.
|
|
|
|
|
|
|
|
\remark: (potential side-effect) this procedure may update the meta-variable assignment
|
|
|
|
associated with the current state. */
|
|
|
|
expr infer_type(expr const & e);
|
|
|
|
/** \brief Return true if \c e is a Proposition */
|
|
|
|
bool is_prop(expr const & e);
|
|
|
|
/** \brief Return true iff the two expressions are definitionally equal in the
|
|
|
|
current state being processed by the blast tactic.
|
|
|
|
|
|
|
|
\remark: (potential side-effect) this procedure may update the meta-variable assignment
|
|
|
|
associated with the current state. */
|
|
|
|
bool is_def_eq(expr const & e1, expr const & e2);
|
|
|
|
/** \brief Try to synthesize an element of the given type class with respect to the blast local context. */
|
|
|
|
optional<expr> mk_class_instance(expr const & e);
|
|
|
|
|
2015-11-08 01:42:58 +00:00
|
|
|
/** \brief Create a congruence lemma for the given function.
|
|
|
|
\pre num_args <= arity of fn
|
|
|
|
\remark The procedure may fail when app_builder used by it fails.
|
|
|
|
Example: it fail to infer the type of fn.
|
|
|
|
|
|
|
|
\remark The generated lemma is useful when performing rewriting.
|
|
|
|
For congruence closure, we must use a different lemma generator, or
|
|
|
|
at least, post-process the lemma generated by this procedure.
|
|
|
|
|
|
|
|
\remark The type \c congr_lemma is defined at library/congr_lemma_manager.h */
|
|
|
|
optional<congr_lemma> mk_congr_lemma_for_simp(expr const & fn, unsigned num_args);
|
|
|
|
/** \brief Similar to previous procedure, but num_args == arith of fn */
|
|
|
|
optional<congr_lemma> mk_congr_lemma_for_simp(expr const & fn);
|
|
|
|
|
2015-11-16 16:54:21 +00:00
|
|
|
/** \brief Create a congruence lemma for the given function.
|
|
|
|
\pre num_args <= arity of fn
|
|
|
|
\remark The procedure may fail when app_builder used by it fails.
|
|
|
|
Example: it fail to infer the type of fn.
|
|
|
|
|
|
|
|
\remark The generated lemma is useful for proving that two terms
|
|
|
|
that are definitionally equal upto subsingletons are propositionally
|
|
|
|
equal.
|
|
|
|
|
|
|
|
\remark The type \c congr_lemma is defined at library/congr_lemma_manager.h */
|
|
|
|
optional<congr_lemma> mk_congr_lemma(expr const & fn, unsigned num_args);
|
|
|
|
/** \brief Similar to previous procedure, but num_args == arith of fn */
|
|
|
|
optional<congr_lemma> mk_congr_lemma(expr const & fn);
|
2015-11-18 02:44:11 +00:00
|
|
|
optional<congr_lemma> mk_rel_iff_congr(expr const & fn);
|
|
|
|
optional<congr_lemma> mk_rel_eq_congr(expr const & fn);
|
2015-11-16 16:54:21 +00:00
|
|
|
|
2015-11-08 01:42:58 +00:00
|
|
|
/** \brief Retrieve information for the given function. */
|
|
|
|
fun_info get_fun_info(expr const & fn);
|
|
|
|
/** \brief Retrieve information for the given function.
|
|
|
|
\pre nargs <= arity fn. */
|
|
|
|
fun_info get_fun_info(expr const & fn, unsigned nargs);
|
|
|
|
|
2015-11-16 16:54:21 +00:00
|
|
|
/** \brief Hash and equality test for abstract expressions */
|
|
|
|
unsigned abstract_hash(expr const & e);
|
|
|
|
bool abstract_is_equal(expr const & e1, expr const & e2);
|
|
|
|
|
2015-10-31 00:45:27 +00:00
|
|
|
/** \brief Display the current state of the blast tactic in the diagnostic channel. */
|
|
|
|
void display_curr_state();
|
2015-10-31 01:14:34 +00:00
|
|
|
/** \brief Display the given expression in the diagnostic channel. */
|
|
|
|
void display_expr(expr const & e);
|
2015-10-31 00:45:27 +00:00
|
|
|
/** \brief Display message in the blast tactic diagnostic channel. */
|
|
|
|
void display(char const * msg);
|
|
|
|
void display(sstream const & msg);
|
2015-12-03 01:28:53 +00:00
|
|
|
/** \brief Create a local scope for saving the assignment and
|
2015-10-31 00:45:27 +00:00
|
|
|
metavariable declarations at curr_state() */
|
2015-10-31 01:14:34 +00:00
|
|
|
class scope_assignment {
|
2015-10-31 00:45:27 +00:00
|
|
|
bool m_keep;
|
|
|
|
public:
|
2015-10-31 01:14:34 +00:00
|
|
|
scope_assignment();
|
|
|
|
~scope_assignment();
|
2015-10-31 00:45:27 +00:00
|
|
|
void commit();
|
|
|
|
};
|
2015-10-31 01:14:34 +00:00
|
|
|
|
2015-12-03 01:28:53 +00:00
|
|
|
typedef std::function<bool(expr const &)> unfold_macro_pred;
|
|
|
|
/** \brief Auxiliary object used to temporarily set predicate used to decide
|
|
|
|
whether macros will be unfolded or not. */
|
|
|
|
class scope_unfold_macro_pred {
|
|
|
|
unfold_macro_pred m_old_pred;
|
|
|
|
public:
|
|
|
|
scope_unfold_macro_pred(unfold_macro_pred const & pred);
|
|
|
|
~scope_unfold_macro_pred();
|
|
|
|
};
|
2015-10-31 01:14:34 +00:00
|
|
|
|
2015-12-03 01:28:53 +00:00
|
|
|
/** \brief Auxiliary object for setting thread local storage associated with blast tactic.
|
2015-10-31 01:14:34 +00:00
|
|
|
This is for debugging purposes only. It allow us to debug/test procedures that can
|
|
|
|
only be invoked from blast. */
|
|
|
|
class scope_debug {
|
|
|
|
struct imp;
|
|
|
|
std::unique_ptr<imp> m_imp;
|
|
|
|
public:
|
|
|
|
scope_debug(environment const & env, io_state const & ios);
|
|
|
|
~scope_debug();
|
|
|
|
};
|
2015-11-01 06:57:34 +00:00
|
|
|
|
2015-11-04 20:29:28 +00:00
|
|
|
|
2015-11-01 06:57:34 +00:00
|
|
|
/** \brief Create a temporary type_context that is compatible with blast.
|
|
|
|
This temporary type context can acces the type of blast hypotheses
|
|
|
|
and meta-variables. */
|
2015-11-04 20:29:28 +00:00
|
|
|
class blast_tmp_type_context {
|
|
|
|
tmp_type_context * m_ctx;
|
|
|
|
public:
|
2015-11-06 00:07:11 +00:00
|
|
|
blast_tmp_type_context(unsigned num_umeta, unsigned num_emeta);
|
2015-11-04 20:29:28 +00:00
|
|
|
blast_tmp_type_context();
|
|
|
|
~blast_tmp_type_context();
|
|
|
|
|
|
|
|
tmp_type_context const * operator->() const { return m_ctx; }
|
|
|
|
tmp_type_context * operator->() { return m_ctx; }
|
|
|
|
tmp_type_context const & operator*() const { return *m_ctx; }
|
|
|
|
tmp_type_context & operator*() { return *m_ctx; }
|
|
|
|
};
|
2015-11-04 23:52:38 +00:00
|
|
|
|
2015-11-16 02:00:32 +00:00
|
|
|
class scope_curr_state {
|
|
|
|
state m_saved;
|
|
|
|
bool m_keep;
|
|
|
|
public:
|
|
|
|
scope_curr_state():m_saved(curr_state()), m_keep(false) {}
|
|
|
|
~scope_curr_state() { if (!m_keep) curr_state() = m_saved; }
|
|
|
|
void commit() { m_keep = true; }
|
|
|
|
};
|
|
|
|
|
2015-11-04 23:52:38 +00:00
|
|
|
/**
|
|
|
|
\brief Convert an external expression into a blast expression
|
|
|
|
It converts meta-variables to blast meta-variables, and ensures the expressions
|
|
|
|
are maximally shared.
|
|
|
|
\remark This procedure should only be used for **debugging purposes**. */
|
|
|
|
expr internalize(expr const & e);
|
2015-10-31 00:45:27 +00:00
|
|
|
}
|
2015-09-25 19:45:16 +00:00
|
|
|
optional<expr> blast_goal(environment const & env, io_state const & ios, list<name> const & ls, list<name> const & ds,
|
|
|
|
goal const & g);
|
2015-09-25 21:43:42 +00:00
|
|
|
void initialize_blast();
|
|
|
|
void finalize_blast();
|
2015-09-25 19:45:16 +00:00
|
|
|
}
|