πŸ“ Is the Polyhedra Domain Actually Practical? (Benchmarks inside)
Replies: 211
Views: 8,847
Started by: PolyhedralPussycat
Posted: 2026-01-14 02:33 UTC
Last post: 2026-03-26 19:44 UTC
Flair: [benchmark] [polyhedra] [PPL] [chernikova]
PolyhedralPussycat
🐱
β˜… Cat.PhD
OP
Posts: 1,203
Joined: 2020-08-11
Online
Rep: ⭐⭐⭐⭐⭐
Post #1 β€” Thread OP

Okay kittens, I've been meaning to post this for a while. After spending three months running benchmarks on our little analysis workbench I finally have numbers worth sharing. The question: is the Polyhedra domain actually usable in production, or is it forever condemned to "works great on toy programs" land?

Short answer: it depends catastrophically on your variable count. Long answer: read on.

Background

We compared three domains across a suite of 20 numerical benchmark programs (mix of loop-heavy C programs, control-flow-intensive kernels, and some embedded-style code). All tests run with APRON as the backend, using PPL for polyhedra, ELINA for octagons, and custom intervals. Widening enabled on all domains, Cousot-Halbwachs standard widening for polyhedra. Machine: AMD Ryzen 9 7950X, 64GB RAM. Each test has a 4-hour timeout and 16GB memory cap.

Benchmark Suite Overview

# Program LOC #Vars (max scope) Loop depth Category
B01matrix_mult_3x34293Linear Algebra
B02bubble_sort_n102842Sorting
B03pid_controller67121Control
B04fir_filter_8tap55142DSP
B05nested_sum_4d3164Arithmetic
B06jacobi_iter_5x589303Numerical
B07lzw_compress134182Compression
B08crc32_byte4881Crypto/Hash
B09gaussian_elim_6x6101403Linear Algebra
B10trajectory_sim78222Physics Sim

Results β€” Analysis Time

Bench Interval (ms) Octagon (ms) Polyhedra (ms) Polyhedral Invariants Found
B014318207 non-trivial
B0228553 non-trivial
B03619014,30011 non-trivial
B04524038,1009 non-trivial
B053224305 non-trivial
B06113,800TIMEOUTN/A
B07182,100TIMEOUTN/A
B08314702 non-trivial
B0917TIMEOUTOOMN/A
B1081,90092,40014 non-trivial
TIMEOUT = exceeded 4-hour wall clock limit. OOM = exceeded 16GB memory cap. All times are mean of 5 runs.

Precision Comparison (false alarm rate on assert-checking task, lower = better)

Bench Interval false% Octagon false% Polyhedra false%
B0144%17%0%
B0222%8%0%
B0361%29%3%
B0455%22%5%
B0518%5%0%
B0830%11%0%
B1048%20%4%
Only benchmarks that completed for all three domains shown. Polyhedra precision is clearly superior when it terminates.

The precision numbers are incredible when polyhedra actually finishes. But look at B06, B07, B09. The moment variable count exceeds ~18-20 in a relational context, we're toast. This is the fundamental problem with convex polyhedra: the double description requires managing both constraint and generator representations, and conversion between them via Chernikova's algorithm can blow up doubly-exponentially in the number of variables.

My question to the forum: is there any realistic path to making polyhedra practical for programs with 20+ relational variables, or should we accept octagons as our ceiling?

🐾 Full benchmark harness + raw data available at: [benchmark download thread]. PPL version: 1.2, APRON commit 3f8a2c1. OS: Ubuntu 22.04 LTS.
🐱 "A polyhedron in hand is worth two in the timeout log."
GaloisCat
😺
πŸŽ“ Purrfessor
Posts: 4,781
Joined: 2018-03-22
Online
Rep: ⭐⭐⭐⭐⭐
Post #2

Great benchmarks PolyhedralPussycat, bookmarked immediately. But I want to push back on the framing a little before the "polyhedra bad" crowd piles in (looking at you, FixpointFeline πŸ‘€).

The "doubly exponential" story gets thrown around a lot but it's worth being precise. The Chernikova algorithm converts between the H-representation (constraints) and V-representation (generators/rays) of a polyhedron. The worst-case complexity for this conversion is indeed exponential in the number of variables, but:

  V-rep complexity: O(exp(n)) generators in worst case
  H-rep complexity: O(exp(n)) constraints in worst case
  Conversion (Chernikova): O(exp(n)) per step, O(exp(n)) steps
  Effective: doubly exponential in pathological cases

