2026-04-05ยท10 min readยทsota.io team

Deploy 2LS to Europe โ€” Daniel Kroening ๐Ÿ‡ฉ๐Ÿ‡ช (University of Oxford), the Two-Level Lattice Solver for Automated Invariant Synthesis, on EU Infrastructure in 2026

Among the persistent challenges in software verification, one stands out as particularly demanding: the automatic synthesis of loop invariants. For most verifiers, loop invariants must be supplied manually โ€” the engineer writes the annotation, the tool checks it. For programs with complex arithmetic over arrays, pointers, and control-flow interactions, finding those invariants by hand is often as hard as the original verification problem.

2LS โ€” the Two-Level Lattice Solver โ€” was designed specifically to address this. Developed by Saurabh Joshi and Daniel Kroening at the University of Oxford and presented at CAV 2014 in Vienna, 2LS combines abstract interpretation over template domains with bounded model checking in a two-level lattice structure: the outer level over-approximates reachable program states (providing safety), while the inner level under-approximates infeasible traces (providing refutation). The combination synthesizes loop invariants automatically โ€” no manual annotation required for the core safety argument.

2LS is the lesser-known sibling of CBMC, also from Kroening's group at Oxford. Where CBMC encodes programs as propositional formulas and uses SAT/SMT to find concrete counterexamples, 2LS works at the abstraction level โ€” inferring invariants rather than finding bugs. The two tools are complementary: CBMC for bounded bug-finding, 2LS for invariant synthesis and unbounded safety.

Daniel Kroening and Saurabh Joshi at Oxford

Daniel Kroening ๐Ÿ‡ฉ๐Ÿ‡ช is a Full Professor of Computer Science at the University of Oxford ๐Ÿ‡ฌ๐Ÿ‡ง and one of the most productive software verification researchers in Europe. Born and educated in Germany, Kroening has spent his career building tools that bridge the gap between theoretical verification methods and industrial C/C++ codebases. His 2004 tool CBMC (C Bounded Model Checker, with Edmund Clarke at CMU) became the most widely deployed academic formal verification tool for C โ€” used in production at Amazon AWS, Toyota, NASA JPL, and Airbus.

After CBMC, Kroening's group at Oxford's Department of Computer Science continued developing complementary verification tools: 2LS for invariant synthesis, ESBMC (with the University of Manchester ๐Ÿ‡ฌ๐Ÿ‡ง), and tools for hardware-software co-verification. The Oxford Computer Science department, founded in the 1950s as part of the UK's earliest computing research programmes, has been a central node in the EU formal verification network since the 1970s.

Saurabh Joshi ๐Ÿ‡ฎ๐Ÿ‡ณ was a DPhil (PhD) student at Oxford under Kroening when 2LS was developed. The CAV 2014 paper โ€” 2LS: A Verification Tool Based on 2-Variable Logic โ€” presented at Computer-Aided Verification 2014 in Vienna, Austria ๐Ÿ‡ฆ๐Ÿ‡น, introduced the two-level lattice framework and its application to loop invariant synthesis for C programs.

The Oxford formal methods group at the time included Kroening, Peter Schrammel ๐Ÿ‡ฉ๐Ÿ‡ช (Diffblue, now at University of Sussex ๐Ÿ‡ฌ๐Ÿ‡ง), and Michael Tautschnig ๐Ÿ‡ฉ๐Ÿ‡ช (Amazon Web Services) โ€” a German-dominated team at a British institution, characteristic of the cross-European nature of UK academic computer science before Brexit.

The Two-Level Lattice Framework

The name "2LS" stands for Two-Level Lattice Solver. The mathematical structure is elegant: rather than working in a single abstract domain, 2LS operates in a product domain where two complementary lattices interact.

Level 1: Template Polyhedra (Over-Approximation)

The outer lattice in 2LS is the template polyhedra domain โ€” a parametric abstract domain originally introduced by Sankaranarayanan, Sipma, and Manna (Stanford, 2005) and refined in 2LS for automatic template selection. A template polyhedron is a set of linear constraints of the form:

c1x1 + c2x2 + ... + cnxn โ‰ค d

where the template directions (c1, ..., cn) are fixed in advance and only the bounds d are inferred. This generalises standard abstract domains:

The key insight: instead of computing the abstract transformer for each template direction independently, 2LS solves for the optimal bounds d โ€” the tightest values that make the template a valid over-approximation of the reachable set. This turns invariant synthesis into a constraint optimisation problem over linear arithmetic.

Level 2: Bounded Model Checking (Under-Approximation)

The inner lattice provides the counterexample backbone. 2LS uses CBMC as its BMC engine: for a given loop unrolling bound k, CBMC encodes the program as a formula and either:

