Zulip Chat Archive
Stream: Is there code for X?
Topic: Dependent inductive parameter
Ka Wing Li (Jan 07 2026 at 02:04):
I am looking for a way to represent the following Rocq code in Lean4.
Local Open Scope positive_scope.
Local Notation "P ~ 0" := (λ p, P p~0) : function_scope.
Local Notation "P ~ 1" := (λ p, P p~1) : function_scope.
Inductive gmap_dep_ne (A : Type) (P : positive → Prop) :=
| GNode001 : gmap_dep_ne A P~1 → gmap_dep_ne A P
| GNode010 : P 1 → A → gmap_dep_ne A P
| GNode011 : P 1 → A → gmap_dep_ne A P~1 → gmap_dep_ne A P
| GNode100 : gmap_dep_ne A P~0 → gmap_dep_ne A P
| GNode101 : gmap_dep_ne A P~0 → gmap_dep_ne A P~1 → gmap_dep_ne A P
| GNode110 : gmap_dep_ne A P~0 → P 1 → A → gmap_dep_ne A P
| GNode111 : gmap_dep_ne A P~0 → P 1 → A → gmap_dep_ne A P~1 → gmap_dep_ne A P.
Variant gmap_dep (A : Type) (P : positive → Prop) :=
| GEmpty : gmap_dep A P
| GNodes : gmap_dep_ne A P → gmap_dep A P.
Ka Wing Li (Jan 07 2026 at 02:05):
I tried the following
import Mathlib
postfix:arg (priority := high) "~0" => fun P p => P (PosNum.bit0 p)
postfix:arg (priority := high) "~1" => fun P p => P (PosNum.bit1 p)
inductive gmap_dep_ne (A : Type) (P : PosNum → Prop) : Type where
| GNode001 : gmap_dep_ne A P~1 → gmap_dep_ne A P
| GNode010 : P 1 → A → gmap_dep_ne A P
| GNode011 : P 1 → A → gmap_dep_ne A (P~1) → gmap_dep_ne A P
| GNode100 : gmap_dep_ne A P~0 → gmap_dep_ne A P
| GNode101 : gmap_dep_ne A P~0 → gmap_dep_ne A P~1 → gmap_dep_ne A P
| GNode110 : gmap_dep_ne A P~0 → P 1 → A → gmap_dep_ne A P
| GNode111 : gmap_dep_ne A P~0 → P 1 → A → gmap_dep_ne A P~1 → gmap_dep_ne A P
inductive gmap_dep (A : Type) (P : PosNum → Prop) where
| GEmpty : gmap_dep A P
| GNodes : gmap_dep_ne A P → gmap_dep A P
Ka Wing Li (Jan 07 2026 at 02:05):
Yet get some cryptic error
Mismatched inductive type parameter in
gmap_dep_ne A ((fun P p ↦ P p.bit1) P)
The provided argument
(fun P p ↦ P p.bit1) P
is not definitionally equal to the expected parameter
P
Aaron Liu (Jan 07 2026 at 02:06):
it works when you make it
inductive gmap_dep_ne (A : Type) : (P : PosNum → Prop) → Type where
Ka Wing Li (Jan 07 2026 at 02:07):
I tried that, but encounter problem when writing a recursive function traversing the gmap.
Aaron Liu (Jan 07 2026 at 02:07):
can you show the problem
Ka Wing Li (Jan 07 2026 at 02:08):
Yep, I am extracting the code of the problem
Ka Wing Li (Jan 07 2026 at 02:15):
I am not sure if this is okay
instance [DecidableEq A] : (∀ i (x y : P i), x = y) → DecidableEq (gmap_dep_ne A P) := by
unfold DecidableEq
intros t₁ t₂
let rec go (t₁ t₂ : gmap_dep_ne A P) : Decidable (t₁ = t₂) :=
match t₁, t₂ with
| .GNode001 r1, .GNode001 r2 => if (go r1 r2) then isTrue _ else isFalse _
| .GNode010 _ x1, .GNode010 _ x2 => sorry
| .GNode011 _ x1 r1, .GNode011 _ x2 r2 => sorry
| .GNode100 l1, .GNode100 l2 => sorry
| .GNode101 l1 r1, .GNode101 l2 r2 => sorry
| .GNode110 l1 _ x1, .GNode110 l2 _ x2 => sorry
| .GNode111 l1 _ x1 r1, .GNode111 l2 _ x2 r2 => sorry
| _, _ => isFalse _
Ka Wing Li (Jan 07 2026 at 02:16):
error at (go r1 r2)
Ka Wing Li (Jan 07 2026 at 02:16):
Application type mismatch: The argument
r1
has type
gmap_dep_ne A ((fun P p ↦ P p.bit1) P)
but is expected to have type
gmap_dep_ne A P
in the application
go r1
Aaron Liu (Jan 07 2026 at 02:16):
(∀ i (x y : P i), x = y) is weird
Aaron Liu (Jan 07 2026 at 02:16):
I can fill it in with fun _ _ _ => rfl
Ka Wing Li (Jan 07 2026 at 02:17):
It is from Rocq (∀ i, ProofIrrel (P i)), probably should not be used here.
Aaron Liu (Jan 07 2026 at 02:17):
Ka Wing Li said:
Application type mismatch: The argument r1 has type gmap_dep_ne A ((fun P p ↦ P p.bit1) P) but is expected to have type gmap_dep_ne A P in the application go r1
isn't go just the original function again
Aaron Liu (Jan 07 2026 at 02:17):
if you give the instance a name you can call it recursively
Ka Wing Li (Jan 07 2026 at 02:18):
what do you mean?
Aaron Liu (Jan 07 2026 at 02:18):
instance decEq [DecidableEq A] : DecidableEq (gmap_dep_ne A P) := fun t₁ t₂ =>
Aaron Liu (Jan 07 2026 at 02:19):
and then you call decEq recursively
Ka Wing Li (Jan 07 2026 at 02:22):
You mean the following?
instance dec [DecidableEq A] : DecidableEq (gmap_dep_ne A P) :=
fun t₁ t₂ ↦
match t₁, t₂ with
| .GNode001 r1, .GNode001 r2 => if (dec r1 r2).decide then isTrue (by sorry) else isFalse (by sorry)
| _, _ => isFalse (by sorry)
Ka Wing Li (Jan 07 2026 at 02:22):
let me try
Ka Wing Li (Jan 07 2026 at 02:27):
It's working! Thanks.
Ka Wing Li (Jan 07 2026 at 02:27):
Sometimes helper functions cause weird problems and inlining works.
Ka Wing Li (Jan 07 2026 at 02:28):
That's another story.
Aaron Liu (Jan 07 2026 at 02:28):
by the way you can deriving DecidableEq for your gmap_dep_ne
Ka Wing Li (Jan 07 2026 at 02:31):
... why I am doing this
Ka Wing Li (Jan 07 2026 at 03:36):
Excuse me, another similar question:
def GNode (ml : gmap_dep A P~0) (mx : Option (P 1 × A)) (mr : gmap_dep A P~1) : gmap_dep A P :=
match ml, mx, mr with
| .GNodes l, some (p, x), .GNodes r => .GNodes (.GNode111 l p x r)
| _, _, _ => sorry
I got problem for P 1 in type.
Type mismatch
P 1
has type
Prop
of sort `Type` but is expected to have type
Type ?u.27678
of sort `Type (?u.27678 + 1)`
Ka Wing Li (Jan 07 2026 at 03:36):
Tried to change P 1 to Prop or Type will result in p being P 1 instead of others.
Aaron Liu (Jan 07 2026 at 03:46):
you can make it (mx : Option (P 1 ×' A))
Ka Wing Li (Jan 07 2026 at 03:48):
? What’s that?
Aaron Liu (Jan 07 2026 at 03:48):
Ka Wing Li (Jan 07 2026 at 03:49):
Ahh, interesting
Aaron Liu (Jan 07 2026 at 03:49):
and then the pattern will be | .GNodes l, some ⟨p, x⟩, .GNodes r => .GNodes (.GNode111 l p x r), with the angle brackets ⟨⟩ instead of parentheses ()
Ka Wing Li (Jan 07 2026 at 03:50):
?!
Aaron Liu (Jan 07 2026 at 03:51):
the (a, b) notation gives you Prod.mk a b, so it's specific to docs#Prod
Aaron Liu (Jan 07 2026 at 03:51):
so if you use docs#PProd that won't work
Aaron Liu (Jan 07 2026 at 03:52):
instead you need to do PProd.mk a b explicitly, or you can use the anonymous constructor notation ⟨a, b⟩ which works on any inductive type with only one constructor
Ka Wing Li (Jan 07 2026 at 03:52):
Angle bracket is building record, right?
Ka Wing Li (Jan 07 2026 at 03:53):
Okay, that make sense now
Ka Wing Li (Jan 07 2026 at 03:55):
One day I’m going to understand the universe in Lean
Ka Wing Li (Jan 07 2026 at 03:56):
I need some doc about the similarities and differences of universe in lean and rocq
Ka Wing Li (Jan 07 2026 at 03:57):
Thanks for the help btw!
Last updated: Feb 28 2026 at 14:05 UTC