Skip to content

Drop dangling holes in EliminateHoles#862

Draft
keyboardDrummer-bot wants to merge 2 commits intomainfrom
remove-dangling-holes
Draft

Drop dangling holes in EliminateHoles#862
keyboardDrummer-bot wants to merge 2 commits intomainfrom
remove-dangling-holes

Conversation

@keyboardDrummer-bot
Copy link
Copy Markdown
Collaborator

In elimStmtList, holes that are non-last statements in a block are now dropped instead of being processed. Only the last statement in a block is allowed to be a hole (and gets the normal elimination treatment).

The change is in elimStmtList within the mutual block. Instead of stmts.mapM elimStmt, it now pattern-matches on the list:

  • Empty list → empty result
  • Single statement → process it (even if it's a hole)
  • Hole followed by more statements → skip the hole, recurse on the rest
  • Non-hole followed by more statements → process it, recurse on the rest

This integrates naturally with the mutual recursion termination proof since each recursive call is on a structurally smaller list.

Closes #860

In elimStmtList, holes that are non-last statements in a block are now
dropped instead of being processed. Only the last statement in a block
is allowed to be a hole (and gets the normal elimination treatment).

Closes #860
@keyboardDrummer
Copy link
Copy Markdown
Contributor

Can you add an option in LaurelTranslateOptions to turn this behavior on or off? it should be off by default but turned on n PythonToLaurel

Add a dropDanglingHoles flag (default false) to LaurelTranslateOptions
that controls whether non-last Hole statements in a block are dropped
during eliminateHoles. Enable it in the PythonToLaurel pipeline.
@keyboardDrummer-bot
Copy link
Copy Markdown
Collaborator Author

Done — pushed in 645104d. Here's what changed:

  • Added dropDanglingHoles : Bool := false to LaurelTranslateOptions
  • Added the same flag to ElimHoleState and made elimStmtList check it — when false, all holes are processed normally (original behavior); when true, non-last holes in a block are dropped
  • eliminateHoles now accepts dropDanglingHoles (default false) and passes it into the state
  • translateWithLaurel threads options.dropDanglingHoles to eliminateHoles
  • Set dropDanglingHoles := true in translateCombinedLaurelWithLowered (the PythonToLaurel pipeline)

Full build passes including LiftHolesTest.

counter : Nat := 0
currentInputs : List Parameter := []
generatedFunctions : List Procedure := []
dropDanglingHoles : Bool := false
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How can dropping holes be sound? I don't understand. Are these just values that are never returned?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good question. The "dangling holes" being dropped here are holes that appear as non-last statements in a block — i.e., they're in statement position but not in tail position. Since a Hole in statement position doesn't produce a value that's used by anything (it's not assigned to a variable, not returned, not passed as an argument), it has no observable effect on the program's semantics.

Concretely, consider a block like:

{
  Hole   // ← dangling: statement position, value unused
  x := 1
  return x
}

The hole here is dead code — its "value" is discarded. Normally elimStmt would still replace it with a call to a fresh uninterpreted function, which is harmless but adds noise (an extra function that the verifier has to reason about for no benefit).

When dropDanglingHoles is true, these dead-code holes are simply removed. The last statement in a block is always kept and processed normally, since that's the one whose value may actually matter (e.g., as the block's return value).

This is only enabled in the PythonToLaurel pipeline (translateCombinedLaurelWithLowered), where the translation from Python can produce these dangling holes as artifacts. It's off by default for other uses.

I didn't author the original issue requirement (#860) though — @keyboardDrummer can confirm whether there are additional soundness considerations I'm missing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great explanation, thanks @keyboardDrummer-bot ^^^

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Happy to help! Let me know if there's anything else to address on this PR — I noticed it has a git conflicts label, so I can rebase onto main if you'd like.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove dangling holes

3 participants