Skip to content

Add Queue datatype - #3084

Draft
silas-hw wants to merge 59 commits into
agda:masterfrom
silas-hw:queue
Draft

Add Queue datatype#3084
silas-hw wants to merge 59 commits into
agda:masterfrom
silas-hw:queue

Conversation

@silas-hw

@silas-hw silas-hw commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Will eventually resolve #3083. Uses the two-list method mentioned in #3072 (but in a PR not generated by an LLM this time).

There may be some poor stylistic choices due to my unfamiliarity with the standard library, for which I am sorry! There are some 'low hanging' basic operations that could still be added, but I think those would be good for separate PRs.

@silas-hw
silas-hw marked this pull request as draft July 20, 2026 21:29
@silas-hw
silas-hw marked this pull request as ready for review July 20, 2026 21:32
@JacquesCarette

Copy link
Copy Markdown
Collaborator

When adding new functionality, we tend to make somewhat larger PRs than when fixing things. In particular, a bunch of properties should be proved too. The main reason is that quite often the proofs reveal when some of functionality was written in a correct-but-hard-to-use (or reason about) manner. So basically all of #3083 will need to be done in this PR.

On the other hand, asking for reviews of the intermediate steps is a good idea.

Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/TwoList/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
toList empty = []
toList (queue dq-hd dq-tail eq) = dq-hd ∷ (dq-tail ++ (reverse eq))

-- Create a Queue from a List, such that the elements

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.

Probably consider fromSnocList too.

@jamesmckinna jamesmckinna left a comment

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.

Some alternative suggestions as to implementation.

Against @JacquesCarette , and because I'm a bit more 'OO-minded', I tend to put things like Empty/isEmpty as manifest fields of the record, because then I don't have to think about the scope management. Similarly toList, because all the pieces are at-hand without further ado... but YMMV.

As for references for this kind of implementation, probably Okasaki's "Purely functional data structures" would be the go-to citation?

Oh, and: fix-whitespace!

Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
@gallais

gallais commented Jul 21, 2026

Copy link
Copy Markdown
Member

As for references for this kind of implementation, probably Okasaki's "Purely functional data structures" would be the go-to citation?

There is also https://doi.org/10.1017/S0956796800001489

@jamesmckinna

Copy link
Copy Markdown
Collaborator

When adding new functionality, we tend to make somewhat larger PRs than when fixing things. In particular, a bunch of properties should be proved too. The main reason is that quite often the proofs reveal when some of functionality was written in a correct-but-hard-to-use (or reason about) manner. So basically all of #3083 will need to be done in this PR.

On the other hand, asking for reviews of the intermediate steps is a good idea.

So, eg.:

toList-fromList : toList (fromList xs) ≡ xs

The converse direction requires some simulation relation on Queues... but that's (probably) worth discussing/thinking about a bit more... although the toList observer of 'internal state' is already one kind of characteristic...

@silas-hw
silas-hw marked this pull request as draft July 21, 2026 14:03
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
Comment thread src/Data/Queue/Base.agda Outdated
silas-hw and others added 5 commits July 22, 2026 11:18
Co-authored-by: jamesmckinna <31931406+jamesmckinna@users.noreply.github.com>
Co-authored-by: jamesmckinna <31931406+jamesmckinna@users.noreply.github.com>
Comment thread src/Data/Queue/TwoList/Base.agda
Comment thread src/Data/Queue/TwoList/Base.agda
Comment thread src/Data/Queue/QueueSpec.agda Outdated
Comment on lines +52 to +53
to𝔹 : Q A → Bool
to𝔹 = isYes ∘ empty?

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.

Similarly, should this be called null? or isEmpty? or what, in general...

Comment thread src/Data/Queue/QueueSpec.agda Outdated
@silas-hw

Copy link
Copy Markdown
Contributor Author

Note: sorry for pushing a file with holes in!

Comment thread src/Data/Queue/TwoList/Properties.agda Outdated
{!!} ≡⟨⟩
{!!}
++-[] : ∀ {xs ys : List A} → (xs ++ ys) ≡ [] → ys ≡ []
++-[] {xs = []} {ys = []} xs++ys≡[] = xs++ys≡[]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Note that the equivalent properties in Data.Nat.Properties have more complex names:

m+n≡0⇒m≡0 :  m {n}  m + n ≡ 0  m ≡ 0
m+n≡0⇒n≡0 :  m {n}  m + n ≡ 0  n ≡ 0

I personally would expect ++-[] to be a proof that xs ++ [] ≡ xs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There are two hard things in computer science...

Descriptive names is definitely something I need to get a hold of!

@silas-hw

Copy link
Copy Markdown
Contributor Author

Should instances bet put into a .Instances module, or put into the file that defines their component parts? Whichever we go with, I think it should be put into the style guide.

@JacquesCarette

Copy link
Copy Markdown
Collaborator

Should instances bet put into a .Instances module, or put into the file that defines their component parts? Whichever we go with, I think it should be put into the style guide.

Yes to instances going into a .Instances module. If the component parts are independently useful, they can go elsewhere. Fully agree that should go in the style guide.

[I'll do a full pass on all the comments / code later.]

@silas-hw

Copy link
Copy Markdown
Contributor Author

Oh no! Some properties of IsQueue require an already existing instance of RawQueue to be provided Thus an instance of IsQueue would require properties proven that themselves require an instance of RawQueue - circular dependency! (Properties would import Instances, and Instances would import Properties)

@jamesmckinna

Copy link
Copy Markdown
Collaborator

hmmm... circular dependencies? Does splitting the Spec module into two help at all?

@silas-hw

silas-hw commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

I think it would rather be splitting Instances. I.e. have TwoList-RawQueue defined as an instance somewhere, have that imported into Properties, which can then be imported into some module that defines TwoList-IsQueue - but this does go against the current style.

Or maybe moving the definitions used in the instance of IsQueue to the Instances file itself, but this would result in a Instances file containing mostly properties.

--- Smart Constructor

queue : List< A List A Queue A
queue [] ys = mkQ (fromList> (reverse ys)) [] (const [])

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.

Ca the call to fromList> (reverse ys) be fused into something simpler?

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.

Add Queue datatype

6 participants