BoogieToStrata is a C# command-line tool that translates Boogie source files (.bpl) into Strata Core programs (.core.st). It uses the official Boogie frontend for parsing and type-checking, then emits equivalent Strata Core syntax that can be verified by the Strata toolchain.
The translator handles most of the Boogie language including:
- Procedures with requires/ensures/modifies contracts
- Structured control flow (if/else, while loops, break)
- Unstructured control flow (goto with forward jumps, back-edge detection for loop recovery)
- Currently, irreducible CFGs that cannot be translated to structured loops are unsupported
- Types: bool, int, real, bitvectors, maps, user-defined type constructors and synonyms
- Expressions: quantifiers (forall/exists) with triggers, lambda, let, old, map select/store
- Bitvector operations (concat, extract, arithmetic, comparisons)
- Constants (including unique constraints), axioms, pure functions with bodies
- Heap modeling (Ref/Field/Heap pattern recognition and translation)
- SMACK-generated Boogie (via
--smackflag)
BoogieToStrata.sln # Visual Studio solution
Source/
├── BoogieToStrata.csproj # Main project
├── BoogieToStrata.cs # CLI entry point (arg parsing, Boogie pipeline invocation)
└── StrataGenerator.cs # Core translation logic (Boogie AST → Strata Core text)
IntegrationTests/
├── BoogieToStrata.IntegrationTests.csproj # xUnit test project
└── BoogieToStrataIntegrationTests.cs # Translation + verification tests
Tests/ # Test inputs (.bpl) and expected outputs (.expect)
run-integration-tests.sh # Build + run integration tests
- .NET 8 SDK
- The Strata
stratabinary (built vialake buildin the repo root) — needed for integration tests that verify translated output
dotnet build Source/BoogieToStrata.csprojThe built executable lands in Source/bin/Debug/net8.0/BoogieToStrata.dll.
# Basic translation (output goes to stdout)
dotnet Source/bin/Debug/net8.0/BoogieToStrata.dll <input.bpl> > output.core.st
# SMACK mode (infers modifies clauses, injects assert preconditions)
dotnet Source/bin/Debug/net8.0/BoogieToStrata.dll --smack <input.bpl> > output.core.stThe tool:
- Parses the Boogie file using the official Boogie parser
- Resolves and type-checks the program
- Emits Strata Core syntax to stdout
Exit codes:
0— success1— parse error, type-check failure, or unsupported construct
The --smack flag enables two accommodations for
SMACK-generated Boogie:
-
InferModifies — Boogie's ModSetCollector infers missing
modifiesclauses so programs without explicit clauses still type-check. -
Synthetic requires — Procedures matching
assert_.<type>(p)get an injectedrequires (p != 0)precondition, enabling the call-elimination pass to generate a VC checking the assertion condition.
Files can opt into SMACK mode in the integration tests by including {:smack}
in their first 5 lines.
Boogie global variables are translated into procedure parameters:
- Globals in the
modifiesclause becomeinoutparameters - All other globals become read-only input parameters
- Call sites are updated to pass globals accordingly
The translator handles Boogie's unstructured control flow (goto/labels) by:
-
Detecting back-edges to identify loops → emitted as
while (true)with labeled blocks (though irreducible loops are currently unsupported) -
Forward gotos → emitted as
exit <label>within labeled wrapper blocks -
Two-target gotos with opposite assume guards → emitted as
if/else
When the translator detects the Ref/Field/Heap pattern (common in SMACK and
other tools), it emits specialized StrataHeapSelect_<type> and
StrataHeapUpdate_<type> function calls instead of raw map operations.
Boogie identifiers containing @, ., #, ^, or $ are sanitized (replaced
with _). When sanitization causes collisions between declarations, the
translator renames later declarations with a prefix (__proc_, __const_,
__func_, __var_). Procedures always win collisions.
The integration test suite translates each .bpl file and optionally verifies the output with the Strata verifier:
# Run all integration tests
./run-integration-tests.sh
# Or directly with dotnet
dotnet test IntegrationTests/BoogieToStrata.IntegrationTests.csprojEach test:
- Translates the
.bplfile to Strata Core - If a
.expectfile exists: runsstrata verifyand compares output to the expected results - If no
.expectfile exists: runsstrata verify --check(parse + type-check only)
Tests/<Name>.bpl— Boogie input fileTests/<Name>.expect— Expected verification output (optional; if absent, only type-checking is tested)
- Create
Tests/<Name>.bplwith the Boogie program - Run the translator manually to verify it works:
dotnet Source/bin/Debug/net8.0/BoogieToStrata.dll Tests/<Name>.bpl
- If the program should verify, run it through Strata and capture the expected output:
dotnet Source/bin/Debug/net8.0/BoogieToStrata.dll Tests/<Name>.bpl > Tests/<Name>.core.st ../../.lake/build/bin/strata verify Tests/<Name>.core.st > Tests/<Name>.expect rm Tests/<Name>.core.st
- Run the integration tests to confirm everything passes
- Datatypes are not yet supported (throws
StrataConversionException) - Irreducible control flow (overlapping loop regions) is rejected
- Multi-target gotos (3+ targets) are not supported unless they can be decomposed
- Real constants have limited support
Apache-2.0 OR MIT