-
Notifications
You must be signed in to change notification settings - Fork 52
Add Concrete Syntax for Unstructured Programs in Strata Core #1196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
PROgram52bc
wants to merge
101
commits into
main2
Choose a base branch
from
htd/unstructured-procedure
base: main2
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
101 commits
Select commit
Hold shift + click to select a range
12e7e3e
add CFG to procedure body, no error handling, tests pass
PROgram52bc cbeee72
eliminate toStmts and use pattern matching/error handling
PROgram52bc 723b1ae
add parser support for user-facing syntax with examples and tests
PROgram52bc 602741c
Add TODO comments for two-stage GOTO pipeline refactor
PROgram52bc dbb6f91
add DetCFG abbrev, add obligation extraction and call extraction for …
PROgram52bc 39123b0
refactor ObligationExtraction
PROgram52bc 814530e
Address PR review: getCfg, CBMC error, CFG eval, grammar comment
PROgram52bc 051f976
integrate semantics for Call statements which could invoke procedures…
PROgram52bc 48a2a32
CST support for unstructured programs
PROgram52bc 5d3aba6
add explicit comments on funcDecl extraction for unstructured program
PROgram52bc 1b8a0e5
add ANF comment
PROgram52bc 6c7a61a
alphaEquiv for CFG
PROgram52bc 4ccddf4
no-op when inlining unstructured procedures
PROgram52bc b295843
add more support for CFG handling
PROgram52bc d184ea0
simplify StatementEval
PROgram52bc 70cda23
indent
PROgram52bc 10cb1eb
Address PR review: remove .stmts, refine Body interface, cleanup
PROgram52bc 58695e5
Regenerate editor syntax files for new CFG keywords (goto, cfg)
PROgram52bc 39acfc8
StatementEval returns error on nonexisting label
PROgram52bc 15cfcf0
Refine unstructured procedure cases, add comments
PROgram52bc 9d1de97
define variable infrastructures
PROgram52bc 7e20805
refactor
PROgram52bc 03c940e
Precond Elim for CFGs
PROgram52bc eba79e4
add error branch for renameAllLocalNames in ProcedureInlining
PROgram52bc c993332
intermediate proof fix
PROgram52bc e6d71f7
fix proof
PROgram52bc e5c4793
comment
PROgram52bc 3bfd467
fix WFProcedure
PROgram52bc 6d937fc
restore comments
PROgram52bc 9eb49ab
run out of fuel warning
PROgram52bc 402e43d
better comments on WF
PROgram52bc 18b41d8
error on goto with 2+ targets
PROgram52bc d694805
refine type checker for CFG
PROgram52bc 21a86aa
simplify
PROgram52bc 09973f6
refine comments
PROgram52bc 4305a67
fix: propagate error in runCFG fallthrough and clarify ObligationExtr…
PROgram52bc 035fa8b
test: add end-to-end CFG verification and body preservation tests
PROgram52bc 74a0977
fix: wrap Procedure.body assignment in TerminationCheck.lean for Body…
PROgram52bc 8f0939d
fix: split postconditionsValid into structured/CFG fields and add Cor…
PROgram52bc 8e944c7
refactor: enrich CoreBodyExec with terminal eval and unify postcondit…
PROgram52bc 7e5884f
Merge branch 'main' into htd/unstructured-procedure
PROgram52bc cf067e8
implement type checking for CFG
PROgram52bc 39afe3e
Implement symbolic executor for CFG
PROgram52bc c1299b8
abstract collectCmds
PROgram52bc b9334dc
add more documentation/better abstraction
PROgram52bc 4d29cde
add metadata to unstructured programs
PROgram52bc 6f2aca0
feat: preserve loop contracts in CFG transfer metadata
PROgram52bc 6d2582c
fix: split transfer_goto grammar to enforce 1 or 2 targets at parse time
PROgram52bc 11f11eb
fix: increment var_def counter when generating nondet goto fvar
PROgram52bc 7f0d3b9
Fix binding bug in CFG Parser
PROgram52bc 12b0295
fix comments
PROgram52bc b0640fd
refactor: use Procedure.Body.getStructured instead of raw match
PROgram52bc b9bb6bb
simplify CFG Eval
PROgram52bc 63181c9
feat: add CFG-based Core-to-GOTO pipeline alongside direct path
PROgram52bc 891d1c4
fix comments
PROgram52bc 86e4600
Elimiate unnecessary constructor
PROgram52bc 0fcdc25
Add PR template warning about repository split (#1166)
atomb 4759712
Htd/unstructured procedure experiment (#1169)
PROgram52bc 99b84e5
lake: build Strata lib as a test-driver dependency (#1138)
tautschnig 8acaa4b
The small-step semantics of Imperative must have scoped var init, rem…
aqjune-aws a5d36ed
Support SMT string literals and common string ops in translateTerm (#…
tautschnig 50b0e12
feat: introduce Provenance type and migrate metadata from FileRange (…
MikaelMayer e529f8b
Merge branch 'main' into htd/unstructured-procedure
PROgram52bc 1d47569
Fix bug: ADT constructors do not change `Map` to `Array` when using u…
thanhnguyen-aws 75e806e
Core.formatProgram to produce round-trip-parseable output for all con…
MikaelMayer 0b4c836
Merge branch 'main' into htd/unstructured-procedure
PROgram52bc 6b3c065
bump maxRecDepth
PROgram52bc 7e0bfc7
Merge branch 'origin/main2' into htd/unstructured-procedure
PROgram52bc 7455fc6
review: address PR #1196 feedback (atomb)
PROgram52bc 049ffc5
lint: replace panic! in nondetTransferToCST with ToCSTM.logError fall…
PROgram52bc 0a9c25b
Merge remote-tracking branch 'origin/main2' into htd/unstructured-pro…
PROgram52bc 8734b66
test: adapt new tests from main2 to Procedure.Body sum type
PROgram52bc b44918a
grammar: split " else goto " into two adjacent literals to keep edito…
PROgram52bc fb40291
Merge branch 'main2' into htd/unstructured-procedure
atomb 0f35daf
Merge branch 'main2' into htd/unstructured-procedure
PROgram52bc 31f19bb
fix(merge): post-merge build/test fixups for PR1196 vs main2
PROgram52bc 000a564
fix(test): refresh global_readonly_call expected obligation IDs
PROgram52bc 496f47e
fix(eval): clear Env.deferred on false branch of CFG condGoto (#1317)
PROgram52bc 7218d1d
refactor: drop default MetaData on remaining transfer constructors (f…
PROgram52bc 02dfc08
Merge branch 'main2' into htd/unstructured-procedure
PROgram52bc 9682784
fix(test): use umbrella Strata.DL.Lambda import
PROgram52bc a3825ca
fix(translator): emit conditional transfer with empty accum
PROgram52bc 7750731
Merge remote-tracking branch 'origin/main2' into htd/unstructured-pro…
PROgram52bc cb658ca
fix(test): refresh Loops.lean #guard_msgs provenance byte ranges afte…
PROgram52bc d56b205
fix(test): refresh Exit.lean #guard_msgs provenance byte ranges
PROgram52bc 8bb2739
wip(reconcile #1196): Procedure migrated
PROgram52bc b4b3af7
wip(reconcile #1196): ProcedureType + FormatCore migrated
PROgram52bc 519804a
wip(reconcile #1196): Translate migrated
PROgram52bc 62fb44d
wip(reconcile #1196): StatementSemantics migrated (keep CoreCFGStepSt…
PROgram52bc 340305a
wip(reconcile #1196): StatementEval migrated (keep runCFG path)
PROgram52bc 2f65146
wip(reconcile #1196): ProcedureEval + WF migrated
PROgram52bc 49b1bbb
wip(reconcile #1196): ObligationExtraction migrated
PROgram52bc c94a553
wip(reconcile #1196): CoreToCProverGOTO migrated
PROgram52bc 0c5a0b5
wip(reconcile #1196): Transform batch (ANFEncoder, CoreSpecification,…
PROgram52bc 5806719
wip(reconcile #1196): ProcBodyVerifyCorrect migrated (adopt main2 blo…
PROgram52bc d5adf55
wip(reconcile #1196): test files (Exit golden + ProcedureInlining CFG…
PROgram52bc f991814
wip(reconcile #1196): CoreCFGToGOTOPipeline definedVars arity fix (ca…
PROgram52bc 0360056
Merge remote-tracking branch 'origin/main2' into htd/sync-1196
PROgram52bc 9c0a369
fix(test): migrate StructuredToUnstructuredTests fixture to new typec…
PROgram52bc fd06592
fix(test): update NondetChoice CFG golden for nondet-goto init lowering
PROgram52bc 6754400
fix(StrataBoole): drop redundant command_cfg_procedure match arm
PROgram52bc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,305 @@ | ||
| /- | ||
| Copyright Strata Contributors | ||
|
|
||
| SPDX-License-Identifier: Apache-2.0 OR MIT | ||
| -/ | ||
| module | ||
|
|
||
| public import Strata.Backends.CBMC.CollectSymbols | ||
| public import Strata.Backends.CBMC.GOTO.CoreToCProverGOTO | ||
| import Strata.Backends.CBMC.GOTO.CoreToGOTOPipeline | ||
| import Strata.Transform.StructuredToUnstructured | ||
| import Strata.Languages.Core.StatementSemantics | ||
|
|
||
| /-! ## Core-to-GOTO translation via CFG | ||
|
|
||
| Alternative pipeline that translates Core procedures to CProver GOTO by going | ||
| through the CFG representation: | ||
|
|
||
| - **Structured body** → `stmtsToCFG` → `coreCFGToGotoTransform` | ||
| - **CFG body** → `coreCFGToGotoTransform` | ||
|
|
||
| This coexists with the direct path in `CoreToGOTOPipeline.lean`. | ||
| -/ | ||
|
|
||
| namespace Strata | ||
|
|
||
| public section | ||
|
|
||
| /-! ### Rename helpers for Core commands (CmdExt) -/ | ||
|
|
||
| private def renameCoreCallArg | ||
| (rn : Std.HashMap String String) | ||
| : Core.CallArg Core.Expression → Core.CallArg Core.Expression | ||
| | .inArg e => .inArg (renameExpr rn e) | ||
| | .inoutArg id => .inoutArg (renameIdent rn id) | ||
| | .outArg id => .outArg (renameIdent rn id) | ||
|
|
||
| private def renameCoreCommand | ||
| (rn : Std.HashMap String String) | ||
| : Core.Command → Core.Command | ||
| | .cmd c => .cmd (renameCmd rn c) | ||
| | .call procName callArgs md => | ||
| .call procName (callArgs.map (renameCoreCallArg rn)) md | ||
|
|
||
| private partial def renameCoreStmt | ||
| (rn : Std.HashMap String String) | ||
| : Core.Statement → Core.Statement | ||
| | .cmd c => .cmd (renameCoreCommand rn c) | ||
| | .block l stmts md => | ||
| .block l (stmts.map (renameCoreStmt rn)) md | ||
| | .ite c t e md => | ||
| .ite (c.map (renameExpr rn)) (t.map (renameCoreStmt rn)) (e.map (renameCoreStmt rn)) md | ||
| | .loop g m i body md => | ||
| .loop (g.map (renameExpr rn)) (m.map (renameExpr rn)) | ||
| (i.map (fun (l, e) => (l, renameExpr rn e))) | ||
| (body.map (renameCoreStmt rn)) md | ||
| | .exit l md => .exit l md | ||
| | .funcDecl d md => .funcDecl d md | ||
| | .typeDecl tc md => .typeDecl tc md | ||
|
|
||
| private def renameCoreDetCFG | ||
| (rn : Std.HashMap String String) | ||
| (cfg : Core.DetCFG) : Core.DetCFG := | ||
| { cfg with blocks := cfg.blocks.map fun (label, block) => | ||
| (label, { cmds := block.cmds.map (renameCoreCommand rn), | ||
| transfer := match block.transfer with | ||
| | .condGoto cond lt lf md => | ||
| .condGoto (renameExpr rn cond) lt lf md | ||
| | .finish md => .finish md }) } | ||
|
|
||
| /-! ### Core-specific CFG-to-GOTO translation -/ | ||
|
|
||
| /-- | ||
| Translate a Core `DetCFG` to CProver GOTO instructions. | ||
|
|
||
| Like `detCFGToGotoTransform` but handles `Core.Command` (which includes | ||
| `CmdExt.call`). The CFG should already have identifiers renamed via | ||
| `renameCoreDetCFG`. | ||
| -/ | ||
| def coreCFGToGotoTransform | ||
| (_Env : Core.Expression.TyEnv) (functionName : String) | ||
| (cfg : Core.DetCFG) | ||
| (trans : Imperative.GotoTransform Core.Expression.TyEnv) | ||
| : Except Std.Format (Imperative.GotoTransform Core.Expression.TyEnv) := do | ||
| let toExpr := Lambda.LExpr.toGotoExprCtx | ||
| (TBase := ⟨Core.ExpressionMetadata, Unit⟩) [] | ||
| -- Verify entry block is first | ||
| match cfg.blocks with | ||
| | (firstLabel, _) :: _ => | ||
| if firstLabel != cfg.entry then | ||
| throw f!"[coreCFGToGotoTransform] Entry label '{cfg.entry}' does not match \ | ||
| first block label '{firstLabel}'." | ||
| | [] => pure () | ||
| let mut trans := trans | ||
| let mut pendingPatches : Array (Nat × String) := #[] | ||
| let mut labelMap : Std.HashMap String Nat := {} | ||
| let mut loopContracts : Std.HashMap String (Imperative.MetaData Core.Expression) := {} | ||
| for (label, block) in cfg.blocks do | ||
| labelMap := labelMap.insert label trans.nextLoc | ||
| let srcLoc : CProverGOTO.SourceLocation := | ||
| { CProverGOTO.SourceLocation.nil with function := functionName } | ||
| trans := Imperative.emitLabel label srcLoc trans | ||
| -- Translate each command | ||
| for cmd in block.cmds do | ||
| match cmd with | ||
| | .cmd c => | ||
| trans ← Imperative.Cmd.toGotoInstructions trans.T functionName c trans | ||
| | .call procName callArgs _md => | ||
| let lhs := Core.CallArg.getLhs callArgs | ||
| let args := Core.CallArg.getInputExprs callArgs | ||
| let argExprs ← args.mapM toExpr | ||
| let lhsExpr := match lhs with | ||
| | id :: _ => | ||
| let name := Core.CoreIdent.toPretty id | ||
| let ty := match trans.T.context.types.find? id with | ||
| | some lty => | ||
| match lty.toMonoTypeUnsafe.toGotoType with | ||
| | .ok gty => gty | ||
| | .error _ => | ||
| dbg_trace s!"warning: type conversion failed for {name}, defaulting to Integer" | ||
| .Integer | ||
| | none => | ||
| dbg_trace s!"warning: no type found for {name}, defaulting to Integer" | ||
| .Integer | ||
| CProverGOTO.Expr.symbol name ty | ||
| | [] => CProverGOTO.Expr.symbol "" .Empty | ||
| let calleeExpr := CProverGOTO.Expr.symbol procName | ||
| (CProverGOTO.Ty.mkCode (argExprs.map (·.type)) lhsExpr.type) | ||
| let callCode := CProverGOTO.Code.functionCall lhsExpr calleeExpr argExprs | ||
| let inst : CProverGOTO.Instruction := | ||
| { type := .FUNCTION_CALL, code := callCode, locationNum := trans.nextLoc } | ||
| trans := { trans with | ||
| instructions := trans.instructions.push inst | ||
| nextLoc := trans.nextLoc + 1 } | ||
| -- Translate the transfer command | ||
| match block.transfer with | ||
| | .condGoto cond lt lf md => | ||
| let transferSrcLoc := Imperative.metadataToSourceLoc md functionName trans.sourceText | ||
| let cond_expr ← toExpr cond | ||
| let hasLoopContract := md.any fun elem => | ||
| elem.fld == Imperative.MetaData.specLoopInvariant || | ||
| elem.fld == Imperative.MetaData.specDecreases | ||
| if hasLoopContract then | ||
| loopContracts := loopContracts.insert label md | ||
| let (trans', falseIdx) := | ||
| Imperative.emitCondGoto (CProverGOTO.Expr.not cond_expr) transferSrcLoc trans | ||
| trans := trans' | ||
| pendingPatches := pendingPatches.push (falseIdx, lf) | ||
| let (trans', trueIdx) := Imperative.emitUncondGoto transferSrcLoc trans | ||
| trans := trans' | ||
| pendingPatches := pendingPatches.push (trueIdx, lt) | ||
| | .finish _md => | ||
| pure () | ||
| -- Second pass: resolve labels and annotate backward-edge GOTOs with loop contracts | ||
| let mut resolvedPatches : List (Nat × Nat) := [] | ||
| for (idx, label) in pendingPatches do | ||
| match labelMap[label]? with | ||
| | some targetLoc => | ||
| resolvedPatches := (idx, targetLoc) :: resolvedPatches | ||
| if let some md := loopContracts[label]? then | ||
| let instLoc := trans.instructions[idx]!.locationNum | ||
| if targetLoc ≤ instLoc then | ||
| let mut guard := trans.instructions[idx]!.guard | ||
| for elem in md do | ||
| if elem.fld == Imperative.MetaData.specLoopInvariant then | ||
| if let .expr e := elem.value then | ||
| let gotoExpr ← toExpr e | ||
| guard := guard.setNamedField "#spec_loop_invariant" gotoExpr | ||
| if elem.fld == Imperative.MetaData.specDecreases then | ||
| if let .expr e := elem.value then | ||
| let gotoExpr ← toExpr e | ||
| guard := guard.setNamedField "#spec_decreases" gotoExpr | ||
| trans := { trans with | ||
| instructions := trans.instructions.set! idx | ||
| { trans.instructions[idx]! with guard := guard } } | ||
| | none => | ||
| throw f!"[coreCFGToGotoTransform] Unresolved label '{label}' referenced \ | ||
| by GOTO at instruction index {idx}." | ||
| return Imperative.patchGotoTargets trans resolvedPatches | ||
|
|
||
| /-! ### Pipeline wrapper -/ | ||
|
|
||
| /-- | ||
| Translate a Core procedure to CProver GOTO via the CFG representation. | ||
|
|
||
| Mirrors `procedureToGotoCtx` but routes through `stmtsToCFG` + | ||
| `coreCFGToGotoTransform` instead of the direct Stmt-to-GOTO path. | ||
| -/ | ||
| def procedureToGotoCtxViaCFG | ||
| (Env : Core.Expression.TyEnv) (p : Core.Procedure) | ||
| (sourceText : Option String := none) | ||
| (axioms : List Core.Axiom := []) | ||
| (distincts : | ||
| List (Core.Expression.Ident × List Core.Expression.Expr) := []) | ||
| : Except Std.Format | ||
| (CoreToGOTO.CProverGOTO.Context × List Core.Function) := do | ||
| let pname := Core.CoreIdent.toPretty p.header.name | ||
| if !p.header.typeArgs.isEmpty then | ||
| .error f!"[procedureToGotoCtxViaCFG] Polymorphic procedures unsupported." | ||
| let ret_ty := CProverGOTO.Ty.Empty | ||
| let formals := p.header.inputs.keys.map Core.CoreIdent.toPretty | ||
| let formals_tys ← p.header.inputs.values.mapM Lambda.LMonoTy.toGotoType | ||
| let new_formals := formals.map (CProverGOTO.mkFormalSymbol pname ·) | ||
| let formals_tys : Map String CProverGOTO.Ty := formals.zip formals_tys | ||
| let outputs := p.header.outputs.keys.map Core.CoreIdent.toPretty | ||
| let new_outputs := outputs.map (CProverGOTO.mkLocalSymbol pname ·) | ||
| let locals_from_body := match p.body with | ||
| | .structured ss => (Imperative.Block.definedVars ss false).map Core.CoreIdent.toPretty | ||
| | .cfg c => c.blocks.flatMap (fun (_, blk) => | ||
| blk.cmds.flatMap Core.Command.definedVars) | ||
| |>.map Core.CoreIdent.toPretty | ||
| let new_locals := locals_from_body.map (CProverGOTO.mkLocalSymbol pname ·) | ||
| let rn : Std.HashMap String String := | ||
| (formals.zip new_formals ++ outputs.zip new_outputs ++ locals_from_body.zip new_locals).foldl | ||
| (init := {}) fun m (k, v) => m.insert k v | ||
| -- Seed the type environment with renamed input and output parameter types | ||
| let inputEntries : Map Core.Expression.Ident Core.Expression.Ty := | ||
| (new_formals.zip p.header.inputs.values).map fun (n, ty) => | ||
| (((n : Core.CoreIdent)), .forAll [] ty) | ||
| let outputEntries : Map Core.Expression.Ident Core.Expression.Ty := | ||
| (new_outputs.zip p.header.outputs.values).map fun (n, ty) => | ||
| (((n : Core.CoreIdent)), .forAll [] ty) | ||
| let Env' : Core.Expression.TyEnv := | ||
| Lambda.TEnv.addInNewestContext (T := ⟨Core.ExpressionMetadata, Unit⟩) | ||
| Env (inputEntries ++ outputEntries) | ||
| -- Emit axioms as ASSUME instructions | ||
| let mut axiomInsts : Array CProverGOTO.Instruction := #[] | ||
| let mut axiomLoc : Nat := 0 | ||
| for ax in axioms do | ||
| let gotoExpr ← Lambda.LExpr.toGotoExprCtx | ||
| (TBase := ⟨Core.ExpressionMetadata, Unit⟩) [] ax.e | ||
| if gotoExpr.hasUnsupportedQuantifierTypes then continue | ||
| axiomInsts := axiomInsts.push | ||
| { type := .ASSUME, locationNum := axiomLoc, | ||
| guard := gotoExpr, | ||
| sourceLoc := { CProverGOTO.SourceLocation.nil with | ||
| function := pname, comment := s!"axiom {ax.name}" } } | ||
| axiomLoc := axiomLoc + 1 | ||
| -- Emit distinct declarations as pairwise != ASSUME instructions | ||
| for (dname, exprs) in distincts do | ||
| let gotoExprs ← exprs.mapM | ||
| (Lambda.LExpr.toGotoExprCtx (TBase := ⟨Core.ExpressionMetadata, Unit⟩) []) | ||
| for i in List.range gotoExprs.length do | ||
| for j in List.range gotoExprs.length do | ||
| if i < j then | ||
| let ei := gotoExprs[i]! | ||
| let ej := gotoExprs[j]! | ||
| let neqExpr : CProverGOTO.Expr := | ||
| { id := .binary .NotEqual, type := .Boolean, operands := [ei, ej] } | ||
| let srcLoc : CProverGOTO.SourceLocation := | ||
| { CProverGOTO.SourceLocation.nil with | ||
| function := pname | ||
| comment := s!"distinct {Core.CoreIdent.toPretty dname}" } | ||
| axiomInsts := axiomInsts.push | ||
| { type := .ASSUME, locationNum := axiomLoc, guard := neqExpr, sourceLoc := srcLoc } | ||
| axiomLoc := axiomLoc + 1 | ||
| -- Build the CFG (from structured body or use existing CFG) | ||
| let (cfg, liftedFuncs) ← match p.body with | ||
| | .structured ss => do | ||
| let (liftedFuncs, body) ← collectFuncDecls ss | ||
| let renamedBody := body.map (renameCoreStmt rn) | ||
| let cfg := Imperative.stmtsToCFG renamedBody | ||
| pure (cfg, liftedFuncs) | ||
| | .cfg c => do | ||
| let cfg := renameCoreDetCFG rn c | ||
| pure (cfg, []) | ||
| -- Translate CFG to GOTO | ||
| let ans ← coreCFGToGotoTransform Env' pname cfg | ||
| { instructions := axiomInsts, nextLoc := axiomLoc, T := Env', sourceText := sourceText } | ||
| let ending_insts : Array CProverGOTO.Instruction := | ||
| #[{ type := .END_FUNCTION, locationNum := ans.nextLoc + 1 }] | ||
| let pgm := { name := pname, | ||
| parameterIdentifiers := new_formals.toArray, | ||
| instructions := ans.instructions ++ ending_insts } | ||
| -- Translate procedure contracts | ||
| let mut contracts : List (String × Lean.Json) := [] | ||
| let preExprs := p.spec.preconditions.values.filter (fun c => c.attr == .Default) | ||
| |>.map (fun c => renameExpr rn c.expr) | ||
| let postExprs := p.spec.postconditions.values.filter (fun c => c.attr == .Default) | ||
| |>.map (fun c => renameExpr rn c.expr) | ||
| let toGotoExpr := Lambda.LExpr.toGotoExprCtx | ||
| (TBase := ⟨Core.ExpressionMetadata, Unit⟩) [] | ||
| if !preExprs.isEmpty then | ||
| let preGoto ← preExprs.mapM toGotoExpr | ||
| let preJson ← (preGoto.mapM CProverGOTO.exprToJson).mapError (fun e => f!"{e}") | ||
| contracts := contracts ++ [("#spec_requires", | ||
| Lean.Json.mkObj [("id", ""), ("sub", Lean.Json.arr preJson.toArray)])] | ||
| if !postExprs.isEmpty then | ||
| let postGoto ← postExprs.mapM toGotoExpr | ||
| let postJson ← (postGoto.mapM CProverGOTO.exprToJson).mapError (fun e => f!"{e}") | ||
| contracts := contracts ++ [("#spec_ensures", | ||
| Lean.Json.mkObj [("id", ""), ("sub", Lean.Json.arr postJson.toArray)])] | ||
| -- Build localTypes map for output parameters | ||
| let output_tys ← p.header.outputs.values.mapM Lambda.LMonoTy.toGotoType | ||
| let localTypes : Std.HashMap String CProverGOTO.Ty := | ||
| (outputs.zip output_tys).foldl (init := {}) fun m (k, v) => m.insert k v | ||
| let ctx : CoreToGOTO.CProverGOTO.Context := | ||
| { program := pgm, formals := formals_tys, ret := ret_ty, | ||
| locals := outputs ++ locals_from_body, contracts := contracts, | ||
| localTypes := localTypes } | ||
| return (ctx, liftedFuncs) | ||
|
|
||
| end -- public section | ||
|
|
||
| end Strata | ||
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.