Skip to content

simple functional queue from Okasaki#558

Open
c-cube wants to merge 18 commits into
leanprover:mainfrom
c-cube:c-cube/functionalQueue
Open

simple functional queue from Okasaki#558
c-cube wants to merge 18 commits into
leanprover:mainfrom
c-cube:c-cube/functionalQueue

Conversation

@c-cube
Copy link
Copy Markdown

@c-cube c-cube commented May 11, 2026

Hi, this is my first attempt at contributing Lean code.

I dug out the old Okasaki, and started off with the simple queue. This should
contain a correctness proof, a complexity proof, and a mapping to a ghost list
of elements. TimeM doesn't seem to be enough for amortized complexity so
I added a module for that, and I also removed the ZeroAdd typeclass constraint
because \N doesn't implement it(!).

AI disclosure: all code is mine, but I had some assistance from GLM 5.1 to
tidy up proof terms and get unstuck.

@c-cube c-cube force-pushed the c-cube/functionalQueue branch from b7c4a9c to a3c0424 Compare May 11, 2026 02:50
Comment thread Cslib/Algorithms/Lean/FunctionalQueue/FunctionalQueue.lean
Comment thread Cslib/Algorithms/Lean/Amortized.lean Outdated
Comment thread Cslib/Algorithms/Lean/FunctionalQueue/FunctionalQueue.lean
Comment thread Cslib/Algorithms/Lean/Amortized.lean
Comment thread Cslib/Algorithms/Lean/Amortized.lean Outdated
@c-cube c-cube force-pushed the c-cube/functionalQueue branch from b22b379 to 5fb8647 Compare May 19, 2026 03:07
Comment thread Cslib/Algorithms/Lean/Amortized.lean Outdated
Comment thread Cslib/Algorithms/Lean/Amortized.lean Outdated
Comment thread Cslib/Algorithms/Lean/Amortized.lean Outdated
@c-cube c-cube requested review from eric-wieser and sorrachai May 29, 2026 02:53
@c-cube
Copy link
Copy Markdown
Author

c-cube commented May 29, 2026

this is ready for re-review

Comment thread Cslib/Algorithms/Lean/FunctionalQueue/FunctionalQueue.lean Outdated
Comment thread Cslib/Algorithms/Lean/FunctionalQueue/FunctionalQueue.lean Outdated
Comment thread Cslib/Algorithms/Lean/Amortized.lean Outdated
Comment thread Cslib/Algorithms/Lean/Amortized.lean Outdated
Comment on lines +34 to +35
class Op α o where
applyOp : α → o → TimeM ℕ α
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has no docstring; and this only makse sense if you are saying "for any given pair of types α o, there is exactly one possible operation".

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how else should I write this? no typeclass at all?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think drop the typeclass entirely.

Comment on lines +91 to +95
/-- Enqueue an element. -/
def push {α : Type u} (x : α) (q : FunctionalQueue α)
: TimeM ℕ (FunctionalQueue α) := do
TimeM.tick 1
rebalance ⟨ q.front, x :: q.back ⟩
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, the TimeM stuff clutters the API here; especially if you find yourself wanting to execute this code, and now end up computing a bunch of counters that you have no interest in. I'd suggest something like

Suggested change
/-- Enqueue an element. -/
def push {α : Type u} (x : α) (q : FunctionalQueue α)
: TimeM ℕ (FunctionalQueue α) := do
TimeM.tick 1
rebalance ⟨ q.front, x :: q.back ⟩
/-- Enqueue an element. -/
def push {α : Type u} (x : α) (q : FunctionalQueue α) : FunctionalQueue α :=
rebalance ⟨q.front, x :: q.back⟩
/-- Push as an algorithm
def pushAlg {α : Type u} (x : α) (q : FunctionalQueue α)
: TimeM ℕ (FunctionalQueue α) := do
TimeM.tick 1
rebalanceAlg ⟨ q.front, x :: q.back ⟩
@[simp] theorem run_pushAlg : (pushAlg x q).ret = pushAlg x q := sorry

and similar for the others.

Perhaps this needs discussion on Zulip.

@c-cube c-cube force-pushed the c-cube/functionalQueue branch from cc292d6 to 36ccb27 Compare June 6, 2026 01:48
back : List α

/-- Well-formedness: if front is empty, back must be empty too. -/
def invariant {α : Type u} (q : Raw.FunctionalQueue α) : Prop :=
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def invariant {α : Type u} (q : Raw.FunctionalQueue α) : Prop :=
def Invariant {α : Type u} (q : Raw.FunctionalQueue α) : Prop :=

since this is a Prop

TimeM.tick 1
rebalance ⟨ q.front, x :: q.back ⟩

theorem pushInvariant {α : Type u} (x : α) (q : FunctionalQueue α)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be called Invariant.push

/-- Physicist method: a potential (lower bound on savings) defined on a
data structure.
[Okasaki, *Purely Functional Data Structures*, 1996][okasaki1996] -/
class Potential (φ α : Type*) [CommRing φ] [LinearOrder φ] [IsStrictOrderedRing φ] where
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that you can change this to

Suggested change
class Potential (φ α : Type*) [CommRing φ] [LinearOrder φ] [IsStrictOrderedRing φ] where
class Potential (φ α : Type*) where

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants