POCKET+ / CCSDS 124.0-B-1 lossless housekeeping-telemetry codec, formally specified in Scala for Stainless, transpiled to C (Stainless GenC), wrapped in a small C ABI, and exercised from Python.
scala/PocketPlus.scala the single source of truth (Stainless-verifiable, GenC-compatible)
native/ C project: GenC output + hand-written DLL shim (pp_* API) → pocketplus.dll
python/ Python project: ctypes interop + pytest round-trip suite
tools/stainless/ vendored Stainless toolchain (jar + z3 + cvc5)
build/ MSBuild glue (GenC + Verify) — no shell scripts
data/ private test vectors (git-ignored; see data/README.md)
- JDK with
javaonPATHandJAVA_HOMEset (only used to run the vendored Stainless). - Python 3 on
PATH(the test dependencies live in a VS-managed virtual environment). - Visual Studio with the "C++ Clang tools for Windows" component (provides the
ClangCLplatform toolset — required because the GenC output uses C99 variable-length arrays that MSVC'sclrejects) and the Python development workload.
Nothing else: the Stainless compiler and the z3/cvc5 solvers are vendored under tools/stainless/.
Open pocket-plus.slnx. The first time, accept VS's prompt to create the virtual environment from
python/requirements.txt (or it is created automatically on first build).
Build Solution in Debug or Release:
- regenerates
native/generated/pocketplus.{c,h}fromscala/PocketPlus.scala(only when the Scala changed — incremental), - compiles
pocketplus.dllwith ClangCL, - runs the Python
pytestinterop suite, excluding the slowverifytest (a failing test fails the build).
Run the tests from Test Explorer (Test → Test Explorer) — build once so pocketplus.dll
exists, then Run/Debug individual tests.
Run formal verification as the verify-marked test: in Test Explorer run
test_stainless_all_vcs_valid (under python/tests/test_verify.py), or from the CLI
pytest -m verify. It runs Stainless over all VCs and fails if any VC is invalid or unknown
(a strict gate). It is excluded from ordinary builds because it is slow; results are cached under
build/.stainless-cache, so re-runs only re-check changed VCs. Override the per-VC timeout with the
POCKETPLUS_VERIFY_TIMEOUT env var (default 5s).
From a Developer Command Prompt for VS (so msbuild/ClangCL are on PATH):
msbuild pocket-plus.slnx /t:Build /p:Configuration=Debug # GenC → DLL → pytest (no verify)
cd python && env\Scripts\python -m pytest tests -m verify # Stainless verification gate
- The codec API the DLL exports (
pp_compressor_create,pp_compress,pp_decompressor_create,pp_decompress, ...) is hand-written innative/src/pp_shim.c; it owns the buffers so Python only passes flat(bool*, length)arrays. The GenC output innative/generated/is never hand-edited. - The verification gate is red by design today: the Scala carries no verification invariants yet, so the array-bounds / overflow / termination VCs are unproven. It turns green as invariants are added.
- To regenerate or verify outside VS, the same
java -jar tools/stainless/lib/...jarinvocations used bybuild/Stainless.targetsandpython/pocketplus/verify.pycan be run directly (python -m pocketplus.verify).