Repository navigation
Conversation
…ers, so --verdict checks what bend2 checks (bendlang#1665)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1665.
Cause
bend2 wraps each node it checks in its type, as a cell (
InferandCheckinbend.ts), andterm_higherkeeps a cell as it is. So a binder inside a def's body is a closure, but an annotation names it by the level bend2 checked it at.etainsafe.tsmakes a term of a function type η-long,λy => t(y), andytakes the leveltwas checked at. Each binder insidetlands one level deeper, and the annotations that name it don't move. In the issue's file, the λ-match undernkeeps{x1 == x1 : Nat}whilenis nowx2andx1isy : Bool, so the kernel rejects a program bend2 accepts.etahas three callers, and each one hits this:arg_term(an argument, the issue's case), a leaf intree(a def's body or a match arm), and a default arm inswi.Fix
etatakes the depthtis at and putstunder the λ through its lowered form, withsubst, the waymodel_atbuilds a λ around a body it found once. Lowered, an annotation namest's binders ast's own uses do, so under the λ they move together.s.d.substnow keeps a variable from outsidet(below the depth) at its level, instead of each caller mapping it back.closed_valandmodel_atdid that by hand; they now leave it tosubst. This keepssafe.tsunder its ttok cap.The issue's term now goes out as the hand-written η-long one in the report, byte for byte.
Checks
On HEAD (main
e5527d5b), Linux x86_64, kernel built from thatbendtt.leanwith Lean 4.34.0:tests/check/eta_levels.bendcovers the four places a term goes η-long: an argument (arg), a def's body (leaf), a match arm (arm) and a default arm (rest). Each one fails--verdicton main when it is on its own. A law pinsmainat10n. The file prints10nwhen run and from the JS and C builds, and--checkupexits 0.etainarg_term, at the leaf intreeor at the default arm each makes the test fail, at the defs that path builds (arg;leafandarm;rest). Droppingsubst's default for outer variables (they come back asRefs), or puttingtunder the λ at depthd + 1ord - 1, fails all four.--verdicton the other 1,733 test, demo and bench files gives the same exit code and output as main: 1,114 check, 619 fail.-ois byte-identical to main for the 1,226 of those files that emit one; the other 507 fail-oon both, with the same message.etaruns 37,201 times over 743 of them, 10,194 times on a term with a binder inside (308 files). 577 of those terms hold bare redexes (601 in all), which raising reduces. All 601 sit inside a type.--verdictoutput and-oon all 1,734 files are byte-identical to this PR's first commit (742429e3).n => ..namingn,n => m => ..namingnorm, or no λ-match). bend2 accepts all 432. The 108 without a λ-match check on both. The 324 with one fail on main and check here. None checks on main and fails here.-oonproofs_3200,generics_3200,defs_12800,trees_400andapp_slash_boss_3d'sPROOF.bend, the medians are within 2% of main.eta_levels,constructor_function_reuseand the repro in --verdict rejects a reused proof after reconstructing a constructor with a function field #1623 all check.bun gates/repo.tswithttok==0.3, as CI runs it: 54 / 54.safe.tsgoes from 23,986 to 23,987 ttok, under its 24,000 cap.tsc: 11 errors, the same as main.--verdictand-oruns above were local, onebend <f> --verdictper file asgates/safe_node.tsruns it.Limits
rebuildalso builds a λ's body under binders bend2 didn't check it at, and it has the same bug (#1669). No test, demo or bench file reaches it. #1670 fixes it on top of this PR, with the samesubst.