Zulip Chat Archive

Stream: new members

Topic: Dependent type casting problem


GraceHopper (Sep 05 2025 at 09:56):

Hello everyone,
we are new to Lean and are stuck at one point in our project for the university. We are writing a library for working with SessionTypes and want to translate this paper from Agda into Lean. However, we are encountering a problem with recursion in Chapter 4, specifically with the implementation of a stack. You probably don't need to read the paper, since we believe that our problem stems from not knowing exactly how typecasts work in Lean. The stack contains pairs of indexed types (SessionType n, Cmd A n S), where S must be typed with the same n. If we now want to implement push as described in xy, we can cast SessionType n to SessionType n+1.

However, when casting the Cmd, we somehow get stuck with its SessionType. Can you help us with this?

Many thanks in advance,

Anne, Jakob, Marlon.

These are the definitions you might need to understand:

inductive SessionType : Nat -> Type where

inductive Cmd (A: Type): Nat  SessionType n  Type where -- A is an ApplicationState

def opposite {n : Nat} (i : Fin n) : Fin n :=
  n - 1 - i.val, by omega

def toN {n : Nat} (i : Fin n) : Nat := i.val

def CmdStack (n : Nat) (A : Type) : Type :=
  (i : Fin n)  Σ S : SessionType (toN (opposite i)), Cmd A (toN (opposite i)) S

And this is the push method we are stuck at:

def push {A : Type} {n : Nat} {S : SessionType n} (old_stack : CmdStack n A) (cmd : Cmd A n S) : CmdStack (n+1) A
| i + 1, p =>

    let fin_i: Fin (n) := i, by omega
    let old_S, old_cmd := old_stack fin_i

    -- Proof, that the Indices are equal
    let h : toN (opposite i + 1, p) = toN (opposite fin_i) := by
      simp [toN, opposite, fin_i]
      omega

    let old_S_casted := Eq.mp (by rw [h]) old_S

    let sess : SessionType (toN (opposite i + 1, p)) := old_S_casted

    let old_cmd_casted := Eq.mp (by sorry) old_cmd -- by rw[h] didn't work here

    let cmd: Cmd A (toN (opposite i + 1, p)) sess := by
        simp[h]
        simp[sess]

        exact old_cmd_casted

    sess, cmd

| 0, p  =>
    S, cmd

Marcus Rossel (Sep 05 2025 at 11:13):

Does this work for you?

inductive SessionType : Nat  Type where

inductive Cmd (A : Type): Nat  SessionType n  Type where -- A is an ApplicationState

def Fin.opposite (i : Fin n) : Fin n :=
  n - 1 - i, by omega

def CmdStack (n : Nat) (A : Type) : Type :=
  (i : Fin n)  Σ S : SessionType i.opposite, Cmd A i.opposite S

def push {S : SessionType n} (oldStack : CmdStack n A) (cmd : Cmd A n S) : CmdStack (n + 1) A
  | 0 => S, cmd
  | i + 1, p =>
    let i : Fin n := i, by omega
    let j := Fin.opposite i + 1, p
    let oldSess, oldCmd := oldStack i
    have h₁ : (i.opposite : Nat) = j := by grind [Fin.opposite]
    let sess := h₁  oldSess
    have h₂ : Cmd A i.opposite oldSess = Cmd A j sess := by grind
    let cmd := h₂  oldCmd
    sess, cmd

Aaron Liu (Sep 05 2025 at 11:15):

why do you want to cast?

GraceHopper (Sep 05 2025 at 13:00):

Aaron Liu schrieb:

why do you want to cast?

We stumbled upon something similar and thought that this might help tbh

GraceHopper (Sep 05 2025 at 13:01):

Nice, thank you @Marcus Rossel , this seems to work.


Last updated: Dec 20 2025 at 21:32 UTC