The UNSAT result feeds back to Level 1: the template bound inference is constrained to exclude the infeasible bounded traces found by CBMC. This produces tighter invariants than abstract interpretation alone.

k-Induction

The two levels interact via k-induction, the verification strategy that:

  1. Base case: prove the property holds for all executions of length โ‰ค k (via BMC)
  2. Inductive step: assume the property holds for k consecutive steps, prove it holds for step k+1 (via invariant strengthening)

In 2LS, the inductive step is discharged by the template polyhedra solver: find bounds that make the template invariant inductive โ€” i.e., that a state satisfying the invariant after one loop iteration still satisfies the invariant. If the template invariant is inductive and the base case holds, the property holds for all loop iterations, not just the first k.

The power of 2LS: k-induction succeeds where BMC alone cannot โ€” it proves properties for all loop executions, not just executions up to a fixed unrolling depth. And the template polyhedra solver makes invariant synthesis automatic โ€” the user provides the property, not the invariant.

# 2LS basic usage: verify a C program with k-induction
./2ls --k-induction program.c

# Specify loop unrolling bound
./2ls --k-induction --unwind 10 program.c

# Template domain selection
./2ls --k-induction --intervals program.c    # interval domain
./2ls --k-induction --octagons program.c     # octagon domain
./2ls --k-induction --template program.c     # template polyhedra (default)

# Termination analysis
./2ls --termination program.c

# Memory safety
./2ls --memory-safety program.c

The 2-Variable Logic Connection

The "2-variable" in 2LS's original CAV 2014 presentation refers to the logic underlying the template instantiation: the constraint synthesis problem for template polyhedra reduces to satisfiability in two-variable logic over ordered structures (a fragment of first-order logic decidable in polynomial space). This provides a theoretical foundation for the termination and soundness of the template bound computation.

In practice, the SMT solver Z3 (Microsoft Research, widely used in EU verification tools) discharges the constraint synthesis queries. Z3's linear arithmetic solver handles the polyhedra bound computation efficiently for the variable counts typical in embedded C code.

SV-COMP and Verification Performance

2LS has participated in SV-COMP (Software Verification Competition, held at ETAPS/TACAS) in the ReachSafety and MemSafety categories. Its performance profile reflects its design: 2LS is particularly strong on programs with numeric-heavy loop bodies where template polyhedra can capture the exact invariant, and where k-induction closes the proof that BMC leaves open.

The SV-COMP context highlights where 2LS sits in the EU verification ecosystem:

ToolInstitutionApproachStrength
CPAcheckerLMU Munich ๐Ÿ‡ฉ๐Ÿ‡ชPredicate abstraction + CEGARBroad, SV-COMP champion
UltimateAutomizerFreiburg ๐Ÿ‡ฉ๐Ÿ‡ชTrace abstraction + BรผchiSV-COMP top tier
CBMCOxford ๐Ÿ‡ฌ๐Ÿ‡งBounded model checkingBug-finding, CI/CD
2LSOxford ๐Ÿ‡ฌ๐Ÿ‡งTemplate polyhedra + k-inductionInvariant synthesis
nuXmvFBK Trento ๐Ÿ‡ฎ๐Ÿ‡นIC3/PDR + BDDHardware-style safety

2LS occupies a complementary niche: where CBMC finds concrete bugs and CPAchecker/UltimateAutomizer prove safety via predicate/trace abstraction, 2LS synthesises the numeric invariants that make those proofs possible. For programs with polynomial-bounded loop variables โ€” typical in signal processing, control theory, and automotive embedded code โ€” 2LS's template approach often produces tighter invariants with less manual effort.

How to Run 2LS

2LS is built on the CPROVER infrastructure (also used by CBMC) and requires a similar setup:

# Clone and build from source
git clone https://github.com/diffblue/2ls.git
cd 2ls
git submodule update --init
cmake -S . -Bbuild -DCMAKE_BUILD_TYPE=Release
cmake --build build -- -j$(nproc)

# Basic safety verification with k-induction
./build/src/2ls/2ls --k-induction program.c

# Memory safety check
./build/src/2ls/2ls --memory-safety --k-induction program.c

# Termination
./build/src/2ls/2ls --termination program.c

# Template polyhedra with explicit domain
./build/src/2ls/2ls --k-induction --template-polyhedra program.c

# Nested loops: increase unrolling depth
./build/src/2ls/2ls --k-induction --unwind 20 nested_loop.c

A minimal C program demonstrating 2LS invariant synthesis:

/* loop_bounds.c โ€” 2LS synthesizes the loop invariant 0 <= i <= n automatically */
#include <assert.h>

