Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
207 commits
Select commit Hold shift + click to select a range
d5d5cb8
Add type checking to Laurel resolution pass
keyboardDrummer-bot May 5, 2026
f65de03
Fix type checking: skip TCore types in assignability check
keyboardDrummer-bot May 5, 2026
7aaea81
Simplify assignment arity check to use valueTy directly
keyboardDrummer-bot May 5, 2026
179d16d
Add tests for type checking error diagnostics in resolution pass
keyboardDrummer-bot May 5, 2026
76ea8df
Add multi-output procedure in expression position check and test
keyboardDrummer-bot May 5, 2026
0a26f1d
Remove checkSingleValued; let type checks report multi-output errors …
keyboardDrummer-bot May 5, 2026
2acc758
Address review feedback: symmetric Eq/Neq errors, extract helper, con…
keyboardDrummer-bot May 6, 2026
e243dbd
add explanations about the typechecking routine added
leo-leesco May 15, 2026
8cb4ab2
bidirectional type checking
leo-leesco May 15, 2026
fbaa911
add resolution-only function
leo-leesco May 15, 2026
39c8dd5
document type system
leo-leesco May 15, 2026
14d27b4
ifthenelse type checking
leo-leesco May 15, 2026
d3750b4
document ifthenelse type checking
leo-leesco May 15, 2026
37e6c35
typechecking description refactor
leo-leesco May 15, 2026
60822bb
reformat typechecking section
leo-leesco May 15, 2026
7d24b64
concise explanations
leo-leesco May 15, 2026
2d85319
restore contexts in rules
leo-leesco May 15, 2026
55083a6
simplify presentation
leo-leesco May 15, 2026
1feda5b
add back in contexts
leo-leesco May 15, 2026
9bb2990
describe literals and easy rules (call, assert/assume…)
leo-leesco May 15, 2026
fea9f95
remove old helpers + mis-subtyping diagnostics
leo-leesco May 15, 2026
ce11f12
quantifier check for bool body
leo-leesco May 15, 2026
2207acc
remove redundant headings
leo-leesco May 15, 2026
4cbab19
class-rules : updates on same-typed fields + this in class context only
leo-leesco May 15, 2026
0a38a7c
references checks
leo-leesco May 15, 2026
3efef2f
pretty printers
leo-leesco May 15, 2026
59ce64d
better type mismatch diagnostics
leo-leesco May 15, 2026
538a687
check ifthenelse
leo-leesco May 15, 2026
a0862ee
type check returns
leo-leesco May 15, 2026
b58a578
type check procedures contracts
leo-leesco May 15, 2026
1a639d1
check untyped holes
leo-leesco May 15, 2026
5717c34
remove dangling reference
leo-leesco May 15, 2026
d8b8c7c
move subtyping/consistency rules in type definition
leo-leesco May 15, 2026
bbee6a7
inferholetypes flag already filled hole types when inconsistent
leo-leesco May 15, 2026
9e4c2f3
future roadmap
leo-leesco May 15, 2026
6fc8e36
fix multi value return destructuring
leo-leesco May 15, 2026
dbc220a
fix error messages to match current type mismatch reporting
leo-leesco May 15, 2026
4cb6de7
fix error reporting location
leo-leesco May 15, 2026
12c7a96
fix location error reporting
leo-leesco May 15, 2026
83fba02
Merge branch 'leo/1120-type-checking' into keyboardDrummer-bot/issue-…
leo-leesco May 15, 2026
9e353ac
fix field lookup
leo-leesco May 18, 2026
228559e
fix silent fail
leo-leesco May 18, 2026
3b3e598
thread typing context through type resolution/inheritance
leo-leesco May 18, 2026
2dffa2a
drop info
leo-leesco May 18, 2026
e69d58f
Merge branch 'leo/1120-type-checking' into keyboardDrummer-bot/issue-…
leo-leesco May 18, 2026
6fa3c22
fix typing doc direction
leo-leesco May 19, 2026
3440420
fix documentation : subtyping is implemented
leo-leesco May 19, 2026
8fc56ae
remove special treatment of TCore
leo-leesco May 19, 2026
d476f6b
fix TCore documentation
leo-leesco May 19, 2026
40236ce
uniform <=/=> and use latex rule presentation
leo-leesco May 19, 2026
c544b2b
extract typing rules out in helper functions for easier verso documen…
leo-leesco May 19, 2026
b0ffaf5
better if-then-else typing discipline
leo-leesco May 19, 2026
887c888
if then else type synthesis
leo-leesco May 19, 2026
8ad24ac
move test to appropriate location
leo-leesco May 19, 2026
4f7b6ba
very strict dereference comparison
leo-leesco May 19, 2026
59a8461
consistent references when comparing
leo-leesco May 19, 2026
8a950f8
fix assign by creating a checking rule
leo-leesco May 20, 2026
fd75ea5
documentation is moved to in-code docstrings
leo-leesco May 20, 2026
fbb5c81
namespace scoping to make code less verbose
leo-leesco May 20, 2026
2a3536a
Add type checking to Laurel resolution pass
keyboardDrummer-bot May 5, 2026
39b4f6c
Fix type checking: skip TCore types in assignability check
keyboardDrummer-bot May 5, 2026
bdae7eb
Simplify assignment arity check to use valueTy directly
keyboardDrummer-bot May 5, 2026
f5302f9
Add tests for type checking error diagnostics in resolution pass
keyboardDrummer-bot May 5, 2026
7d00fae
add explanations about the typechecking routine added
leo-leesco May 15, 2026
941f4ae
bidirectional type checking
leo-leesco May 15, 2026
be1d8de
add resolution-only function
leo-leesco May 15, 2026
83e449f
document type system
leo-leesco May 15, 2026
a7d90d6
ifthenelse type checking
leo-leesco May 15, 2026
0958f26
document ifthenelse type checking
leo-leesco May 15, 2026
2a513c7
typechecking description refactor
leo-leesco May 15, 2026
fcbe1fc
reformat typechecking section
leo-leesco May 15, 2026
084fa2d
concise explanations
leo-leesco May 15, 2026
294be7b
restore contexts in rules
leo-leesco May 15, 2026
06ce7b9
simplify presentation
leo-leesco May 15, 2026
835d8b5
add back in contexts
leo-leesco May 15, 2026
a7ae7bb
describe literals and easy rules (call, assert/assume…)
leo-leesco May 15, 2026
f3d657e
remove old helpers + mis-subtyping diagnostics
leo-leesco May 15, 2026
054a8ba
quantifier check for bool body
leo-leesco May 15, 2026
597c79e
remove redundant headings
leo-leesco May 15, 2026
3ea2431
class-rules : updates on same-typed fields + this in class context only
leo-leesco May 15, 2026
7872826
references checks
leo-leesco May 15, 2026
b212eb5
pretty printers
leo-leesco May 15, 2026
c51fc96
better type mismatch diagnostics
leo-leesco May 15, 2026
a70d171
check ifthenelse
leo-leesco May 15, 2026
453d293
type check returns
leo-leesco May 15, 2026
7bc098d
type check procedures contracts
leo-leesco May 15, 2026
c69210a
check untyped holes
leo-leesco May 15, 2026
e823cef
remove dangling reference
leo-leesco May 15, 2026
47ad5db
move subtyping/consistency rules in type definition
leo-leesco May 15, 2026
40e1572
inferholetypes flag already filled hole types when inconsistent
leo-leesco May 15, 2026
3897097
future roadmap
leo-leesco May 15, 2026
86b6d27
fix multi value return destructuring
leo-leesco May 15, 2026
18eb6c9
fix error messages to match current type mismatch reporting
leo-leesco May 15, 2026
151efeb
Add multi-output procedure in expression position check and test
keyboardDrummer-bot May 5, 2026
d7e2903
fix error reporting location
leo-leesco May 15, 2026
138993c
Remove checkSingleValued; let type checks report multi-output errors …
keyboardDrummer-bot May 5, 2026
4a4bbc6
fix location error reporting
leo-leesco May 15, 2026
d9caa37
Address review feedback: symmetric Eq/Neq errors, extract helper, con…
keyboardDrummer-bot May 6, 2026
65bc2b0
Merge branch 'leo/1120-type-checking' into keyboardDrummer-bot/issue-…
leo-leesco May 15, 2026
f2fea0a
thread typing context through type resolution/inheritance
leo-leesco May 18, 2026
f4fd6ff
fix field lookup
leo-leesco May 18, 2026
fb6fdd6
drop info
leo-leesco May 18, 2026
f5f57c1
fix silent fail
leo-leesco May 18, 2026
06ab507
Merge branch 'leo/1120-type-checking' into keyboardDrummer-bot/issue-…
leo-leesco May 18, 2026
c28cd1c
fix typing doc direction
leo-leesco May 19, 2026
cdfdda8
fix documentation : subtyping is implemented
leo-leesco May 19, 2026
fbb1de3
remove special treatment of TCore
leo-leesco May 19, 2026
a4674bd
fix TCore documentation
leo-leesco May 19, 2026
77d32f1
uniform <=/=> and use latex rule presentation
leo-leesco May 19, 2026
ccc2a98
extract typing rules out in helper functions for easier verso documen…
leo-leesco May 19, 2026
3d61b04
better if-then-else typing discipline
leo-leesco May 19, 2026
665e88f
if then else type synthesis
leo-leesco May 19, 2026
95763e2
move test to appropriate location
leo-leesco May 19, 2026
0341105
very strict dereference comparison
leo-leesco May 19, 2026
3fbb542
consistent references when comparing
leo-leesco May 19, 2026
2502825
fix assign by creating a checking rule
leo-leesco May 20, 2026
c9ce940
documentation is moved to in-code docstrings
leo-leesco May 20, 2026
d2de9da
namespace scoping to make code less verbose
leo-leesco May 20, 2026
8ceaf32
Merge branch 'leo/1120-type-checking' of github.com:strata-org/strata…
leo-leesco May 20, 2026
5826fff
cleanup rules presentation
leo-leesco May 20, 2026
1cde2a1
expand prose around Block typing rules
leo-leesco May 20, 2026
cc16c3e
remove synthesis rule for if-then-else
leo-leesco May 20, 2026
fbccb15
remove synthesis rule for blocks
leo-leesco May 20, 2026
7d3cdf6
move statement-shaped constructs to check-only
leo-leesco May 20, 2026
be18c88
move Old and ProveBy to check-only
leo-leesco May 20, 2026
4c23930
push assignment target types into RHS
leo-leesco May 20, 2026
971c39d
fix return type
leo-leesco May 20, 2026
f3da746
add [⇐] Assign entry to typing-rule index
leo-leesco May 20, 2026
5717a72
remove synthesis rule for assign
leo-leesco May 20, 2026
88e01cb
better docstrings
leo-leesco May 20, 2026
f0016e6
move holes to check-only, roll back InferHoleTypes
leo-leesco May 21, 2026
6f64515
Merge branch 'leo/1120-type-checking' into keyboardDrummer-bot/issue-…
leo-leesco May 21, 2026
778faf7
remove future structural changes entirely
leo-leesco May 21, 2026
b649e94
update rules
leo-leesco May 21, 2026
26c0c82
fix error reporting
leo-leesco May 22, 2026
1e8050d
have operators check as much as possible
leo-leesco May 22, 2026
8be2b90
improve typing rules index
leo-leesco May 26, 2026
032c46f
update block rules + is/asType
leo-leesco May 27, 2026
9ec6dec
first try at arithmetic typing
leo-leesco May 27, 2026
d4b0d62
arith operators
leo-leesco May 27, 2026
b5d4190
update rules documentation
leo-leesco May 27, 2026
f0e5351
simplify arith operator type inference
leo-leesco May 27, 2026
4de8b89
Merge remote-tracking branch 'origin/main2' into keyboardDrummer-bot/…
leo-leesco May 27, 2026
7bce041
error reporting on binary operators
leo-leesco May 27, 2026
e306965
fix incorrect verso syntax
leo-leesco May 28, 2026
c33d1b8
workaround to make TCore Any ~ UserDefined Any
leo-leesco May 28, 2026
0eb841a
move type consistency check type-unfolding to call-site
leo-leesco May 28, 2026
9045907
Core Any + UserDefined Any as dynamic types
leo-leesco May 28, 2026
28dcf86
typecheck impure calls that return a value against TVoid
leo-leesco May 28, 2026
a32a136
synth hole type
leo-leesco May 28, 2026
9d7f9b1
fix test after holes synthesize their types
leo-leesco May 28, 2026
47b14ca
fix misreporting on rules
leo-leesco May 28, 2026
9be6a47
explicitly include labels for namespace resolution
leo-leesco May 29, 2026
c559a62
generalize TCore gradual rule, drop Any special-casing
leo-leesco Jun 2, 2026
455d024
rewrite and simplify block rule
leo-leesco Jun 2, 2026
613e3f8
fix label context resolution
leo-leesco Jun 2, 2026
bf8bbb8
Merge branch 'main2' into keyboardDrummer-bot/issue-1120-type-checking
leo-leesco Jun 2, 2026
c50c8e6
update documentation
leo-leesco Jun 3, 2026
2f39d28
reword block rule
leo-leesco Jun 4, 2026
2bcaa1b
Merge branch 'main2' into keyboardDrummer-bot/issue-1120-type-checking
leo-leesco Jun 4, 2026
370542f
rename lub to join
leo-leesco Jun 4, 2026
178dfa1
fix compilation pipeline
leo-leesco Jun 4, 2026
aacf861
centralize $body tag
leo-leesco Jun 4, 2026
c780864
clarify typing rules
leo-leesco Jun 4, 2026
980d1ad
fix imports
leo-leesco Jun 5, 2026
3c15bb9
fix variable shadowing
leo-leesco Jun 8, 2026
fb97ba5
Merge branch 'main2' into keyboardDrummer-bot/issue-1120-type-checking
leo-leesco Jun 8, 2026
7e42c7a
add small glossary
leo-leesco Jun 8, 2026
dcff9b4
test variable "shadowing" (in a field)
leo-leesco Jun 8, 2026
e734ed7
Merge branch 'keyboardDrummer-bot/issue-1120-type-checking' of github…
leo-leesco Jun 8, 2026
6208951
clearer high level explanations
leo-leesco Jun 8, 2026
851f8c9
update docstring rule presentation
leo-leesco Jun 8, 2026
4eaa89e
add in undocumented cases
leo-leesco Jun 8, 2026
7afbe45
Merge branch 'main2' into keyboardDrummer-bot/issue-1120-type-checking
leo-leesco Jun 8, 2026
ca3f6ba
add synth ifthenelse/block
leo-leesco Jun 9, 2026
bece7b2
void procedures check against void instead of MultiReturn []
leo-leesco Jun 9, 2026
53cf3e7
old types pass through
leo-leesco Jun 9, 2026
21834f0
stop dropping first parameter on staticProcedure
leo-leesco Jun 9, 2026
d815958
document new rules (synth if/block)
leo-leesco Jun 9, 2026
bc069b3
remove stale documentation
leo-leesco Jun 9, 2026
8d09368
fix rule presentation
leo-leesco Jun 9, 2026
c875841
void staticProcedures return TVoid
leo-leesco Jun 9, 2026
88e4499
add call resolution support for instanceProcedures
leo-leesco Jun 9, 2026
e1025ef
make bitvectors numeric
leo-leesco Jun 9, 2026
451dbfc
Merge branch 'main2' (transparent procedures #1215) into type-checkin…
leo-leesco Jun 11, 2026
1fd40cc
typecontext -> typelattice
leo-leesco Jun 11, 2026
5bae88d
explain invariance rules for collection types
leo-leesco Jun 11, 2026
fa629e3
fix(laurel): collapse unresolved type names to Unknown to stop diagno…
leo-leesco Jun 11, 2026
644c111
feat(laurel): reject over-arity calls to known procedures
leo-leesco Jun 11, 2026
eb5f354
fix(laurel): reject multi-output calls used as operator operands
leo-leesco Jun 11, 2026
d90c03b
docs(laurel): document bitvectors as a numeric type
leo-leesco Jun 11, 2026
6f5aad5
refactor(laurel): symmetrize Synth.ifThenElse via join (branch-order …
leo-leesco Jun 11, 2026
cb98beb
Merge branch 'main2' into keyboardDrummer-bot/issue-1120-type-checking
leo-leesco Jun 11, 2026
7c32f11
collapse identical branches
leo-leesco Jun 11, 2026
03e56c6
make which op category we check explicit
leo-leesco Jun 11, 2026
d36cbdf
remove self explanatory docstring
leo-leesco Jun 11, 2026
a32917c
simplify stale explanation
leo-leesco Jun 11, 2026
995991b
Merge branch 'main2' into keyboardDrummer-bot/issue-1120-type-checking
leo-leesco Jun 12, 2026
b85c480
Merge main into main2 (2026-06-11) (#1363)
shigoel Jun 12, 2026
88a66b9
update documentation
leo-leesco Jun 12, 2026
f118ed6
update tests
leo-leesco Jun 12, 2026
04bd682
Merge branch 'main2' into keyboardDrummer-bot/issue-1120-type-checking
leo-leesco Jun 12, 2026
175446f
fix duplicate error reported
leo-leesco Jun 12, 2026
bff10cf
better formatting for documentation
leo-leesco Jun 16, 2026
aa29d72
Merge branch 'reviewed-kbd-will-merge-to-main' into keyboardDrummer-b…
leo-leesco Jun 17, 2026
265f1d1
typecheck ++/--
leo-leesco Jun 17, 2026
98002c0
Merge branch 'reviewed-kbd-will-merge-to-main' into keyboardDrummer-b…
leo-leesco Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .kiro/steering/structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ Strata is a Lean4 verification framework using **dialects** as composable langua
- `Strata/` - Core implementation (DDM, dialects, languages, transforms, backends)
- `StrataTest/` - Unit tests (mirrors Strata/ structure)
- `Examples/` - Sample programs (`.st` files, naming: `<name>.<dialect>.st`)
- `Tools/` - External tools (BoogieToStrata, Python utilities)
- `vcs/` - Generated SMT2 verification conditions

### Core Components

Expand All @@ -34,9 +32,7 @@ Strata is a Lean4 verification framework using **dialects** as composable langua
- `Core/` - Primary verification language (procedures, contracts, VCG, SMT encoding)
- `C_Simp/` - Simplified C-like language
- `Dyn/` - Dynamic language example
- `Laurel/` - A common representation for front-end languages like Java, Python and JavaScript.
Translated to Core.
- `Python/` - The well-known Python language
- `Laurel/` - A common representation for front-end languages like Java, Python and JavaScript. Translated to Core.

**`Strata/Transform/`** - Program Transformations
- Each transformation has implementation + optional correctness proof (`*Correct.lean`)
Expand Down
29 changes: 5 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,10 @@ changes!**
(`cvc5` and `z3`). See [Installing dependencies → SMT Solvers](#smt-solvers)
below.

3. **Python 3.11+**: required for Python-related tests and the `strata`
Python tooling. See [Installing dependencies → Python](#python) below.

4. **Java JDK (11 or later)**: required for Java code generation tests.
3. **Java JDK (11 or later)**: required for Java code generation tests.
See [Installing dependencies → Java](#java-for-code-generation-tests) below.

5. **ion-java jar (1.11.11)**: required for the Java/Ion integration test.
4. **ion-java jar (1.11.11)**: required for the Java/Ion integration test.
See [Installing dependencies → Java](#java-for-code-generation-tests) below.

### Installing dependencies
Expand All @@ -54,18 +51,6 @@ cp /path/to/cvc5 /path/to/z3 ~/.local/bin/
# or: sudo cp /path/to/cvc5 /path/to/z3 /usr/local/bin/
```

#### Python

Python 3.11 or later is required. Install the `strata` Python package inside a
virtual environment (recommended; avoids PEP 668's `externally-managed-environment`
error on Debian/Ubuntu 23.04+):

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install ./Tools/Python
```

#### Java (for code generation tests)

A JDK (11+) providing `javac` must be on your `PATH`. For running the
Expand All @@ -81,7 +66,6 @@ wget -q -O StrataTestExtra/Languages/Java/testdata/ion-java-1.11.11.jar \
```bash
cvc5 --version # should print version info
z3 --version # should print version info
python3 --version # should be 3.11+
```

## Build
Expand Down Expand Up @@ -111,13 +95,10 @@ Two kinds of tests coexist in this repo:
These accept prefix filters:

```bash
# Run all extra tests except Python (which requires the Python package)
lake test -- --exclude Languages.Python

# Run only Python extra tests (requires `pip install ./Tools/Python`)
lake test -- Languages.Python
# Run all extra tests except those in the Imperative namespace
lake test -- --exclude DL.Imperative

# Run all extra tests (Python tests will fail without the Python package above)
# Run all extra tests
lake test
```

Expand Down
79 changes: 79 additions & 0 deletions Scripts/JavaGenTestData.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/-
Copyright Strata Contributors

SPDX-License-Identifier: Apache-2.0 OR MIT
-/
import StrataDDM

/-!
# Java test data generation helper

Usage:
lake env lean --run Scripts/JavaGenTestData.lean javaGen <dialect-file> <package> <output-dir>
lake env lean --run Scripts/JavaGenTestData.lean print --include <dir> <file>

Note: Unlike the former CLI `javaGen` command, this script only loads dialects
from files — it does not support referencing preloaded dialect names directly.
This is sufficient for the testdata regeneration workflow.
-/

open StrataDDM

def javaGen (dialectPath packageName outputDir : String) : IO Unit := do
let fm ← mkDialectFileMap
let d ← readStrataDialectFile fm dialectPath
match StrataDDM.Java.generateDialect d packageName with
| .ok files =>
StrataDDM.Java.writeJavaFiles outputDir packageName files
IO.println s!"Generated Java files for {d.name} in {outputDir}/{StrataDDM.Java.packageToPath packageName}"
| .error msg =>
IO.eprintln s!"Error generating Java: {msg}"
IO.Process.exit 1

def printFile (includeDirs : List String) (file : String) : IO Unit := do
let fm ← mkDialectFileMap
let mut fm := fm
for dir in includeDirs do
match ← fm.addSearchPath dir |>.toBaseIO with
| .error msg =>
IO.eprintln msg
IO.Process.exit 1
| .ok fm' => fm := fm'
let ld ← fm.getLoaded
if mem : file ∈ ld.dialects then
IO.print <| ld.dialects.format file mem
return
match ← readStrataFile fm file with
| .dialect d =>
let ld ← fm.getLoaded
if mem : d.name ∈ ld.dialects then
IO.print <| ld.dialects.format d.name mem
else
IO.eprintln "Internal error reading file."
IO.Process.exit 1
| .program pgm =>
IO.print <| toString pgm

private def parseIncludeArgs (args : List String) : List String × List String :=
go args []
where
go : List String → List String → List String × List String
| "--include" :: dir :: rest, includes => go rest (dir :: includes)
| other, includes => (includes.reverse, other)

def main (args : List String) : IO Unit := do
match args with
| "javaGen" :: dialectPath :: packageName :: outputDir :: _ =>
javaGen dialectPath packageName outputDir
| "print" :: rest =>
let (includeDirs, fileArgs) := parseIncludeArgs rest
match fileArgs with
| [file] => printFile includeDirs file
| _ =>
IO.eprintln "Usage: ... print [--include <dir>]... <file>"
IO.Process.exit 1
| _ =>
IO.eprintln "Usage:"
IO.eprintln " lake env lean --run Scripts/JavaGenTestData.lean javaGen <dialect> <package> <output-dir>"
IO.eprintln " lake env lean --run Scripts/JavaGenTestData.lean print [--include <dir>]... <file>"
IO.Process.exit 1
134 changes: 134 additions & 0 deletions Scripts/LaurelToCBMC.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/-
Copyright Strata Contributors

SPDX-License-Identifier: Apache-2.0 OR MIT
-/
import Strata.Backends.CBMC.GOTO.CoreToGOTOPipeline
import Strata.Languages.Laurel

/-! # LaurelToCBMC

Script that replaces `laurel_to_cbmc.sh`. Translates a Laurel `.lr.st` source
file through the full Strata pipeline to CBMC verification:

1. Parse Laurel source → Laurel AST
2. Translate Laurel → Core
3. Inline procedures, type-check, generate CProver GOTO JSON
4. Invoke `symtab2gb` to produce a GOTO binary
5. Invoke `goto-cc` to add C scaffolding
6. Invoke `goto-instrument --dfcc` for contract instrumentation
7. Invoke `cbmc` for bounded model checking

Usage:
lake env lean --run Scripts/LaurelToCBMC.lean <file.lr.st>

Environment variables:
CBMC - path to cbmc binary (default: cbmc)
GOTO_CC - path to goto-cc binary (default: goto-cc)
GOTO_INSTRUMENT - path to goto-instrument binary (default: goto-instrument)
-/

open Strata

/-- Strip well-known Strata file suffixes from a file path's basename. -/
private def deriveBaseName (file : String) : String :=
let name := System.FilePath.fileName file |>.getD file
let suffixes := [".lr.st", ".laurel.st", ".st"]
match suffixes.find? (name.endsWith ·) with
| some sfx => (name.dropEnd sfx.length).toString
| none => name

/-- Read an environment variable, returning a default if unset or empty. -/
private def getEnvOrDefault (var : String) (default : String) : IO String := do
match ← IO.getEnv var with
| some v => if v.isEmpty then pure default else pure v
| none => pure default

/-- Run an external process. Prints stdout/stderr to the caller's streams and
returns the exit code. -/
private def runProcess (step : String) (cmd : String) (args : Array String) : IO UInt32 := do
let proc ← IO.Process.spawn {
cmd := cmd
args := args
stdout := .inherit
stderr := .inherit
stdin := .inherit
}
let exitCode ← proc.wait
if exitCode != 0 then
IO.eprintln s!"Error: {step} failed (exit code {exitCode})"
return exitCode

/-- The Laurel-to-GOTO translation pipeline. Parses a Laurel source file,
translates to Core, inlines procedures, type-checks, and emits CProver GOTO
JSON files (`<baseName>.symtab.json` and `<baseName>.goto.json`) in the
given output directory. -/
private def laurelAnalyzeToGoto (path : System.FilePath) (outputDir : System.FilePath)
(baseName : String) : IO Unit := do
let content ← IO.FS.readFile path
let laurelProgram ← Strata.parseLaurelText path content
match ← Strata.Laurel.translate {} laurelProgram with
| (none, diags) =>
throw (IO.userError s!"Core translation errors: {diags.map (·.message)}")
| (some coreProgram, _) =>
-- Use the output directory as a prefix so files land in tmpDir
let outputBaseName := (outputDir / baseName).toString
match ← Strata.inlineCoreToGotoFiles coreProgram outputBaseName
(sourceText := some content) |>.toBaseIO with
| .ok () => pure ()
| .error msg => throw (IO.userError msg)

def main (args : List String) : IO UInt32 := do
match args with
| [file] =>
unless file.endsWith ".lr.st" || file.endsWith ".laurel.st" do
IO.eprintln s!"Error: expected a .lr.st file, got: {file}"
return 1
let path : System.FilePath := file
unless ← path.pathExists do
IO.eprintln s!"Error: file not found: {file}"
return 1
let baseName := deriveBaseName file

-- Use a temporary directory for intermediate files (cleaned up automatically)
IO.FS.withTempDir fun tmpDir => do

-- Step 1: Laurel → GOTO JSON (in tmp dir)
let result ← (laurelAnalyzeToGoto path tmpDir baseName).toBaseIO
match result with
| .error e =>
IO.eprintln s!"Error: {e}"
return 1
| .ok () => pure ()

let symTabFile := (tmpDir / s!"{baseName}.symtab.json").toString
let gotoFile := (tmpDir / s!"{baseName}.goto.json").toString
let gbFile := (tmpDir / s!"{baseName}.gb").toString
let ccGbFile := (tmpDir / s!"{baseName}_cc.gb").toString
let dfccGbFile := (tmpDir / s!"{baseName}_dfcc.gb").toString

-- Step 2: symtab2gb
let rc ← runProcess "symtab2gb" "symtab2gb"
#[symTabFile, "--goto-functions", gotoFile, "--out", gbFile]
if rc != 0 then return rc

-- Step 3: goto-cc (add C scaffolding)
let gotoCC ← getEnvOrDefault "GOTO_CC" "goto-cc"
let rc ← runProcess "goto-cc" gotoCC
#["--function", "main", "-o", ccGbFile, gbFile]
if rc != 0 then return rc

-- Step 4: goto-instrument --dfcc
let gotoInstrument ← getEnvOrDefault "GOTO_INSTRUMENT" "goto-instrument"
let rc ← runProcess "goto-instrument --dfcc" gotoInstrument
#["--dfcc", "main", ccGbFile, dfccGbFile]
if rc != 0 then return rc

-- Step 5: cbmc verification
let cbmc ← getEnvOrDefault "CBMC" "cbmc"
runProcess "cbmc" cbmc
#[dfccGbFile, "--function", "main", "--z3", "--verbosity", "9"]

| _ =>
IO.eprintln "Usage: LaurelToCBMC <file.lr.st>"
return 1
Loading
Loading