Generates abstract invariants using domain abstraction — intervals, octagons, polyhedra, sign domains — to find invariants that concrete reasoning misses. Use when standard invariant inference fails, when the invariant involves relationships between multiple variables, or when verifying numerical code.
Install with Tessl CLI
npx tessl i github:santosomar/general-secure-coding-agent-skills --skill abstract-invariant-generator94
Quality
92%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
When → invariant-inference (which works from concrete traces) can't find the invariant, abstract interpretation can. It over-approximates: instead of tracking exact values, track which region of a chosen domain the values are in.
| Domain | Can express | Example invariant | Cost |
|---|---|---|---|
| Sign | x > 0, x = 0, x < 0 | n > 0 | Trivial |
| Interval | lo ≤ x ≤ hi | 0 ≤ i ≤ n | Cheap |
| Octagon | ±x ± y ≤ c (two-var bounds) | i ≤ j, j - i ≤ n | Moderate |
| Polyhedra | Arbitrary linear inequalities | 2i + 3j ≤ n + 5 | Expensive |
| Congruence | x ≡ k (mod m) | i is even | Cheap |
Start cheap. Intervals catch 80% of array-bounds invariants. Octagons catch most two-pointer patterns. Polyhedra are for when you actually need a weird linear relationship.
i = 0 → in intervals: i ∈ [0, 0].i := i + 1 on [a, b] → [a+1, b+1].[0,0] ⊔ [1,1] = [0,1].[0,1] ⊔ [0,2] ⊔ [0,3] ⊔ ... → widen to [0, +∞). Then narrow: apply the loop guard i < n to get [0, n-1].Code:
int i = 0, j = n;
while (i < j) {
i++;
j--;
}
// invariant at loop head? need: 0 ≤ i, j ≤ n, and relationship between i and jInterval abstraction:
| Iteration | i | j |
|---|---|---|
| Init | [0, 0] | [n, n] |
| After 1 | [1, 1] | [n-1, n-1] |
| Join | [0, 1] | [n-1, n] |
| After 2 | [1, 2] | [n-2, n-1] |
| Join | [0, 2] | [n-2, n] |
| …widen | [0, +∞) | (-∞, n] |
Narrow (guard i < j) | [0, n] | [0, n] |
Interval invariant: 0 ≤ i ≤ n ∧ 0 ≤ j ≤ n. True but weak — doesn't capture i + j = n.
Octagon domain (tracks ±x ± y ≤ c):
Initial: i + j = n (since i=0, j=n). Transition: i' = i+1, j' = j-1 → i' + j' = i + j = n. Preserved. Octagon finds i + j = n (as i+j ≤ n ∧ -(i+j) ≤ -n).
Lesson: Intervals are per-variable; they can't see i + j = n. For relational invariants, you need a relational domain.
i ≤ j) → octagons.[-∞, +∞]), the domain can't express the invariant — upgrade.[0, +∞) — useless. The guard narrows it back.i*i ≤ n — none of these domains can express it. You need a polynomial domain or template-based search.## Domain
<interval | octagon | polyhedra | congruence> — <why this domain>
## Fixpoint iteration
<table: iteration → abstract state>
## Invariant
<the stabilized abstract state, written as a logical formula>
## Strength check
Sufficient for the postcondition? <yes | no — need stronger domain: which>47d56bb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.