2014-11-11 20:26:26 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "kernel/environment.h"
|
2014-12-19 22:40:15 +00:00
|
|
|
#include "kernel/type_checker.h"
|
2014-11-11 20:26:26 +00:00
|
|
|
|
|
|
|
namespace lean {
|
2014-12-19 22:40:15 +00:00
|
|
|
typedef std::unique_ptr<type_checker> type_checker_ptr;
|
|
|
|
|
2015-01-20 23:42:51 +00:00
|
|
|
/** \brief Return true iff \c e is of the form <tt>(f ...)</tt> where
|
|
|
|
\c f is a non-opaque constant definition */
|
|
|
|
bool is_def_app(environment const & env, expr const & e);
|
|
|
|
|
|
|
|
/** \brief If \c e is of the form <tt>(f a_1 ... a_n)</tt>, where \c f is
|
|
|
|
a non-opaque definition, then unfold \c f, and beta reduce.
|
|
|
|
Otherwise, return none.
|
|
|
|
*/
|
|
|
|
optional<expr> unfold_app(environment const & env, expr const & e);
|
|
|
|
|
2015-01-04 21:25:58 +00:00
|
|
|
/** \brief Reduce (if possible) universe level by 1.
|
|
|
|
\pre is_not_zero(l)
|
|
|
|
*/
|
|
|
|
optional<level> dec_level(level const & l);
|
|
|
|
|
2014-11-11 21:46:36 +00:00
|
|
|
bool has_unit_decls(environment const & env);
|
|
|
|
bool has_eq_decls(environment const & env);
|
|
|
|
bool has_heq_decls(environment const & env);
|
2014-11-11 22:55:21 +00:00
|
|
|
bool has_prod_decls(environment const & env);
|
2014-12-09 06:11:48 +00:00
|
|
|
bool has_lift_decls(environment const & env);
|
2014-11-11 20:26:26 +00:00
|
|
|
/** \brief Return true iff \c n is the name of a recursive datatype in \c env.
|
|
|
|
That is, it must be an inductive datatype AND contain a recursive constructor.
|
|
|
|
|
|
|
|
\remark Records are inductive datatypes, but they are not recursive.
|
|
|
|
|
2014-11-11 21:24:58 +00:00
|
|
|
\remark For mutually indutive datatypes, \c n is considered recursive
|
2014-11-11 20:26:26 +00:00
|
|
|
if there is a constructor taking \c n.
|
|
|
|
*/
|
|
|
|
bool is_recursive_datatype(environment const & env, name const & n);
|
2014-11-11 21:24:58 +00:00
|
|
|
|
2014-12-02 01:11:06 +00:00
|
|
|
/** \brief Return true if \c n is a recursive *and* reflexive datatype.
|
|
|
|
|
|
|
|
We say an inductive type T is reflexive if it contains at least one constructor that
|
|
|
|
takes as an argument a function returning T.
|
|
|
|
*/
|
|
|
|
bool is_reflexive_datatype(type_checker & tc, name const & n);
|
|
|
|
|
2014-11-11 21:24:58 +00:00
|
|
|
/** \brief Return true iff \c n is an inductive predicate, i.e., an inductive datatype that is in Prop.
|
|
|
|
|
|
|
|
\remark If \c env does not have Prop (i.e., Type.{0} is not impredicative), then this method always return false.
|
|
|
|
*/
|
|
|
|
bool is_inductive_predicate(environment const & env, name const & n);
|
2014-11-11 22:55:21 +00:00
|
|
|
|
2014-12-20 19:30:41 +00:00
|
|
|
/** \brief Store in \c result the introduction rules of the given inductive datatype.
|
|
|
|
\remark this procedure does nothing if \c n is not an inductive datatype.
|
|
|
|
*/
|
|
|
|
void get_intro_rule_names(environment const & env, name const & n, buffer<name> & result);
|
|
|
|
|
2015-02-06 20:12:25 +00:00
|
|
|
/** \brief If \c e is a constructor application, then return the name of the constructor.
|
|
|
|
Otherwise, return none.
|
|
|
|
*/
|
|
|
|
optional<name> is_constructor_app(environment const & env, expr const & e);
|
|
|
|
|
|
|
|
/** \brief If \c e is a constructor application, or a definition that wraps a
|
|
|
|
constructor application, then return the name of the constructor.
|
|
|
|
Otherwise, return none.
|
|
|
|
*/
|
|
|
|
optional<name> is_constructor_app_ext(environment const & env, expr const & e);
|
|
|
|
|
2014-12-15 19:04:55 +00:00
|
|
|
/** \brief "Consume" Pi-type \c type. This procedure creates local constants based on the domain of \c type
|
2014-11-11 22:55:21 +00:00
|
|
|
and store them in telescope. If \c binfo is provided, then the local constants are annoted with the given
|
|
|
|
binder_info, otherwise the procedure uses the one attached in the domain.
|
|
|
|
The procedure returns the "body" of type.
|
|
|
|
*/
|
2014-12-15 19:04:55 +00:00
|
|
|
expr to_telescope(name_generator & ngen, expr const & type, buffer<expr> & telescope,
|
2014-11-11 22:55:21 +00:00
|
|
|
optional<binder_info> const & binfo = optional<binder_info>());
|
2014-12-12 01:31:47 +00:00
|
|
|
/** \brief Similar to previous procedure, but puts \c type in whnf */
|
2014-11-12 21:31:31 +00:00
|
|
|
expr to_telescope(type_checker & tc, expr type, buffer<expr> & telescope,
|
|
|
|
optional<binder_info> const & binfo = optional<binder_info>());
|
2014-12-12 01:31:47 +00:00
|
|
|
/** \brief Similar to previous procedure, but also accumulates constraints generated while
|
|
|
|
normalizing type.
|
2014-11-12 20:24:22 +00:00
|
|
|
|
2014-12-12 01:31:47 +00:00
|
|
|
\remark Constraints are generated only if \c type constains metavariables.
|
|
|
|
*/
|
|
|
|
expr to_telescope(type_checker & tc, expr type, buffer<expr> & telescope, optional<binder_info> const & binfo,
|
|
|
|
constraint_seq & cs);
|
2014-12-15 19:04:55 +00:00
|
|
|
|
|
|
|
/** \brief "Consume" fun/lambda. This procedure creates local constants based on the arguments of \c e
|
|
|
|
and store them in telescope. If \c binfo is provided, then the local constants are annoted with the given
|
|
|
|
binder_info, otherwise the procedure uses the one attached to the arguments.
|
|
|
|
The procedure returns the "body" of function.
|
|
|
|
*/
|
|
|
|
expr fun_to_telescope(name_generator & ngen, expr const & e, buffer<expr> & telescope, optional<binder_info> const & binfo);
|
|
|
|
|
2014-11-12 20:24:22 +00:00
|
|
|
/** \brief Return the universe where inductive datatype resides
|
|
|
|
\pre \c ind_type is of the form <tt>Pi (a_1 : A_1) (a_2 : A_2[a_1]) ..., Type.{lvl}</tt>
|
|
|
|
*/
|
|
|
|
level get_datatype_level(expr ind_type);
|
|
|
|
|
|
|
|
expr instantiate_univ_param (expr const & e, name const & p, level const & l);
|
2014-12-03 04:23:53 +00:00
|
|
|
|
|
|
|
expr mk_true();
|
2014-12-03 18:39:22 +00:00
|
|
|
expr mk_true_intro();
|
2014-12-03 04:23:53 +00:00
|
|
|
expr mk_and(expr const & a, expr const & b);
|
|
|
|
expr mk_and_intro(type_checker & tc, expr const & Ha, expr const & Hb);
|
|
|
|
expr mk_and_elim_left(type_checker & tc, expr const & H);
|
|
|
|
expr mk_and_elim_right(type_checker & tc, expr const & H);
|
|
|
|
|
|
|
|
expr mk_unit(level const & l);
|
2014-12-03 18:39:22 +00:00
|
|
|
expr mk_unit_mk(level const & l);
|
2014-12-03 04:23:53 +00:00
|
|
|
expr mk_prod(type_checker & tc, expr const & A, expr const & B);
|
|
|
|
expr mk_pair(type_checker & tc, expr const & a, expr const & b);
|
|
|
|
expr mk_pr1(type_checker & tc, expr const & p);
|
|
|
|
expr mk_pr2(type_checker & tc, expr const & p);
|
|
|
|
|
|
|
|
expr mk_unit(level const & l, bool prop);
|
2014-12-03 18:39:22 +00:00
|
|
|
expr mk_unit_mk(level const & l, bool prop);
|
2014-12-03 04:23:53 +00:00
|
|
|
expr mk_prod(type_checker & tc, expr const & a, expr const & b, bool prop);
|
|
|
|
expr mk_pair(type_checker & tc, expr const & a, expr const & b, bool prop);
|
|
|
|
expr mk_pr1(type_checker & tc, expr const & p, bool prop);
|
|
|
|
expr mk_pr2(type_checker & tc, expr const & p, bool prop);
|
|
|
|
|
2014-12-08 02:17:15 +00:00
|
|
|
expr mk_eq(type_checker & tc, expr const & lhs, expr const & rhs);
|
2014-12-19 02:23:59 +00:00
|
|
|
expr mk_refl(type_checker & tc, expr const & a);
|
2015-02-04 21:44:55 +00:00
|
|
|
expr mk_symm(type_checker & tc, expr const & H);
|
2014-12-20 05:57:22 +00:00
|
|
|
bool is_eq_rec(expr const & e);
|
|
|
|
bool is_eq(expr const & e);
|
2014-12-22 17:40:15 +00:00
|
|
|
/** \brief Return true iff \c e is of the form (eq A a a) */
|
2014-12-20 05:57:22 +00:00
|
|
|
bool is_eq_a_a(expr const & e);
|
2014-12-22 17:40:15 +00:00
|
|
|
/** \brief Return true iff \c e is of the form (eq A a a') where \c a and \c a' are definitionally equal */
|
|
|
|
bool is_eq_a_a(type_checker & tc, expr const & e);
|
2014-12-08 02:17:15 +00:00
|
|
|
|
2015-02-09 01:27:59 +00:00
|
|
|
bool is_iff(expr const & e);
|
|
|
|
expr mk_iff(expr const & lhs, expr const & rhs);
|
|
|
|
expr mk_iff_refl(expr const & a);
|
|
|
|
|
2014-12-08 02:17:15 +00:00
|
|
|
/** \brief Create a telescope equality for HoTT library.
|
|
|
|
This procedure assumes eq supports dependent elimination.
|
|
|
|
For HoTT, we can't use heterogeneous equality.
|
|
|
|
*/
|
|
|
|
void mk_telescopic_eq(type_checker & tc, buffer<expr> const & t, buffer<expr> const & s, buffer<expr> & eqs);
|
|
|
|
void mk_telescopic_eq(type_checker & tc, buffer<expr> const & t, buffer<expr> & eqs);
|
|
|
|
|
2014-12-09 06:11:48 +00:00
|
|
|
level mk_max(levels const & ls);
|
|
|
|
|
2014-12-12 01:31:47 +00:00
|
|
|
expr mk_sigma_mk(type_checker & tc, buffer<expr> const & ts, buffer<expr> const & as, constraint_seq & cs);
|
|
|
|
|
2015-01-22 01:22:41 +00:00
|
|
|
enum class implicit_infer_kind { Implicit, RelaxedImplicit, None };
|
|
|
|
|
|
|
|
/** \brief Infer implicit parameter annotations for the first \c nparams using mode
|
|
|
|
specified by \c k.
|
|
|
|
*/
|
|
|
|
expr infer_implicit_params(expr const & type, unsigned nparams, implicit_infer_kind k);
|
|
|
|
|
2015-02-01 18:59:27 +00:00
|
|
|
/** \brief Similar to has_expr_metavar, but ignores metavariables occurring in the type
|
|
|
|
of local constants */
|
|
|
|
bool has_expr_metavar_relaxed(expr const & e);
|
|
|
|
|
2014-12-10 19:23:23 +00:00
|
|
|
void initialize_library_util();
|
|
|
|
void finalize_library_util();
|
2014-11-11 20:26:26 +00:00
|
|
|
}
|