Skip to content

Sound equality checking for Lambda#641

Merged
joscoh merged 15 commits intomainfrom
josh/sound-eq
Mar 24, 2026
Merged

Sound equality checking for Lambda#641
joscoh merged 15 commits intomainfrom
josh/sound-eq

Conversation

@joscoh
Copy link
Contributor

@joscoh joscoh commented Mar 24, 2026

Issue #, if available:

Description of changes: Previously, Lambda's equality checking was unsound (when compared against an in-progress denotational semantics). This was partially fixed in #633, but it involved an awkward mechanism that prevented equality checking under lambdas. It was also still unsound, since we cannot erase types when comparing equality (e.g. @Nil int is not semantically equal to @Nil bool).

This PR adds a more principled equality check that is sound but incomplete, giving up if it cannot prove equality of inequality. It tries syntactic equality (which can prove equality, not inequality), reasons about constants, proves equality and inequality of lambdas extensionally, and reasons about the (in)equality of datatype constructors by using injectivity+disjointness properties. Tests demonstrating its behavior are in LExprEqTests.lean.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@joscoh joscoh added the Core label Mar 24, 2026
@joscoh joscoh marked this pull request as ready for review March 24, 2026 17:32
@joscoh joscoh requested a review from a team March 24, 2026 17:32
aqjune-aws
aqjune-aws previously approved these changes Mar 24, 2026
@andrewmwells-amazon
Copy link
Contributor

Code LGTM. Left a suggestion for an outdated comment.

Co-authored-by: Andrew Wells <130512013+andrewmwells-amazon@users.noreply.github.com>
@joscoh joscoh added this pull request to the merge queue Mar 24, 2026
Merged via the queue into main with commit 7143d14 Mar 24, 2026
15 checks passed
@joscoh joscoh deleted the josh/sound-eq branch March 24, 2026 20:30
-/
def eql (F : @Factory T.base) (e1 e2 : LExpr T) : Option Bool :=
-- If syntactic equality holds, so does semantic equality
if eqModuloMeta e1 e2 then some true
Copy link
Contributor

Choose a reason for hiding this comment

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

During a separate discussion on the slack channel, I became to have a curiosity - does this fast-forwarded path actually still allow Nil without any type annotation to still compare equal? If the two Nils are annotated with different types, does it imply that type annotation may change evaluation result?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, two Nil without type annotations are considered equal and yes, if they are annotated with different types, the evaluation result may change. I think this is fine. Our semantics are defined only after type inference, when the annotation is uniquely determined. Essentially, we make no guarantees about the behavior of the evaluator (except that it is consistent with Step) on untyped terms.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants