feat(frontends/lean/elaborator): report an error when Type becomes a Prop after elaboration, closes #208
This commit is contained in:
parent
fbbd1d25cd
commit
9c55bbb871
3 changed files with 37 additions and 5 deletions
|
@ -161,12 +161,12 @@ congruence.mk (λx y H, H)
|
||||||
-- Relations that can be coerced to functions / implications
|
-- Relations that can be coerced to functions / implications
|
||||||
-- ---------------------------------------------------------
|
-- ---------------------------------------------------------
|
||||||
|
|
||||||
inductive mp_like {R : Type → Type → Prop} {a b : Type} (H : R a b) : Prop :=
|
inductive mp_like {R : Type → Type → Prop} {a b : Type} (H : R a b) : Type :=
|
||||||
mk {} : (a → b) → @mp_like R a b H
|
mk {} : (a → b) → @mp_like R a b H
|
||||||
|
|
||||||
namespace mp_like
|
namespace mp_like
|
||||||
|
|
||||||
definition app {R : Type → Type → Prop} {a : Type} {b : Type} {H : R a b}
|
definition app.{l} {R : Type → Type → Prop} {a : Type} {b : Type} {H : R a b}
|
||||||
(C : mp_like H) : a → b := rec (λx, x) C
|
(C : mp_like H) : a → b := rec (λx, x) C
|
||||||
|
|
||||||
definition infer ⦃R : Type → Type → Prop⦄ {a : Type} {b : Type} (H : R a b)
|
definition infer ⦃R : Type → Type → Prop⦄ {a : Type} {b : Type} (H : R a b)
|
||||||
|
|
|
@ -75,7 +75,7 @@ typedef name_map<expr> mvar2meta;
|
||||||
class elaborator : public coercion_info_manager {
|
class elaborator : public coercion_info_manager {
|
||||||
typedef name_map<expr> local_tactic_hints;
|
typedef name_map<expr> local_tactic_hints;
|
||||||
typedef rb_map<expr, pair<expr, constraint_seq>, expr_quick_cmp> cache;
|
typedef rb_map<expr, pair<expr, constraint_seq>, expr_quick_cmp> cache;
|
||||||
|
typedef std::vector<pair<expr, expr>> to_check_sorts;
|
||||||
elaborator_context & m_env;
|
elaborator_context & m_env;
|
||||||
name_generator m_ngen;
|
name_generator m_ngen;
|
||||||
type_checker_ptr m_tc[2];
|
type_checker_ptr m_tc[2];
|
||||||
|
@ -85,6 +85,9 @@ class elaborator : public coercion_info_manager {
|
||||||
local_context m_full_context; // superset of m_context, it also contains non-contextual locals.
|
local_context m_full_context; // superset of m_context, it also contains non-contextual locals.
|
||||||
mvar2meta m_mvar2meta;
|
mvar2meta m_mvar2meta;
|
||||||
cache m_cache;
|
cache m_cache;
|
||||||
|
// The following vector contains sorts that we should check
|
||||||
|
// whether the computed universe is too specific or not.
|
||||||
|
to_check_sorts m_to_check_sorts;
|
||||||
|
|
||||||
// mapping from metavariable name ?m to tactic expression that should be used to solve it.
|
// mapping from metavariable name ?m to tactic expression that should be used to solve it.
|
||||||
// this mapping is populated by the 'by tactic-expr' expression.
|
// this mapping is populated by the 'by tactic-expr' expression.
|
||||||
|
@ -598,7 +601,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
expr visit_sort(expr const & e) {
|
expr visit_sort(expr const & e) {
|
||||||
return update_sort(e, replace_univ_placeholder(sort_level(e)));
|
expr r = update_sort(e, replace_univ_placeholder(sort_level(e)));
|
||||||
|
if (is_placeholder(sort_level(e)))
|
||||||
|
m_to_check_sorts.emplace_back(e, r);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr visit_macro(expr const & e, constraint_seq & cs) {
|
expr visit_macro(expr const & e, constraint_seq & cs) {
|
||||||
|
@ -984,6 +990,30 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Check whether the solution found by the elaborator is producing too specific
|
||||||
|
universes.
|
||||||
|
|
||||||
|
\remark For now, we only check if a term Type.{?u} was solved by assigning ?u to 0.
|
||||||
|
In this case, the user should write Prop instead of Type.
|
||||||
|
*/
|
||||||
|
void check_sort_assignments(substitution const & s) {
|
||||||
|
for (auto const & p : m_to_check_sorts) {
|
||||||
|
expr pre = p.first;
|
||||||
|
expr post = p.second;
|
||||||
|
lean_assert(is_sort(post));
|
||||||
|
level u = sort_level(post);
|
||||||
|
lean_assert(is_meta(u));
|
||||||
|
if (s.is_assigned(u)) {
|
||||||
|
level r = *s.get_level(u);
|
||||||
|
if (is_zero(r)) {
|
||||||
|
throw_kernel_exception(env(), pre, [=](formatter const &) {
|
||||||
|
return format("solution computed by the elaborator forces Type to be Prop");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief Apply substitution and solve remaining metavariables using tactics. */
|
/** \brief Apply substitution and solve remaining metavariables using tactics. */
|
||||||
expr apply(substitution & s, expr const & e, name_set & univ_params, buffer<name> & new_params) {
|
expr apply(substitution & s, expr const & e, name_set & univ_params, buffer<name> & new_params) {
|
||||||
expr r = s.instantiate(e);
|
expr r = s.instantiate(e);
|
||||||
|
@ -1013,6 +1043,7 @@ public:
|
||||||
auto p = solve(cs).pull();
|
auto p = solve(cs).pull();
|
||||||
lean_assert(p);
|
lean_assert(p);
|
||||||
substitution s = p->first.first;
|
substitution s = p->first.first;
|
||||||
|
check_sort_assignments(s);
|
||||||
auto result = apply(s, r);
|
auto result = apply(s, r);
|
||||||
copy_info_to_manager(s);
|
copy_info_to_manager(s);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1038,6 +1069,7 @@ public:
|
||||||
auto p = solve(cs).pull();
|
auto p = solve(cs).pull();
|
||||||
lean_assert(p);
|
lean_assert(p);
|
||||||
substitution s = p->first.first;
|
substitution s = p->first.first;
|
||||||
|
check_sort_assignments(s);
|
||||||
name_set univ_params = collect_univ_params(r_v, collect_univ_params(r_t));
|
name_set univ_params = collect_univ_params(r_v, collect_univ_params(r_t));
|
||||||
buffer<name> new_params;
|
buffer<name> new_params;
|
||||||
expr new_r_t = apply(s, r_t, univ_params, new_params);
|
expr new_r_t = apply(s, r_t, univ_params, new_params);
|
||||||
|
|
|
@ -11,7 +11,7 @@ open function
|
||||||
namespace congruence
|
namespace congruence
|
||||||
|
|
||||||
-- TODO: move this somewhere else
|
-- TODO: move this somewhere else
|
||||||
definition reflexive {T : Type} (R : T → T → Type) : Prop := ∀x, R x x
|
definition reflexive {T : Type} (R : T → T → Prop) : Prop := ∀x, R x x
|
||||||
|
|
||||||
-- Congruence classes for unary and binary functions
|
-- Congruence classes for unary and binary functions
|
||||||
-- -------------------------------------------------
|
-- -------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue