feat(frontends/lean/structure): add option for controlling whether we automatically generate eta and projection-over-intro theorems for structures
It seems most of the time these theorems are not used at all. They are just polluting the namespace. Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
d67583df44
commit
05f27b8f0e
4 changed files with 42 additions and 2 deletions
|
@ -3,6 +3,8 @@
|
||||||
-- Author: Leonardo de Moura, Jeremy Avigad
|
-- Author: Leonardo de Moura, Jeremy Avigad
|
||||||
open decidable
|
open decidable
|
||||||
|
|
||||||
|
set_option structure.proj_mk_thm true
|
||||||
|
|
||||||
structure subtype {A : Type} (P : A → Prop) :=
|
structure subtype {A : Type} (P : A → Prop) :=
|
||||||
tag :: (elt_of : A) (has_property : P elt_of)
|
tag :: (elt_of : A) (has_property : P elt_of)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,9 @@ notation `Type₁` := Type.{1}
|
||||||
notation `Type₂` := Type.{2}
|
notation `Type₂` := Type.{2}
|
||||||
notation `Type₃` := Type.{3}
|
notation `Type₃` := Type.{3}
|
||||||
|
|
||||||
|
set_option structure.eta_thm true
|
||||||
|
set_option structure.proj_mk_thm true
|
||||||
|
|
||||||
inductive unit.{l} : Type.{l} :=
|
inductive unit.{l} : Type.{l} :=
|
||||||
star : unit
|
star : unit
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ Author: Leonardo de Moura
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "util/sstream.h"
|
#include "util/sstream.h"
|
||||||
|
#include "util/sexpr/option_declarations.h"
|
||||||
#include "kernel/type_checker.h"
|
#include "kernel/type_checker.h"
|
||||||
#include "kernel/instantiate.h"
|
#include "kernel/instantiate.h"
|
||||||
#include "kernel/abstract.h"
|
#include "kernel/abstract.h"
|
||||||
|
@ -43,17 +44,38 @@ Author: Leonardo de Moura
|
||||||
#define LEAN_DEFAULT_STRUCTURE_INTRO "mk"
|
#define LEAN_DEFAULT_STRUCTURE_INTRO "mk"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LEAN_DEFAULT_STRUCTURE_ETA
|
||||||
|
#define LEAN_DEFAULT_STRUCTURE_ETA false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LEAN_DEFAULT_STRUCTURE_PROJ_MK
|
||||||
|
#define LEAN_DEFAULT_STRUCTURE_PROJ_MK false
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
static name * g_tmp_prefix = nullptr;
|
static name * g_tmp_prefix = nullptr;
|
||||||
|
static name * g_gen_eta = nullptr;
|
||||||
|
static name * g_gen_proj_mk = nullptr;
|
||||||
|
|
||||||
void initialize_structure_cmd() {
|
void initialize_structure_cmd() {
|
||||||
g_tmp_prefix = new name(name::mk_internal_unique_name());
|
g_tmp_prefix = new name(name::mk_internal_unique_name());
|
||||||
|
g_gen_eta = new name{"structure", "eta_thm"};
|
||||||
|
g_gen_proj_mk = new name{"structure", "proj_mk_thm"};
|
||||||
|
register_bool_option(*g_gen_eta, LEAN_DEFAULT_STRUCTURE_ETA,
|
||||||
|
"(structure) automatically generate 'eta' theorem whenever declaring a new structure");
|
||||||
|
register_bool_option(*g_gen_proj_mk, LEAN_DEFAULT_STRUCTURE_PROJ_MK,
|
||||||
|
"(structure) automatically gneerate projection over introduction theorem when declaring a new structure, the theorem is never generated for proof irrelevant fields");
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalize_structure_cmd() {
|
void finalize_structure_cmd() {
|
||||||
delete g_tmp_prefix;
|
delete g_tmp_prefix;
|
||||||
|
delete g_gen_eta;
|
||||||
|
delete g_gen_proj_mk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_structure_eta_thm(options const & o) { return o.get_bool(*g_gen_eta, LEAN_DEFAULT_STRUCTURE_ETA); }
|
||||||
|
bool get_structure_proj_mk_thm(options const & o) { return o.get_bool(*g_gen_proj_mk, LEAN_DEFAULT_STRUCTURE_ETA); }
|
||||||
|
|
||||||
/** \brief Return true iff the type named \c S can be viewed as
|
/** \brief Return true iff the type named \c S can be viewed as
|
||||||
a structure in the given environment.
|
a structure in the given environment.
|
||||||
|
|
||||||
|
@ -111,10 +133,15 @@ struct structure_cmd_fn {
|
||||||
levels m_ctx_levels; // context levels for creating aliases
|
levels m_ctx_levels; // context levels for creating aliases
|
||||||
buffer<expr> m_ctx_locals; // context local constants for creating aliases
|
buffer<expr> m_ctx_locals; // context local constants for creating aliases
|
||||||
|
|
||||||
|
bool m_gen_eta;
|
||||||
|
bool m_gen_proj_mk;
|
||||||
|
|
||||||
structure_cmd_fn(parser & p):m_p(p), m_env(p.env()), m_ngen(p.mk_ngen()), m_namespace(get_namespace(m_env)) {
|
structure_cmd_fn(parser & p):m_p(p), m_env(p.env()), m_ngen(p.mk_ngen()), m_namespace(get_namespace(m_env)) {
|
||||||
m_tc = mk_type_checker(m_env, m_p.mk_ngen(), false);
|
m_tc = mk_type_checker(m_env, m_p.mk_ngen(), false);
|
||||||
m_infer_result_universe = false;
|
m_infer_result_universe = false;
|
||||||
m_using_explicit_levels = false;
|
m_using_explicit_levels = false;
|
||||||
|
m_gen_eta = get_structure_eta_thm(p.get_options());
|
||||||
|
m_gen_proj_mk = get_structure_proj_mk_thm(p.get_options());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Parse structure name and (optional) universe parameters */
|
/** \brief Parse structure name and (optional) universe parameters */
|
||||||
|
@ -750,6 +777,8 @@ struct structure_cmd_fn {
|
||||||
}
|
}
|
||||||
|
|
||||||
void declare_eta() {
|
void declare_eta() {
|
||||||
|
if (!m_gen_eta)
|
||||||
|
return;
|
||||||
if (!has_eq_decls(m_env))
|
if (!has_eq_decls(m_env))
|
||||||
return;
|
return;
|
||||||
level_param_names lnames = to_list(m_level_names.begin(), m_level_names.end());
|
level_param_names lnames = to_list(m_level_names.begin(), m_level_names.end());
|
||||||
|
@ -781,6 +810,8 @@ struct structure_cmd_fn {
|
||||||
}
|
}
|
||||||
|
|
||||||
void declare_proj_over_mk() {
|
void declare_proj_over_mk() {
|
||||||
|
if (!m_gen_proj_mk)
|
||||||
|
return;
|
||||||
if (!has_eq_decls(m_env))
|
if (!has_eq_decls(m_env))
|
||||||
return;
|
return;
|
||||||
level_param_names lnames = to_list(m_level_names.begin(), m_level_names.end());
|
level_param_names lnames = to_list(m_level_names.begin(), m_level_names.end());
|
||||||
|
@ -791,6 +822,8 @@ struct structure_cmd_fn {
|
||||||
expr const & field = m_fields[i];
|
expr const & field = m_fields[i];
|
||||||
name const & field_name = mlocal_name(field);
|
name const & field_name = mlocal_name(field);
|
||||||
expr const & field_type = mlocal_type(field);
|
expr const & field_type = mlocal_type(field);
|
||||||
|
if (m_env.prop_proof_irrel() && m_tc->is_prop(field_type).first)
|
||||||
|
continue;
|
||||||
level field_level = sort_level(m_tc->ensure_type(field_type).first);
|
level field_level = sort_level(m_tc->ensure_type(field_type).first);
|
||||||
name proj_name = m_name + field_name;
|
name proj_name = m_name + field_name;
|
||||||
expr lhs = mk_app(mk_app(mk_constant(proj_name, st_ls), m_params), mk_fields);
|
expr lhs = mk_app(mk_app(mk_constant(proj_name, st_ls), m_params), mk_fields);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import logic data.unit
|
import logic data.unit
|
||||||
|
|
||||||
|
set_option structure.eta_thm true
|
||||||
|
|
||||||
structure point (A : Type) (B : Type) :=
|
structure point (A : Type) (B : Type) :=
|
||||||
mk :: (x : A) (y : B)
|
mk :: (x : A) (y : B)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue