Skip to content

Conversation

@keyboardDrummer
Copy link
Contributor

@keyboardDrummer keyboardDrummer commented Jan 21, 2026

Changes

  1. Translates Laurel procedures to Core functions when possible (expression body and no contract)
  2. Translates Laurel procedure contracts to Core procedure contracts
  3. Implement Laurel's field access operator for mutable field
  4. Support both types of return value syntax in Laurel
  5. Some support for parsing composite type definitions in Laurel
  6. Identify which Laurel procedures read or mutate the heap, and introduce the Heap as an in or out parameter accordingly
  7. Let impure expression lifting code detect some not supported cases instead of incorrectly translating them

Testing

  • For 1-2, add T5_ProcedureCallsBoogie.lean
  • For 3-6, turn on T1_MutableFields.lean
  • For 7, add T2_ImpureExpressionsNotSupported

@keyboardDrummer keyboardDrummer requested a review from a team as a code owner January 21, 2026 09:12
@@ -0,0 +1,48 @@
/-
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we rename "Boogie" to "StrataCore"?

assert y == 2;
assert false;
// ^^^^^^^^^^^^^ error: assertion does not hold
procedure NestedImpureStatements() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally these (and below) would be defined using:

#strata
...
#end

Copy link
Contributor

Choose a reason for hiding this comment

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

(Not blocking)

def transformProcedureBody (body : StmtExpr) : StmtExpr :=
let (seqStmts, _) := transformStmt body |>.run {}
def transformProcedureBody (body : StmtExpr) : SequenceM StmtExpr := do
let seqStmts <- transformStmt body
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let seqStmts <- transformStmt body
let seqStmts transformStmt body

let seqBody := transformProcedureBody bodyExpr
{ proc with body := .Transparent seqBody }
| _ => proc -- Opaque and Abstract bodies unchanged
let seqBody <- transformProcedureBody bodyExpr
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let seqBody <- transformProcedureBody bodyExpr
let seqBody transformProcedureBody bodyExpr

| .TInt => LMonoTy.int
| .TBool => LMonoTy.bool
| .TVoid => LMonoTy.bool -- Using bool as placeholder for void
| .TVoid => LMonoTy.bool
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want this long-term?

let check : Core.Procedure.Check := { expr := translateExpr constants initEnv postcond }
[("ensures", check)]
| _ => []
-- Add $heap to modifies clause only if this procedure writes to the heap
Copy link
Contributor

Choose a reason for hiding this comment

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

Calling this "Add" when modifies is ["$heap"] or [] confused me. Maybe just remove this comment?

modifies := []
preconditions := []
postconditions := []
modifies := modifies
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
modifies := modifies
modifies,

preconditions := []
postconditions := []
modifies := modifies
preconditions := preconditions
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
preconditions := preconditions
preconditions,

postconditions := []
modifies := modifies
preconditions := preconditions
postconditions := postconditions
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
postconditions := postconditions
postconditions,

body := none
}

-- Axiom 1: read-over-write-same
Copy link
Contributor

Choose a reason for hiding this comment

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

Having axioms in the translator feels weird to me. Could this go in a prelude?

IO.FS.withTempDir (fun tempDir =>
EIO.toIO (fun f => IO.Error.userError (toString f))
(Core.verify smtsolver coreProgram tempDir options))
match boogieProgramExcept with
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
match boogieProgramExcept with
match strataCoreProgramExcept with

(options : Options := Options.default)
(tempDir : Option String := .none)
: IO (Except (Array DiagnosticModel) VCResults) := do
let boogieProgramExcept := translate program
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
let boogieProgramExcept := translate program
let strataCoreProgramExcept := translate program

deriving Repr, BEq

def toDiagnostic (files: Map Strata.Uri Lean.FileMap) (vcr : Core.VCResult) : Option Diagnostic := do
def DiagnosticModel.toDiagnostic (files: Map Strata.Uri Lean.FileMap) (dm: DiagnosticModel): Diagnostic :=
Copy link
Contributor

Choose a reason for hiding this comment

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

Diagnostic seems like a more general notion, and I think it may make sense to place it where it can be reusable. Maybe your new PR (that I haven't seen yet) about metadata locations does that?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm also a little unclear on whether the diagnostic printing will lose the kind of proof-obligation specific printing we've got going in this file (e.g., VCResults formatting). Mind helping me understand the implications here?

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.

6 participants