Open JasonGross opened 7 years ago
Yes, the error message is not good. The equation compiler currently uses three different strategies:
For course of values recursion, we use an auxiliary recursor (brec_on
) that is automatically generated.
Reflexive types such as let_inM
complicate the generation of the this recursor because of impredicativity. Given A : Sort u
and B : A -> Sort v
, the type of Pi (a : A), B a
is Sort (imax u v)
, where imax u v = 0
if v = 0
, and imax u v = max u v
otherwise. Thus, we have
1- imax u 0 = 0
2- imax u (succ v) = max u (succ v)
These two identities simplify the generation of brec_on
for inductive datatypes such as let_inM
.
To be able to use these identities we generate two versions of brec_on
:
binduction_on
which can eliminate only into Prop
, and where we can use identity (1) to simplify the construction, andbrec_on
which can eliminate only into data, and where we can use identity (2) to simplify the construction.When the equation compiler tries to compile denote_let_inM
, it has to decide which recursor (binduction
or brec_on
) to use. Since the result type may be a proposition u = 0
or not u > 0
, it produces an error message. The following two variants work
namespace in_Prop
lemma denote_let_inM : Π {A : Sort 0} , let_inM A → A
| A (@let_inM.ret ._ v) := v
| B (@let_inM.bind A ._ v f) := let v' := @denote_let_inM A v in @denote_let_inM B (f v')
end in_Prop
namespace in_data
def denote_let_inM : Π {A : Sort (u+1)} , let_inM A → A
| A (@let_inM.ret ._ v) := v
| B (@let_inM.bind A ._ v f) := let v' := @denote_let_inM A v in @denote_let_inM B (f v')
end in_data
because in the first case the equation compiler uses binduction_on
and in the second it uses brec_on
.
That being said, course of values recursion is an overkill for this definition. The kernel primitive recursor rec
can be used to compile it. However, we have not implemented this compilation strategy yet.
This is currently on the TODO list: https://github.com/leanprover/lean/issues/1611
In the meantime, you can use the tactic framework to define def denote_let_inM : Π {A : Sort u} , let_inM A → A
.
def denote_let_inM {A : Sort u} (e : let_inM A) : A :=
begin
induction e,
case let_inM.ret A v { exact v },
case let_inM.bind A B v f ih_1 ih_2 { exact ih_2 ih_1 }
end
or use the recursor directly:
def denote_let_inM {A : Sort u} (e : let_inM A) : A :=
let_inM.rec
(λ A v, v)
(λ A B v f ih_1 ih_2, ih_2 ih_1)
e
If I replace
u
with1
andu+1
with2
, it goes through. Similarly, if I replaceu
with(u+1)
, it goes through. I'm confused what makes the equation invalid... (And should there be a warning at the datatype definition time?)