The key word is pathological. For programs with sparse variable interaction graphs β€” i.e., most real code β€” the polyhedra arising during analysis stay decomposable. The ELINA work by Singh, PΓΌschel and Vechev (POPL 2017) showed exactly this: if you exploit variable partitioning, you can get orders of magnitude speedups because most real polyhedra factor into independent subspaces.

Your B09 (gaussian_elim_6x6, 40 vars, dense interactions) is literally the worst case for polyhedra. Of course it OOMs. A dense nΓ—n linear system has maximally interacting variables by construction. That's a benchmark designed to fail polyhedra, not a representative real-world program.

PolyhedralPussycat wrote:
is there any realistic path to making polyhedra practical for programs with 20+ relational variables

Yes: decomposed polyhedra (block-diagonal factorization), template polyhedra (fix constraint templates a priori), or sub-polyhedra domains like Pentagons or LinearRelation. None of these are as precise as full polyhedra, but they're far more scalable and much more precise than octagons for programs with genuine multi-variable invariants.

See also: the ELINA decomposed polyhedra thread and template polyhedra.

😺 The Galois connection is the moral foundation of everything. β€” P. Cousot, probably
FixpointFeline
😾
⚑ Senior Analyst
Posts: 2,344
Joined: 2019-07-05
Offline
Rep: ⭐⭐⭐⭐
Post #3
GaloisCat wrote:
looking at you, FixpointFeline πŸ‘€

I am right here and I have opinions, as always.

GaloisCat's "it's only pathological cases" argument is the same cope I've been hearing at every SAS conference since 2015. Let me be direct: the polyhedra domain is not practical for general-purpose static analysis of real-world code. PolyhedralPussycat's B06 (PID controller, 12 vars) and B07 (LZW, 18 vars) both timed out. These are not corner cases β€” a PID controller is about as idiomatic embedded control code as it gets.

Here's the real problem. It's not just Chernikova's algorithm. The widening story is also broken. The Cousot-Halbwachs widening for convex polyhedra works by retaining only the constraints from the current approximation that were already present (or equivalent to ones that were) in the previous iteration. This guarantees finite convergence, but:

  -- Standard C&H widening on polyhedra:
  P βˆ‡ Q = { c ∈ C(Q) | c ∈ C(P) or C(P) ⊨ c }
  
  Problem: the widening operator can be "too aggressive"
  throwing away constraints that were informative.
  
  Result: the fixpoint we converge to is often far coarser
  than necessary, causing massive false alarm inflation
  AFTER paying the exponential cost to get there.

The precision numbers in PolyhedralPussycat's table look great because they only show the benchmarks that finished. On a real analyzer workload, polyhedra will timeout or OOM on 40-60% of your programs. The "14 non-trivial invariants" on B10 are lovely but meaningless if your CI pipeline is sitting at a wall for 92 seconds per analysis run.

⚠️ Industry reality check: I know of exactly zero production static analyzers shipping polyhedra as the default domain for general code. Astrée uses a bespoke combination of intervals + specific relational domains. Polyspace uses interval arithmetic. Frama-C's Value offers polyhedra but explicitly warns about scalability. The research-practice gap is real.

See my longer rant: The polyhedra research-practice gap (megathread).

😾 Widening: the art of forgetting things in a principled way.
LatticeTabby
🐾
πŸŽ“ Purrfessor
MOD
Posts: 6,102
Joined: 2017-01-30
Online
Rep: ⭐⭐⭐⭐⭐
Post #4

Alright, I'm going to try to play mediator here before this devolves into the usual GaloisCat vs FixpointFeline thunderdome. Both of you have valid points and I think the disagreement is partly definitional.

The domain hierarchy (for those following along at home):

  Intervals βŠ‘ Zones βŠ‘ Octagons βŠ‘ Polyhedra
      ↑           ↑         ↑            ↑
   O(n)         O(nΒ²)     O(nΒ³)      exp(n)
   fastest     fast       sweet spot  slowest
   imprecise   okay       good        most precise

