Zulip Chat Archive

Stream: Is there code for X?

Topic: Can this be done without mutual recursion?


Ching-Tsun Chou (Nov 12 2025 at 23:15):

Is it possible to define the function oneStep below without using mutual recursion? Informally speaking, oneStep f (n+1) is the result of applying f to the concatenation of oneStep f 0, ..., oneStep f n. I can't figure out a way to produce that concatenation without mutual recursion.

variable {α : Type*}

mutual
  def oneStep (f : List α  List α) :   List α
    | 0 => f []
    | n + 1 => f (cumSteps f n)

  def cumSteps (f : List α  List α) :   List α
    | 0 => oneStep f 0
    | n + 1 => cumSteps f n ++ oneStep f (n + 1)
end

Kenny Lau (Nov 12 2025 at 23:21):

import Mathlib

variable {α : Type*}

def oneStep (f : List α  List α) :   List α
  | n => f (List.flatten <| (List.finRange n).map fun i : Fin n  oneStep f i)

Ching-Tsun Chou (Nov 12 2025 at 23:25):

The same idea also occurred to me just after I posed the question. But your solution is more elegant.

def oneStep (f : List α  List α) :   List α
  | 0 => f []
  | n + 1 => f (List.ofFn (fun k : Fin (n + 1)  oneStep f k)).flatten

Aaron Liu (Nov 13 2025 at 00:55):

I don't like these solutions because they don't reduce

Ching-Tsun Chou (Nov 13 2025 at 00:55):

Any better ideas?

Ching-Tsun Chou (Nov 13 2025 at 01:03):

BTW, I like @Kenny Lau's solution because it does not use recursion at all involve case split.

Aaron Liu (Nov 13 2025 at 01:04):

It definitely does use recursion

Aaron Liu (Nov 13 2025 at 01:04):

We call oneStep from inside itself

Ching-Tsun Chou (Nov 13 2025 at 01:10):

Sorry, I misspoke. I really meant to say that it does not involve a case split.

Kenny Lau (Nov 13 2025 at 01:11):

import Mathlib

variable {α : Type*}

def oneStep (f : List α  List α) :   List α :=
  fun n  (aux n).2 where
  -- n ↦ (oneStep f 0 ++ oneStep f 1 ++ .. ++ oneStep f (n - 1), oneStep f n)
  aux :   List α × List α
  | 0 => ([], f [])
  | n+1 => match aux n with | (a, b) => (a ++ b, f (a ++ b))

variable (f : List α  List α)

example : oneStep f 3 = f (oneStep f 0 ++ oneStep f 1 ++ oneStep f 2) := rfl

Ching-Tsun Chou (Nov 13 2025 at 01:14):

In my real application, the function f involves a Classical.choose and Kenny's first solution turns out to be more convenient.

Aaron Liu (Nov 13 2025 at 01:19):

Kenny Lau said:

import Mathlib

variable {α : Type*}

def oneStep (f : List α  List α) :   List α
  | n => f (List.flatten <| (List.finRange n).map fun i : Fin n  oneStep f i)

Instead of using List.flatten with List.map, does List.flatMap work?


Last updated: Dec 20 2025 at 21:32 UTC