int main() {
  int n;
  __CPROVER_assume(n >= 0 && n <= 100);
  
  int i = 0;
  int sum = 0;
  
  while (i < n) {
    sum += i;
    i++;
  }
  
  /* 2LS synthesizes: 0 <= i <= n and sum == i*(i-1)/2 */
  assert(i == n);
  assert(sum >= 0);
  return 0;
}
# 2LS automatically finds the loop invariant and proves both assertions
./build/src/2ls/2ls --k-induction loop_bounds.c
# VERIFICATION SUCCESSFUL

Docker Deployment for CI/CD

A production Dockerfile for a 2LS verification service:

FROM debian:bookworm-slim AS builder

RUN apt-get update && apt-get install -y \
    git cmake ninja-build \
    g++ flex bison \
    libz-dev libgmp-dev \
    && apt-get clean

# Build 2LS from source
RUN git clone --depth=1 https://github.com/diffblue/2ls.git /opt/2ls-src \
    && cd /opt/2ls-src \
    && git submodule update --init --depth=1 \
    && cmake -S . -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release \
    && cmake --build build

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y libgmp10 && apt-get clean

COPY --from=builder /opt/2ls-src/build/src/2ls/2ls /usr/local/bin/2ls

WORKDIR /workspace
COPY verify.sh /usr/local/bin/verify
RUN chmod +x /usr/local/bin/verify

CMD ["verify"]
#!/bin/bash
# verify.sh โ€” run 2LS + store results in sota.io PostgreSQL