The octagon domain β€” constraints of the form Β±x Β± y ≀ c β€” sits in a genuinely interesting sweet spot. O(nΒ³) closure cost via Floyd-Warshall-style algorithms, far more expressive than intervals, handles the vast majority of loop invariants that actually matter in practice. Mine's 2006 paper on the octagon abstract domain is required reading for anyone in this debate.

FixpointFeline is correct that for general-purpose production analysis, octagons with a good variable-packing heuristic beat full polyhedra almost every time. GaloisCat is also correct that for specific, carefully-scoped analyses (formal verification of safety-critical code, small procedure summaries, etc.), full polyhedra with decomposition can be worth it.

The issue isn't "polyhedra vs. octagons." It's knowing when to deploy which tool. Some considerations:

ScenarioRecommendedWhy
Large codebase, CI pipelineOctagons or IntervalsMust terminate; false alarms handled by triage
Small safety-critical function (<15 vars)PolyhedraPrecision critical; exponential blowup unlikely
Loop with dense multi-var invariantDecomposed PolyhedraELINA-style factoring handles this case well
Array bounds checkingOctagons / PentagonsDifference constraints suffice for most patterns
Relational summaries between functionsPolyhedra (with budget)Summaries are small; cost is amortized

On the widening question that FixpointFeline raised: yes, the Cousot-Halbwachs widening is the standard, but Bagnara et al. published "Precise Widening Operators for Convex Polyhedra" which addresses exactly the coarsening problem. You don't have to use the original widening; the PPL actually ships multiple options. See the widening operators megathread for a comparison.

🐾 Every lattice is complete. Not every analysis is.
AbsintKitty
🐈
πŸ”¬ Analyst
Posts: 892
Joined: 2021-11-03
Offline
Rep: ⭐⭐⭐
Post #5

Can I ask a possibly dumb question? In PolyhedralPussycat's setup: which PPL operations are actually dominating the runtime? Because there are multiple expensive pieces here and I'm not sure which is the bottleneck:

  1. Chernikova conversion (H-rep ↔ V-rep)
  2. Join (convex hull) β€” expensive in H-rep
  3. Meet (intersection) β€” cheap in H-rep, expensive in V-rep
  4. Project (existential quantification / variable elimination)
  5. Widening step itself

The reason I ask is that depending on your program structure, the bottleneck changes. For loop-heavy code, you're hitting join at every iteration + widening. For procedure calls, projection dominates (computing summaries). For conditional-heavy code, meet is frequent.

Did you profile which operation accounts for the most wall time? The PPL has instrumentation hooks for this.

🐈 Always profile before you optimize. β€” my advisor, repeatedly
PolyhedralPussycat
🐱
β˜… Cat.PhD
OP
Posts: 1,203
Joined: 2020-08-11
Online
Rep: ⭐⭐⭐⭐⭐
Post #6
AbsintKitty wrote:
Did you profile which operation accounts for the most wall time?

Great question! Yes, I have the gprof data. Here's the breakdown for the worst performers:

Benchmark Join/Hull % Chernikova Conv. % Widening % Project % Other
B03 (pid, 14.3s)38%41%9%8%4%
B04 (fir, 38.1s)32%52%7%6%3%
B10 (traj, 92.4s)44%39%11%3%3%

So the culprit is: Chernikova conversion + convex hull, together accounting for 70-80% of runtime. This matches the theoretical expectation. Every join requires computing the convex hull of two polyhedra in V-representation, which then needs converting back to H-representation for the next constraint operation. It's the conversion that kills you.

GaloisCat wrote:
if you exploit variable partitioning, you can get orders of magnitude speedups

I tried this! Manually partitioned B03's variables into {error, integral, derivative} vs {setpoint, output, feedback} clusters. Got the runtime down from 14.3s to 2.1s β€” a 6.8Γ— speedup β€” without losing any of the invariants that mattered. The polyhedra just stayed in their respective subspaces and never needed joint Chernikova conversion. So GaloisCat is absolutely right about decomposition.

The problem is: how do you automate this partitioning? You'd need to run a pre-analysis to determine the variable dependency graph, then partition β€” and that pre-analysis itself has a cost. I'll spin up a separate thread about automated variable clustering: Automated variable clustering for polyhedra analysis.

FixpointFeline wrote:
I know of exactly zero production static analyzers shipping polyhedra as the default domain

