Zulip Chat Archive

Stream: new members

Topic: How to make this recursion (?) work?


Ilmārs Cīrulis (Jan 14 2025 at 15:52):

Here's a tiny example:

mutual
  inductive Value: Type where
  | function:   Expression  Value

  inductive Expression where
  | fun_apply: Expression  List Expression  Expression
end

def List.Exists {A} (L: List A) (P: A  Prop): Prop :=
  match L with
  | List.nil => False
  | x :: t => P x  t.Exists P

def freeVariable (n: ) (exp: Expression): Prop :=
  match exp with
  | Expression.fun_apply f L => freeVariable n f  L.Exists (fun e => freeVariable n e)

How to make this work?

Thank you!

Joachim Breitner (Jan 14 2025 at 15:59):

See https://lean-lang.org/blog/2024-1-11-recursive-definitions-in-lean/ in particular section “Nested recursion”

Ilmārs Cīrulis (Jan 14 2025 at 16:02):

We can use this function before Lift.map, ignore the proof in the argument to List.map, and suddenly Lean accepts the definition:

Is that Lift.map a spelling error?

Ilmārs Cīrulis (Jan 14 2025 at 16:12):

Thank you, it works!

mutual
  inductive Value: Type where
  | function:   Expression  Value

  inductive Expression where
  | fun_apply: Expression  List Expression  Expression
end

def List.Exists {A} (L: List A) (P: A  Prop): Prop :=
  match L with
  | List.nil => False
  | x :: t => P x  t.Exists P

def freeVariable (n: ) (exp: Expression): Prop :=
  match exp with
  | Expression.fun_apply f L => freeVariable n f  List.Exists L.attach (fun e, _⟩ => freeVariable n e)

Notification Bot (Jan 14 2025 at 16:54):

Ilmārs Cīrulis has marked this topic as resolved.

Joachim Breitner (Jan 14 2025 at 18:36):

Ilmārs Cīrulis said:

Is that Lift.map a spelling error?

Thanks, pushed a fix (to be deployed in a bit)

Notification Bot (Jan 15 2025 at 07:22):

Ilmārs Cīrulis has marked this topic as unresolved.

Ilmārs Cīrulis (Jan 15 2025 at 07:23):

How to get this to work? I'm stuck, it seems.

inductive Expression where
| var: String  Expression
| object: List (String × Expression)  Expression

def t (exp: Expression): List String :=
  match exp with
  | Expression.var s => [s]
  | Expression.object L => List.foldl (fun L1 L2 => L1 ++ L2) [] (L.attach.map (fun x => t x.1.2))

Ilmārs Cīrulis (Jan 15 2025 at 08:11):

I managed to do it this way, using decreasing_by.

inductive Expression where
| var: String  Expression
| object: List (String × Expression)  Expression

def t (exp: Expression): List String :=
  match exp with
  | Expression.var s => [s]
  | Expression.object L => List.foldl (fun L1 L2 => L1 ++ L2) [] ((L.map (fun x => x.2)).attach.map (fun x, h => t x))
  decreasing_by
    simp at *
    obtain a, Ha := h
    simp_wf
    have H := List.sizeOf_lt_of_mem Ha
    simp at H
    omega

Last updated: May 02 2025 at 03:31 UTC