fix(library/definitional/projection): error messages for projection generation
This commit is contained in:
parent
fe4ea48381
commit
30571ce418
3 changed files with 51 additions and 9 deletions
|
@ -14,30 +14,37 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
[[ noreturn ]] static void throw_ill_formed(name const & n) {
|
[[ noreturn ]] static void throw_ill_formed(name const & n) {
|
||||||
throw exception(sstream() << "error in 'projection' generation, '" << n << "' is an ill-formed inductive datatype");
|
throw exception(sstream() << "error in projection generation, '" << n << "' is an ill-formed inductive datatype");
|
||||||
}
|
}
|
||||||
|
|
||||||
static pair<unsigned, inductive::intro_rule> get_nparam_intro_rule(environment const & env, name const & n) {
|
static pair<unsigned, inductive::intro_rule> get_nparam_intro_rule(environment const & env, name const & n) {
|
||||||
optional<inductive::inductive_decls> decls = inductive::is_inductive_decl(env, n);
|
optional<inductive::inductive_decls> decls = inductive::is_inductive_decl(env, n);
|
||||||
if (!decls)
|
if (!decls)
|
||||||
throw exception(sstream() << "error in 'projection' generation, '" << n << "' is not an inductive datatype");
|
throw exception(sstream() << "error in projection generation, '" << n << "' is not an inductive datatype");
|
||||||
|
optional<unsigned> num_indices = inductive::get_num_indices(env, n);
|
||||||
|
if (num_indices && *num_indices > 0)
|
||||||
|
throw exception(sstream() << "error in projection generation, '"
|
||||||
|
<< n << "' is an indexed inductive datatype family");
|
||||||
unsigned num_params = std::get<1>(*decls);
|
unsigned num_params = std::get<1>(*decls);
|
||||||
for (auto const & decl : std::get<2>(*decls)) {
|
for (auto const & decl : std::get<2>(*decls)) {
|
||||||
if (inductive::inductive_decl_name(decl) == n) {
|
if (inductive::inductive_decl_name(decl) == n) {
|
||||||
auto intros = inductive::inductive_decl_intros(decl);
|
auto intros = inductive::inductive_decl_intros(decl);
|
||||||
if (length(intros) != 1)
|
if (length(intros) != 1)
|
||||||
throw exception(sstream() << "error in 'projection' generation, '"
|
throw exception(sstream() << "error in projection generation, '"
|
||||||
<< n << "' must have a single constructor");
|
<< n << "' does not have a single constructor");
|
||||||
return mk_pair(num_params, head(intros));
|
return mk_pair(num_params, head(intros));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
optional<unsigned> num_indices = inductive::get_num_indices(env, n);
|
|
||||||
if (num_indices && *num_indices > 0)
|
|
||||||
throw exception(sstream() << "error in 'projection' generation, '"
|
|
||||||
<< n << "' is an indexed inductive datatype family");
|
|
||||||
throw_ill_formed(n);
|
throw_ill_formed(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_prop(expr type) {
|
||||||
|
while (is_pi(type)) {
|
||||||
|
type = binding_body(type);
|
||||||
|
}
|
||||||
|
return is_sort(type) && is_zero(sort_level(type));
|
||||||
|
}
|
||||||
|
|
||||||
environment mk_projections(environment const & env, name const & n, buffer<name> const & proj_names) {
|
environment mk_projections(environment const & env, name const & n, buffer<name> const & proj_names) {
|
||||||
// Given an inductive datatype C A (where A represent parameters)
|
// Given an inductive datatype C A (where A represent parameters)
|
||||||
// intro : Pi A (x_1 : B_1[A]) (x_2 : B_2[A, x_1]) ..., C A
|
// intro : Pi A (x_1 : B_1[A]) (x_2 : B_2[A, x_1]) ..., C A
|
||||||
|
@ -52,6 +59,8 @@ environment mk_projections(environment const & env, name const & n, buffer<name>
|
||||||
expr intro_type = inductive::intro_rule_type(intro);
|
expr intro_type = inductive::intro_rule_type(intro);
|
||||||
name rec_name = inductive::get_elim_name(n);
|
name rec_name = inductive::get_elim_name(n);
|
||||||
declaration ind_decl = env.get(n);
|
declaration ind_decl = env.get(n);
|
||||||
|
if (env.impredicative() && is_prop(ind_decl.get_type()))
|
||||||
|
throw exception(sstream() << "error in projection generation, '" << n << "' is a proposition");
|
||||||
declaration rec_decl = env.get(rec_name);
|
declaration rec_decl = env.get(rec_name);
|
||||||
level_param_names lvl_params = ind_decl.get_univ_params();
|
level_param_names lvl_params = ind_decl.get_univ_params();
|
||||||
levels lvls = param_names_to_levels(lvl_params);
|
levels lvls = param_names_to_levels(lvl_params);
|
||||||
|
@ -77,7 +86,7 @@ environment mk_projections(environment const & env, name const & n, buffer<name>
|
||||||
environment new_env = env;
|
environment new_env = env;
|
||||||
for (name const & proj_name : proj_names) {
|
for (name const & proj_name : proj_names) {
|
||||||
if (!is_pi(intro_type))
|
if (!is_pi(intro_type))
|
||||||
throw exception(sstream() << "error in projection '" << proj_name << "' generation, '"
|
throw exception(sstream() << "error generating projection '" << proj_name << "', '"
|
||||||
<< n << "' does not have sufficient data");
|
<< n << "' does not have sufficient data");
|
||||||
expr result_type = binding_domain(intro_type);
|
expr result_type = binding_domain(intro_type);
|
||||||
buffer<expr> proj_args;
|
buffer<expr> proj_args;
|
||||||
|
|
25
tests/lean/proj.lean
Normal file
25
tests/lean/proj.lean
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import logic data.nat.basic
|
||||||
|
|
||||||
|
inductive vector (T : Type) : nat → Type :=
|
||||||
|
nil {} : vector T nat.zero,
|
||||||
|
cons : T → ∀{n}, vector T n → vector T (nat.succ n)
|
||||||
|
|
||||||
|
#projections or
|
||||||
|
#projections and
|
||||||
|
#projections eq.refl
|
||||||
|
#projections eq
|
||||||
|
#projections vector
|
||||||
|
|
||||||
|
inductive point :=
|
||||||
|
mk : nat → nat → point
|
||||||
|
|
||||||
|
#projections point :: x y z
|
||||||
|
|
||||||
|
#projections point :: x y
|
||||||
|
|
||||||
|
#projections point :: x y
|
||||||
|
|
||||||
|
inductive funny : nat → Type :=
|
||||||
|
mk : Π (a : nat), funny a
|
||||||
|
|
||||||
|
#projections funny
|
8
tests/lean/proj.lean.expected.out
Normal file
8
tests/lean/proj.lean.expected.out
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
proj.lean:7:0: error: error in projection generation, 'or' does not have a single constructor
|
||||||
|
proj.lean:8:0: error: error in projection generation, 'and' is a proposition
|
||||||
|
proj.lean:9:0: error: error in projection generation, 'eq.refl' is not an inductive datatype
|
||||||
|
proj.lean:10:0: error: error in projection generation, 'eq' is an indexed inductive datatype family
|
||||||
|
proj.lean:11:0: error: error in projection generation, 'vector' is an indexed inductive datatype family
|
||||||
|
proj.lean:16:0: error: error generating projection 'point.z', 'point' does not have sufficient data
|
||||||
|
proj.lean:20:0: error: invalid object declaration, environment already has an object named 'point.x'
|
||||||
|
proj.lean:25:0: error: error in projection generation, 'funny' is an indexed inductive datatype family
|
Loading…
Reference in a new issue