This is mostly true, but I'd note that AstrΓ©e does use polyhedral-style reasoning in specific subdomains for safety-critical real-time code (embedded flight software etc.). The trick is they don't run it on the whole program β€” they scope it to individual procedures with small variable sets. That seems like the right engineering answer tbh.

🐱 "A polyhedron in hand is worth two in the timeout log."
FixpointFeline
😾
⚑ Senior Analyst
Posts: 2,344
Joined: 2019-07-05
Offline
Rep: ⭐⭐⭐⭐
Post #7

The profiling data confirms what I expected. 80% of time in Chernikova + hull β€” exactly the operations that are exponential in theory and blow up in practice.

I want to put a specific number on what "exponential in n variables" means empirically. Based on my own benchmarking (different programs but similar methodology):

#Variables (relational) Avg. hull time (ms) Avg. Chernikova conv. (ms) Expected #generators
50.30.1~20
104.22.8~120
158955~1,400
202,3001,800~28,000
2531,00024,000~900,000
30OOMOOM>10^7

The number of generators grows roughly as the Catalan number / McMullen's upper bound β€” it's combinatorial explosion. Each doubling of variable count roughly squares the cost. This is not a constant factor you can engineer away.

LatticeTabby wrote:
Bagnara et al. published "Precise Widening Operators for Convex Polyhedra" which addresses exactly the coarsening problem

I've read the Bagnara et al. paper. The more precise widening operators they describe are more expensive than the standard C&H widening, not less. You pay more time for more precision. Great for verification of small, critical loops β€” not helpful when you're already timing out.

Bottom line: polyhedra is a precision tool, not a scalability tool. Use it accordingly. Octagons are the practical workhorse. This isn't a failure of polyhedra β€” it's a scope mismatch.

I'll actually give GaloisCat partial credit on the decomposition point. If your analysis can automatically identify independent variable clusters BEFORE running polyhedra, decomposed polyhedra is genuinely useful. But that automatic partitioning is a research problem in itself. See PolyhedralPussycat's thread.

😾 Widening: the art of forgetting things in a principled way.
GaloisCat
😺
πŸŽ“ Purrfessor
Posts: 4,781
Joined: 2018-03-22
Online
Rep: ⭐⭐⭐⭐⭐
Post #8

Fine, FixpointFeline, you've talked me into a partial concession. The scalability ceiling is real and the numbers in your table above are stark.

But I want to make a different argument for why polyhedra research still matters even if it's not your CI workhorse:

1. Polyhedra as an oracle for weaker domain design. When you design a new, cheaper abstract domain (octagons, pentagons, zones), you validate its precision by comparing against polyhedra on small programs. Polyhedra provides the "ground truth" for what relational information actually exists in a program. Without it, you're flying blind on precision evaluation.

2. Polyhedra for interprocedural summaries. If you compute polyhedral summaries at the function level (functions with small argument count β€” say ≀8 params), the analysis cost is bounded by the number of parameters, not the program size. This is actually practical! You can then use these precise summaries during a whole-program interval or octagon analysis to propagate relational information across call boundaries without paying exponential costs globally.

3. ELINA is genuinely good. The decomposed polyhedra in ELINA (ETH Library for Numerical Analysis) achieves near-octagon speeds on many programs while retaining polyhedral precision for variable clusters that need it. PolyhedralPussycat, did you try ELINA instead of raw PPL for your timing-out benchmarks?

πŸ“Ž Relevant reading: Singh, PΓΌschel, Vechev β€” "Fast Polyhedra Abstract Domain" (POPL 2017). Key insight: "polyhedra arising during analysis can usually be kept decomposed, thus considerably reducing the overall complexity." The key word is usually β€” dense numerical programs like B06/B09 are the exception, not the rule.
😺 The Galois connection is the moral foundation of everything. β€” P. Cousot, probably
MittensMonotone
🐱
🐾 Meow
Posts: 47
Joined: 2025-09-12
Online
Rep: ⭐
Post #9

First post in this thread! Sorry if this is a noob question but I'm a bit lost on one thing. Can someone explain what the Chernikova algorithm is actually doing conceptually? I know it converts between constraint and generator representations but I don't understand why you need both representations in the first place.

Like... can't you just always use constraints (H-representation)?

