Skip to main content

Contains a shared interface of different software verifiers

Project description

formal-lib

A Python library that provides structured representations of software verifier output.

Backends

The following backends are supported:

  • ESBMC
  • CBMC
  • Clang
  • PyTest

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.

Frontend

pf (Pretty Format) is the 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:

  1. Preferred: Using the -- separator and specifying the command
  2. Pipe

Using the -- Separator

The pf can invoke the command by specifying -- and the command:

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

Formatting ESBMC output

from pathlib import Path
from formal_lib import VerifierRunner, VerifierIssue, esbmc_spec

verifier = VerifierRunner(
    base_cmd=Path("/usr/bin/esbmc"),
    regex_spec=esbmc_spec,
    default_timeout=120,
)

result = verifier.verify_source(Path("main.c"), include_paths=[Path("include/")])

if not result.successful:
    for issue in result.issues:
        print(f"[{issue.severity}] {issue.error_type}: {issue.message}")
        print(f"  Location: {issue.file_path}:{issue.line_number}")
        print(issue.stack_trace_formatted)

        if isinstance(issue, VerifierIssue):
            print(issue.counterexample_formatted)

Running a verifier with auto-detection

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 output with auto-detection

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)

for issue in result.issues:
    print(f"[{issue.severity}] {issue.error_type}: {issue.message}")

Filtering traces to specific files

result = verifier.verify_source(Path("main.c"), Path("lib/"))

# 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)

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)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

formal_lib-1.0.0.tar.gz (48.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

formal_lib-1.0.0-py3-none-any.whl (39.3 kB view details)

Uploaded Python 3

File details

Details for the file formal_lib-1.0.0.tar.gz.

File metadata

  • Download URL: formal_lib-1.0.0.tar.gz
  • Upload date:
  • Size: 48.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for formal_lib-1.0.0.tar.gz
Algorithm Hash digest
SHA256 b5e6e5fe8a49b9859259eb8be856283ca20aa5ab51016616fb36dde8288ffdb9
MD5 516ca2d8b8468f4edb7fd31ac966ebe4
BLAKE2b-256 f662411cdda1e837c7998689654d9a594cb91e8ed79b11eca0aacf32f48f3b2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for formal_lib-1.0.0.tar.gz:

Publisher: release.yml on ByteRepair/formal-lib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file formal_lib-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: formal_lib-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 39.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for formal_lib-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a2c683d920077b8e890edbfc5a71b639d77d39e2f7de7b66527e600c808f6cf
MD5 358bf85c8bbcb9427186adc4be85233a
BLAKE2b-256 1b3693c011e691a7bf55aaecbc6168b0b8c95aa95c9831452d1b9ed35e0c9142

See more details on using hashes here.

Provenance

The following attestation bundles were made for formal_lib-1.0.0-py3-none-any.whl:

Publisher: release.yml on ByteRepair/formal-lib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page