for src in /workspace/src/*.c; do
  name=$(basename "$src" .c)
  
  result=$(2ls \
    --k-induction \
    --memory-safety \
    --unwind 20 \
    "$src" 2>&1)
  
  if echo "$result" | grep -q "VERIFICATION SUCCESSFUL"; then
    verdict="SAFE"
  elif echo "$result" | grep -q "VERIFICATION FAILED"; then
    verdict="UNSAFE"
  else
    verdict="UNKNOWN"
  fi
  
  # Store in EU PostgreSQL on sota.io
  psql "$DATABASE_URL" -c "
    INSERT INTO verification_results (program, tool, verdict, timestamp, raw_output)
    VALUES ('${name}', '2ls-k-induction', '${verdict}', NOW(), \$\$${result}\$\$)
    ON CONFLICT (program, tool) DO UPDATE SET
      verdict = EXCLUDED.verdict,
      timestamp = EXCLUDED.timestamp,
      raw_output = EXCLUDED.raw_output;"
  
  echo "=== ${name}: ${verdict} ==="
done
# Deploy to sota.io
docker build -t 2ls-verification-service .
docker push registry.sota.io/your-project/2ls-verification-service

curl -X POST https://api.sota.io/v1/projects/YOUR_PROJECT_ID/deploy \
  -H "Authorization: Bearer $SOTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"image": "registry.sota.io/your-project/2ls-verification-service"}'

Verification results โ€” synthesised invariants, SAFE certificates, counterexamples โ€” stored in EU PostgreSQL on German infrastructure, under EU jurisdiction, fully GDPR-compliant.

Industrial Relevance: EU Safety-Critical Systems

Automotive: ISO 26262 ASIL D

2LS's template polyhedra domain is particularly well-suited for automotive control software: PID controllers, braking algorithms, powertrain state machines all have numeric loop bodies with bounded arithmetic. The interval and octagon domains capture these precisely.

For automotive teams at Bosch ๐Ÿ‡ฉ๐Ÿ‡ช, Continental ๐Ÿ‡ฉ๐Ÿ‡ช, Infineon ๐Ÿ‡ฉ๐Ÿ‡ช, and STMicroelectronics ๐Ÿ‡ฎ๐Ÿ‡น working under ISO 26262 ASIL D, 2LS provides:

The connection to CBMC is industrially significant: many teams that use CBMC for bug-finding in CI/CD can add 2LS for the invariant synthesis step, using the same CPROVER infrastructure and harness patterns. One toolchain, two complementary verification modes.

IEC 61508 SIL 3/4

For German process industry manufacturers โ€” Endress+Hauser ๐Ÿ‡ฉ๐Ÿ‡ช, Pepperl+Fuchs ๐Ÿ‡ฉ๐Ÿ‡ช, Wago ๐Ÿ‡ฉ๐Ÿ‡ช โ€” IEC 61508 SIL 3/4 certification requires formal verification evidence for C safety functions in field devices and safety controllers.

2LS's k-induction approach satisfies IEC 61508 Part 3's "formal proof" technique (T3.7) when:

The CPROVER infrastructure (shared with CBMC) provides mature tool qualification documentation via Diffblue's (Oxford spinout) toolchain certification support.

EN 50128 SIL 4: Railway Signalling

For ETCS onboard units and interlocking controllers developed by Siemens Mobility ๐Ÿ‡ฉ๐Ÿ‡ช and Thales Rail ๐Ÿ‡ซ๐Ÿ‡ท, 2LS's termination analysis complements CBMC's safety analysis. EN 50128 SIL 4 requires evidence that:

  1. Safety functions are reachable (reachability โ€” CBMC)
  2. Safety functions terminate (termination โ€” 2LS --termination)
  3. Loop variables stay within safe bounds (invariant โ€” 2LS --k-induction)

The three modes together provide a formal evidence package across the safety hierarchy: bounded reachability, unbounded termination, and numeric range proofs.

EU Regulatory Context

EU Cyber Resilience Act (CRA) 2027

The CRA requires manufacturers of products with digital elements to demonstrate "state of the art" security measures. For embedded C products, 2LS provides:

These certificates, produced by a reproducible pipeline (2LS version + property spec + harness), qualify as formal verification evidence in a CRA technical documentation package.

EU AI Act Article 9: Risk Management Systems

For high-risk AI systems with C inference engines โ€” ADAS (Annex III ยง3), medical devices (Annex III ยง5), industrial control (Annex III ยง6) โ€” 2LS provides:

The synthesised invariants are human-readable (linear constraints), which simplifies the EU AI Act conformity assessment review: auditors can inspect the invariants without understanding the full verification algorithm.

GDPR Article 25: Privacy by Design

2LS's data-flow analysis modes can verify that personal data processing loops remain within their specified scope: a template invariant processed_count โ‰ค dataset_size proves that a loop cannot silently extend beyond the consented data range โ€” a direct GDPR Art. 25 "data minimisation by design" argument.

The Oxford-Diffblue Formal Verification Ecosystem

Daniel Kroening's Oxford group spawned the company Diffblue ๐Ÿ‡ฌ๐Ÿ‡ง (Oxford spinout, founded 2016), which commercialises CPROVER-based technology for:

The Oxford formal verification cluster built around Kroening's group:

This cluster represents one of the densest formal verification research outputs from a single institution in Europe. The common CPROVER infrastructure means advances in one tool directly benefit the others โ€” a genuine research ecosystem, not isolated tools.

Deploying 2LS on sota.io

2LS runs on any Linux server with a standard C/C++ toolchain. For a continuous invariant-synthesis service that stores results in PostgreSQL:

FROM debian:bookworm-slim AS builder

RUN apt-get update && apt-get install -y \
    git cmake g++ flex bison libz-dev libgmp-dev ninja-build \
    && apt-get clean

RUN git clone --depth=1 https://github.com/diffblue/2ls.git /2ls \
    && cd /2ls \
    && git submodule update --init --depth=1 \
    && cmake -S . -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release \
    && cmake --build build

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y libgmp10 postgresql-client && apt-get clean
COPY --from=builder /2ls/build/src/2ls/2ls /usr/local/bin/2ls

COPY run_verification.sh /usr/local/bin/run_verification
RUN chmod +x /usr/local/bin/run_verification

CMD ["run_verification"]
#!/bin/bash
# run_verification.sh โ€” 2LS invariant synthesis + sota.io PostgreSQL storage

for src in /workspace/src/*.c; do
  name=$(basename "$src" .c)
  
  # Run 2LS with template polyhedra + k-induction
  result=$(2ls \
    --k-induction \
    --template-polyhedra \
    --memory-safety \
    --unwind 20 \
    "$src" 2>&1)
  
  verdict=$(echo "$result" | grep -oP 'VERIFICATION (SUCCESSFUL|FAILED)' | head -1 | awk '{print $2}')
  
  # Extract synthesised invariants (2LS outputs them in the result)
  invariants=$(echo "$result" | grep -A5 'Invariant' | head -20)
  
  # Store in EU PostgreSQL on sota.io โ€” no US jurisdiction
  psql "$DATABASE_URL" -c "
    INSERT INTO formal_verification (
      component, verifier, verdict, invariants, timestamp
    ) VALUES (
      '${name}', '2ls-template-polyhedra', '${verdict}',
      \$inv\$${invariants}\$inv\$, NOW()
    ) ON CONFLICT (component, verifier) DO UPDATE SET
      verdict = EXCLUDED.verdict,
      invariants = EXCLUDED.invariants,
      timestamp = EXCLUDED.timestamp;"
  
  echo "=== ${name}: ${verdict} ==="
done

Verification results and synthesised invariants stored in EU-jurisdiction PostgreSQL โ€” directly useful for ISO 26262, IEC 61508, and CRA technical documentation packages.


2LS is open source (BSD licence). Source code at github.com/diffblue/2ls. sota.io has a free tier โ€” deploy your first 2LS invariant-synthesis service in minutes and generate formal evidence that satisfies EU regulatory requirements for safety-critical C code.


See Also


sota.io is built in Europe, for Europe. Every workload you deploy on sota.io stays under EU jurisdiction โ€” GDPR-compliant, Cloud Act-free, and operated by an EU entity. Deploy 2LS now โ†’