🐱 Still learning to purr in the language of lattices.
LatticeTabby
🐾
πŸŽ“ Purrfessor
MOD
Posts: 6,102
Joined: 2017-01-30
Online
Rep: ⭐⭐⭐⭐⭐
Post #10
MittensMonotone wrote:
can't you just always use constraints (H-representation)?

Great question! Welcome to the forum 🐱. Short answer: some operations are cheap in one representation and expensive in the other. Here's the breakdown:

Operation H-rep (constraints) V-rep (generators/rays)
Meet (intersection)CHEAP β€” union of constraint setsEXPENSIVE β€” need Chernikova
Join (convex hull)EXPENSIVE β€” need ChernikovaCHEAP β€” union of generator sets
Test P βŠ† QCHEAP β€” LP feasibility checkEXPENSIVE
Assign x := eModerate (add, project var)Moderate
Project (βˆƒx. P)EXPENSIVE β€” Fourier-MotzkinCHEAP β€” drop generators for x

So yes, you can use only H-representation β€” this is what the Verimag Polyhedra Library does. The cost is that convex hull (join) becomes your bottleneck via Fourier-Motzkin elimination, which generates many redundant constraints. The PPL instead maintains both representations lazily and converts between them as needed. The conversion is Chernikova's algorithm.

Think of it like always needing both a recipe (constraints: what rules must hold) and a list of extreme points (generators: what combinations are achievable). Some cooking questions are easier with the recipe, some with the list of ingredients.

For a deeper dive: the Double Description Method wiki article and the Chernikova Algorithm explained thread.

🐾 Every lattice is complete. Not every analysis is.
PolyhedralPussycat
🐱
β˜… Cat.PhD
OP
Posts: 1,203
Joined: 2020-08-11
Online
Rep: ⭐⭐⭐⭐⭐
Post #11
GaloisCat wrote:
PolyhedralPussycat, did you try ELINA instead of raw PPL for your timing-out benchmarks?

Yes, I ran ELINA overnight! Updated results for the tricky benchmarks:

Bench PPL (original) ELINA Decomposed Precision loss vs. PPL
B03 (pid)14,300ms1,840ms0 invariants lost
B04 (fir)38,100ms5,200ms1 invariant coarsened
B06 (jacobi)TIMEOUT44,000msStill slow but terminates!
B07 (lzw)TIMEOUT21,000msTerminates! 3 invariants vs. PPL unknown
B09 (gaussian)OOMTIMEOUT (still)40 fully-coupled vars = no decomposition possible

So ELINA decomposed polyhedra is a genuine win for most programs. B09 is the true pathological case β€” a dense 6Γ—6 Gaussian elimination involves all 40 variables in a fully coupled invariant, so there's nothing to decompose. For this particular program, I don't think any polyhedral analysis is going to work short of dramatic mathematical breakthroughs.

Tentative conclusions (subject to revision as the thread continues):

  1. Raw PPL polyhedra: practical for ≀15 relational variables, impractical beyond that.
  2. ELINA decomposed polyhedra: practical for ≀25 relational variables IF the dependency graph is sparse.
  3. Octagons: practical for arbitrary-size programs; best precision-performance tradeoff for general analysis.
  4. Dense fully-coupled programs (Gaussian elimination style): currently nothing beats intervals for scalability, though you pay a precision price.

Thanks everyone for the great discussion. This thread has been way more informative than I expected. Will update with more benchmarks as I run them. 🐾

🐱 "A polyhedron in hand is worth two in the timeout log."
200 more replies in this thread.   Continue to page 2 β†’  |  Jump to last page β†’

πŸ’¬ Quick Reply

 You are posting as VisitorKitten
πŸ”— Related Threads
πŸ“ ELINA Decomposed Polyhedra: Setup Guide & Gotchas ⬑ Octagon Domain Deep Dive β€” Mine's 2006 Paper Discussion β†‘βˆ‡ Widening Operators: Standard vs. Precise vs. Lookahead πŸ”§ APRON Library Review β€” Which Backend for Which Task? πŸ”„ Chernikova's Algorithm Explained (with Diagrams) 🏭 The Polyhedra Research-Practice Gap (Megathread) πŸ”— Automated Variable Clustering for Polyhedra Analysis πŸ“‹ Template Polyhedra: Fixing Constraint Shapes A Priori πŸ“š Abstract Interpretation Reading List (2026 Edition) πŸ“ Why Intervals Aren't Enough β€” A Practical Guide