formal-lib
A Python library that provides structured representations of software verifier output.
Installation
- PyPI (Recommended)
- GitHub Releases
Backends
The following backends are supported:
- ESBMC
- CBMC
- Clang
- PyTest
- Kani
Spec Versioning
Each backend is parsed by a spec that declares which verifier versions it supports, as exact versions and/or inclusive version ranges (a missing bound means the range is unbounded on that side; the default is all versions). When a verifier changes its output format, a new spec is added for the new versions alongside the old one. Within a backend, no two specs may support the same version (a spec conflict). Check this with:
hatch run check-specs # fails on any spec conflict
hatch run check-specs -v # also lists every spec and the versions it supports
Frontend
pf (Pretty Format) is a CLI frontend for formal-lib. It can be invoked from
the CLI to get formatted output from any supported backends. There are two ways
to invoke pf; detailed below.
Using the -- Separator (Recommeded)
The verifier command is specified after the -- separator. Any builtin backend
can be specified. For example:
pf -- esbmc --k-induction --k-step 2 --max-k-step 10 file.c
This makes it easier for some backends that use stderr like ESBMC as you don't
need to redirect stderr to stdout before piping.
Pipe
Pipe verifier output to pf to parse it into structured output:
esbmc --k-induction --k-step 2 --max-k-step 10 file.c 2>&1 | pf
Piping as a method of invocation cannot measure the duration of execution, so that detail will be omitted from the output.
Library Examples
The following section shows some simple examples of the capability of
formal-lib.
Running a Verifier
from pathlib import Path
from formal_lib import VerifierRunner
verifier = VerifierRunner(base_cmd=Path("/usr/bin/esbmc"), default_timeout=120)
result = verifier.verify_source(Path("main.c"))
for issue in result.issues:
print(f"[{issue.severity}] {issue.error_type}: {issue.message}")
Analyzing Verifier Output
from formal_lib import detect_spec, IssueSpecOutputParser
output = open("verifier.log").read()
spec = detect_spec(output)
parser = IssueSpecOutputParser(spec)
result = parser.parse_output(output=output)
# Drop traces from system headers or other files not in your project
project_files = {Path("main.c"), Path("lib/utils.c")}
result = result.filter_traces(project_files)
for issue in result.issues:
print(f"[{issue.severity}] {issue.error_type}: {issue.message}")
Passing ESBMC output to LiteLLM
from pathlib import Path
import litellm
from formal_lib import VerifierRunner
from formal_lib.specs import esbmc_spec
from formal_lib.issue import VerifierIssue
verifier = VerifierRunner(base_cmd=Path("/usr/bin/esbmc"), regex_spec=esbmc_spec)
result = verifier.verify_source(Path("main.c"))
if not result.successful:
issue = result.primary_issue
counterexample = ""
if isinstance(issue, VerifierIssue):
counterexample = f"\nCounterexample:\n{issue.counterexample_formatted}"
source = Path("main.c").read_text()
response = litellm.completion(
model="gpt-4o",
messages=[
{
"role": "user",
"content": (
f"Fix the following {issue.error_type} in {issue.file_path}:{issue.line_number}:\n"
f"{issue.message}\n\n"
f"Stack trace:\n{issue.stack_trace_formatted}"
f"{counterexample}\n\n"
f"Source:\n```c\n{source}\n```"
),
}
],
)
print(response.choices[0].message.content)
Cite
If you use formal-lib in your work, please cite it using the following BibTeX entry:
@misc{charalambous2026formallib,
author = {Charalambous, Yiannis},
title = {formal-lib: A shared interface for software verifier output},
year = {2026},
howpublished = {\url{https://github.com/ByteRepair/formal-lib}},
}
Please cite the version you used; see the Releases page.
License
Copyright © 2026 The University of Manchester. Authored by Yiannis Charalambous.
[!NOTE] This project is offered under a dual-licence model: the open-source GNU AGPL-3.0, or a separate commercial licence for proprietary use.
For a commercial licence, contact UOM Innovation Factory (the commercialisation subsidiary of The University of Manchester) at contact@uominnovationfactory.com.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file formal_lib-1.2.0.tar.gz.
File metadata
- Download URL: formal_lib-1.2.0.tar.gz
- Upload date:
- Size: 107.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6583f6716bf08c1af092e42675bea6004e50ebab58aae431ce1c424fb3b4773c
|
|
| MD5 |
34047e14bf4e14e3a1ad40770f969f42
|
|
| BLAKE2b-256 |
e75ff148877015dce70beb474816c56749b6f6b400b8d6ebe60fff01d231b291
|
Provenance
The following attestation bundles were made for formal_lib-1.2.0.tar.gz:
Publisher:
release.yml on ByteRepair/formal-lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
formal_lib-1.2.0.tar.gz -
Subject digest:
6583f6716bf08c1af092e42675bea6004e50ebab58aae431ce1c424fb3b4773c - Sigstore transparency entry: 2218139736
- Sigstore integration time:
-
Permalink:
ByteRepair/formal-lib@bd8e8d12769e1ceebf81032da8ae4cf129c450bf -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/ByteRepair
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@bd8e8d12769e1ceebf81032da8ae4cf129c450bf -
Trigger Event:
release
-
Statement type:
File details
Details for the file formal_lib-1.2.0-py3-none-any.whl.
File metadata
- Download URL: formal_lib-1.2.0-py3-none-any.whl
- Upload date:
- Size: 46.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85518e8e28a7bc50abb045a7bfc179137344619b86d2f6042844c3b0de8e3b7e
|
|
| MD5 |
5d1df83901685c428b6d55599d929922
|
|
| BLAKE2b-256 |
c9d3c2671b1e47e4c33dbe1f7063d731221e3ce9264005ebf210d36b488f6463
|
Provenance
The following attestation bundles were made for formal_lib-1.2.0-py3-none-any.whl:
Publisher:
release.yml on ByteRepair/formal-lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
formal_lib-1.2.0-py3-none-any.whl -
Subject digest:
85518e8e28a7bc50abb045a7bfc179137344619b86d2f6042844c3b0de8e3b7e - Sigstore transparency entry: 2218139761
- Sigstore integration time:
-
Permalink:
ByteRepair/formal-lib@bd8e8d12769e1ceebf81032da8ae4cf129c450bf -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/ByteRepair
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@bd8e8d12769e1ceebf81032da8ae4cf129c450bf -
Trigger Event:
release
-
Statement type: