Zulip Chat Archive
Stream: lean4
Topic: Mem synthesis fails
Marcus Rossel (Feb 11 2022 at 21:41):
In the following MWE:
constant X : Type _
mutual
inductive A
| mk (b : B)
inductive B
| mk (a : X → A) (b : X → B)
end
example (a : A) (as : List A) (h : a ∈ as) : True := sorry
... Lean complains on the last line about h
:
failed to synthesize instance
Mem A (List A)
Even adding:
instance : Mem A (List A) where
mem a l := l.mem a
... doesn't resolve the issue. But changing basically anything about the definition of B
resolves the issue.
Is this intended?
Horatiu Cheval (Feb 11 2022 at 22:18):
Where is a Mem
from? I remember it not being in core Lean 4 but only defined in mathlib 4
Horatiu Cheval (Feb 11 2022 at 22:19):
At least the error I get is simply expected token
at ∈
Marcus Rossel (Feb 11 2022 at 22:19):
Ah, I do have Mathlib4 imported (commit from 2022-02-08).
Mario Carneiro (Feb 12 2022 at 00:14):
what are your imports? Even if mathlib4 is a dependency this code would still not work
Marcus Rossel (Feb 12 2022 at 08:18):
Mario Carneiro said:
what are your imports? Even if mathlib4 is a dependency this code would still not work
Only mathlib. Here's a full setup that reproduces the issue: https://github.com/marcusrossel/mwe/tree/mem-synthesis-fails
Marcus Rossel (Feb 12 2022 at 08:30):
And here's a version without any imports:
constant X : Type _
mutual
inductive A
| mk (b : B)
inductive B
| mk (a : X → A) (b : X → B)
end
class Mem (α : outParam $ Type u) (γ : Type v) where
mem : α → γ → Prop
infix:50 " ∈ " => Mem.mem
def mem (a : α) : List α → Prop
| [] => False
| (b :: l) => a = b ∨ mem a l
instance : Mem α (List α) := ⟨mem⟩
example (a : A) (as : List A) (h : a ∈ as) : True := sorry
Leonardo de Moura (Feb 12 2022 at 16:11):
The issue is due to universe contraints. Note that A
and B
have two universe parameters: one for each X
.
set_option pp.all true
#print A
#print B
You did not specify these universe parameters in your example. The following works
example (a : A.{u, v}) (as : List A.{u, v}) (h : a ∈ as) : True := sorry
Another option is to simplify your mutual definition and make sure both X
s are using the same universe
mutual
inductive A
| mk (b : B)
inductive B
| mk (a : X.{u} → A) (b : X.{u} → B)
end
Leonardo de Moura (Feb 12 2022 at 16:16):
Without specifying the universes in your original example, type class resolution fails when trying to solve
max ?u.1701 ?u.1700 =?= max ?u.1706 ?u.1705
Lean 4 does not approximate the solution using
?u.1701 =?= ?u.1706
?u.1700 =?= ?u.1705
Marcus Rossel (Feb 13 2022 at 07:38):
Leonardo de Moura said:
The issue is due to universe contraints. Note that
A
andB
have two universe parameters: one for eachX
.
I don't understand why each X
has its own universe parameter.
Is this somehow related to the fact that X
is declared as a constant?
Or perhaps as a related question: How could it happen that I use X
s from different universes in the same definition? And are there any other types where this is a thing?
Marcus Rossel (Feb 13 2022 at 07:50):
But thanks, this helped solve my issue!
Horatiu Cheval (Feb 13 2022 at 08:00):
I don't think it's related to constant X : Type _
, the same happens if you replace it with some universe polymorphic def, like def X := Type _
Horatiu Cheval (Feb 13 2022 at 08:02):
I guess each X
is getting its own parameter because Lean tries to be as polymorphic as possible, so each occurrence of the same (modulo universe) term is universe independent from the other? Like
set_option pp.universes true
def p : (α → α) × (β → β) := ⟨id, id⟩
#check @p
-- @p.{u_1, u_2} : {α : Type u_1} → {β : Type u_2} → Prod.{u_1, u_2} (α → α) (β → β)
Marcus Rossel (Feb 13 2022 at 08:36):
Wouldn't the analogous definition be def X : Type _ := <something>
though?
Horatiu Cheval (Feb 13 2022 at 08:51):
Well yeah, it's def x : Type _ := Type _
:)
Last updated: Dec 20 2023 at 11:08 UTC