Agent skill

Invariant Inference

by ArabelaTso in ArabelaTso/Skills-4-SE

Automatically infer loop invariants for code verification and correctness proofs.

Apache-2.0Auto-check passed

Install Invariant Inference

skills CLI
$ npx skills add ArabelaTso/Skills-4-SE --skill invariant-inference -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ArabelaTso/Skills-4-SE invariant-inference --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ArabelaTso/Skills-4-SE.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/invariant-inference .claude/skills/invariant-inference && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
invariant-inference
GitHub stars
253
Token cost
~3.1k tokens
SKILL.md length
466 words
Files
2 (incl. references)
Skills in repo
170
Repo updated
First seen
Licence
Apache-2.0

At a glance

Automatically infer loop invariants for code verification and correctness proofs.

  • Works in 6 steps: Identify the Loop → Analyze Loop Structure → Infer Invariant Categories → …
  • Analyzing loops to identify properties that hold throughout execution
  • SKILL.md covers Overview, Workflow, Example Workflows and Tips for Effective Invariant…, plus 1 more section
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Invariant Inference is an agent skill from ArabelaTso/Skills-4-SE. Automatically infer loop invariants for code verification and correctness proofs. Use when analyzing loops to identify properties that hold throughout execution, generating assertions for verification, proving loop correctness, or documenting loop behavior. Supports Python, Java, C/C++, and language-agnostic analysis. Generates invariants as code assertions (assert statements). Triggers when users ask to infer invariants, find loop properties, generate loop assertions, prove loop correctness, or verify loop…

Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/invariant-patterns.md`).

It works with C++, Java and Python. The repository describes itself as: A curated list of 180+ useful Claude Skills for Software Engineering and resources for customizing AI for SE workflows. The licence is Apache-2.0.

When your agent uses it

  • Analyzing loops to identify properties that hold throughout execution
  • Generating assertions for verification
  • Proving loop correctness
  • Documenting loop behavior

Example prompts

  • “/invariant-inference”

Requirements

  • Python 3

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Identify the Loop
  2. Analyze Loop Structure
  3. Infer Invariant Categories
  4. Generate Assertions
  5. Verify Invariants
  6. Handle Complex Cases

What it can do on your machine

Read from SKILL.md and the folder at commit 4f38503. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python, java and c).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Invariant Inference loads about 3.1k tokens when it runs, and up to ~4.6k if it reads all its reference files. Until then it costs about 136 tokens; SKILL.md has 466 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~136
When it runs · the whole SKILL.md, loaded when a task matches
~3.1k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from ArabelaTso/Skills-4-SE at commit 4f38503, republished under its Apache-2.0 licence (© ArabelaTso). 466 words, ~3,096 tokens.

Download SKILL.mdSave it as .claude/skills/invariant-inference/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
invariant-inference
description
Automatically infer loop invariants for code verification and correctness proofs. Use when analyzing loops to identify properties that hold throughout execution, generating assertions for verification, proving loop correctness, or documenting loop behavior. Supports Python, Java, C/C++, and language-agnostic analysis. Generates invariants as code assertions (assert statements). Triggers when users ask to infer invariants, find loop properties, generate loop assertions, prove loop correctness, or verify loop behavior.

Invariant Inference

Overview

Analyze loops and automatically infer invariants—properties that remain true throughout loop execution. Generate these as code assertions for verification and correctness proofs.

Workflow

1. Identify the Loop

First, locate and understand the loop to analyze:

Loop types to recognize:

  • for loops with index variables
  • while loops with conditions
  • do-while loops
  • Iterator-based loops
  • Recursive functions (treated as implicit loops)

Extract key information:

  • Loop variable(s) and their initial values
  • Loop condition (when it terminates)
  • Loop body (what happens each iteration)
  • Variables modified in the loop
  • Variables read but not modified
2. Analyze Loop Structure

Understand what the loop does:

Categorize the loop:

  • Accumulation: Building up a sum, product, or collection
  • Search: Looking for an element or condition
  • Transformation: Modifying elements in a data structure
  • Generation: Creating new data based on input
  • Traversal: Visiting all elements
  • Sorting/Partitioning: Rearranging elements

Identify patterns:

  • Array/list iteration with bounds
  • Counter increments/decrements
  • Pointer advancement
  • Collection building
  • Flag-based early termination
3. Infer Invariant Categories

Generate invariants for each applicable category. See invariant-patterns.md for comprehensive patterns.

Bounds Invariants

Properties about variable ranges:

python
# Loop: for i in range(n)
assert 0 <= i < n

# Loop: while i < len(arr)
assert 0 <= i <= len(arr)

# Loop: two pointers
while left < right:
    assert 0 <= left <= right < len(arr)
Relationship Invariants

Properties relating variables:

Sum/Accumulation:

python
total = 0
for i in range(len(arr)):
    assert total == sum(arr[0:i])  # Invariant before update
    total += arr[i]
assert total == sum(arr)  # Post-condition

Max/Min:

python
max_val = arr[0]
for i in range(1, len(arr)):
    assert max_val == max(arr[0:i])
    if arr[i] > max_val:
        max_val = arr[i]

Product:

python
product = 1
for i in range(len(arr)):
    assert product == arr[0] * arr[1] * ... * arr[i-1]
    product *= arr[i]
Progress Invariants

Properties showing termination:

python
# Decreasing to zero
while n > 0:
    assert n > 0  # Still positive
    n -= 1
    assert n >= 0  # Non-negative after decrement

# Increasing to limit
i = 0
while i < n:
    assert i < n  # Not yet at limit
    i += 1
    assert i <= n  # At most n
Data Structure Invariants

Properties about structure integrity:

Sorted sublists:

python
# Insertion sort
for i in range(1, len(arr)):
    assert is_sorted(arr[0:i])  # Prefix is sorted
    # ... insert arr[i] into sorted position

Partition property:

python
# Partitioning around pivot
while left < right:
    assert all(arr[j] <= pivot for j in range(0, left))
    assert all(arr[j] >= pivot for j in range(right, len(arr)))
    # ... move pointers

Size invariants:

python
result = []
for i in range(len(items)):
    assert len(result) == i  # Processed i items so far
    if condition(items[i]):
        result.append(items[i])
4. Generate Assertions

Convert inferred invariants into code assertions:

Python Format
python
def find_maximum(arr):
    """Find maximum element in array."""
    assert len(arr) > 0, "Array must not be empty"  # Pre-condition

    max_val = arr[0]

    for i in range(1, len(arr)):
        # Loop invariants
        assert 0 < i < len(arr), "Index in valid range"
        assert max_val == max(arr[0:i]), "max_val is maximum so far"
        assert max_val in arr[0:i], "max_val is from processed elements"

        if arr[i] > max_val:
            max_val = arr[i]

    assert max_val == max(arr), "max_val is maximum of entire array"  # Post-condition
    return max_val
Java Format
java
public int findMaximum(int[] arr) {
    assert arr.length > 0 : "Array must not be empty";

    int maxVal = arr[0];

    for (int i = 1; i < arr.length; i++) {
        assert i > 0 && i < arr.length : "Index in valid range";
        assert maxVal == max(arr, 0, i) : "maxVal is maximum so far";

        if (arr[i] > maxVal) {
            maxVal = arr[i];
        }
    }

    assert maxVal == max(arr, 0, arr.length) : "maxVal is maximum";
    return maxVal;
}
C/C++ Format
c
int find_maximum(int arr[], int n) {
    assert(n > 0);  // Pre-condition

    int max_val = arr[0];

    for (int i = 1; i < n; i++) {
        assert(i >= 1 && i < n);  // Bounds
        assert(max_val >= arr[0]);  // max_val is at least first element
        // Note: Can't easily express "max of subarray" in C without helper

        if (arr[i] > max_val) {
            max_val = arr[i];
        }
    }

    return max_val;
}
5. Verify Invariants

Check that inferred invariants are correct:

Initialization

Invariant must be true before the loop starts:

python
# Loop: total = 0; for i in range(n): total += arr[i]
# Invariant: total == sum(arr[0:i])
# Check: Before loop, i=0, total=0, sum(arr[0:0])=0 ✓
Maintenance

Invariant remains true after each iteration:

python
# Assume invariant true at start of iteration i
# Show it's true at start of iteration i+1
# Before: total == sum(arr[0:i])
# Execute: total += arr[i]
# After: total == sum(arr[0:i]) + arr[i] == sum(arr[0:i+1]) ✓
Termination

Invariant + termination condition proves post-condition:

python
# After loop: i == n (termination) and total == sum(arr[0:i]) (invariant)
# Therefore: total == sum(arr[0:n]) == sum(arr) ✓
6. Handle Complex Cases
Nested Loops

Generate invariants for each nesting level:

python
# Matrix sum
total = 0
for i in range(rows):
    assert total == sum(matrix[0:i, :])  # Outer invariant

    for j in range(cols):
        assert total == sum(matrix[0:i, :]) + sum(matrix[i, 0:j])  # Inner
        total += matrix[i][j]
Multiple Variables

Track relationships between variables:

python
# Two pointers
left, right = 0, len(arr) - 1
while left < right:
    assert 0 <= left <= right < len(arr)
    assert left + right == len(arr) - 1  # Relationship invariant
    # (only true if they move symmetrically)
    left += 1
    right -= 1
Early Exit

Handle break/return statements:

python
# Search with early exit
found = False
for i in range(len(arr)):
    assert not found or arr[i-1] == target  # If found, previous element was it

    if arr[i] == target:
        found = True
        break

assert not found or target in arr[0:i+1]  # Post-condition
Loop with Side Effects

Track effects on external state:

python
# Modifying a list
for i in range(len(arr)):
    assert len(arr) remains constant  # Size doesn't change
    assert arr[0:i] are processed correctly
    arr[i] = transform(arr[i])
Show full SKILL.md (187 more words)Show less

Example Workflows

Example 1: Simple Accumulation

User request:

"Infer invariants for this sum loop"

python
def array_sum(arr):
    total = 0
    for i in range(len(arr)):
        total += arr[i]
    return total

Response:

python
def array_sum(arr):
    assert len(arr) >= 0  # Pre-condition: valid array

    total = 0
    for i in range(len(arr)):
        # Loop invariants
        assert 0 <= i < len(arr), "Index in valid range"
        assert total == sum(arr[0:i]), "total is sum of elements so far"

        total += arr[i]

    assert total == sum(arr), "total is sum of entire array"  # Post-condition
    return total

Explanation:

  • Bounds: 0 <= i < len(arr)
  • Relationship: total == sum(arr[0:i])
  • Progress: i increases each iteration
  • Post-condition follows from invariant + termination
Example 2: Search Loop

User request:

"What are the invariants for binary search?"

python
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

Response:

python
def binary_search(arr, target):
    assert is_sorted(arr), "Array must be sorted"  # Pre-condition

    left, right = 0, len(arr) - 1

    while left <= right:
        # Loop invariants
        assert 0 <= left <= len(arr), "left in valid range"
        assert -1 <= right < len(arr), "right in valid range"
        assert left <= right + 1, "Valid search range"

        # Critical invariant: if target exists, it's in [left, right]
        assert (target not in arr or
                any(arr[i] == target for i in range(left, right + 1))), \
               "Target in current range if it exists"

        mid = (left + right) // 2

        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            assert arr[mid] < target, "All elements left of mid < target"
            left = mid + 1
        else:
            assert arr[mid] > target, "All elements right of mid > target"
            right = mid - 1

    assert left > right, "Search range exhausted"
    assert target not in arr, "Target not found implies not in array"
    return -1
Example 3: Insertion Sort

User request:

"Generate invariants for insertion sort"

python
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key

Response:

python
def insertion_sort(arr):
    for i in range(1, len(arr)):
        # Outer loop invariant
        assert is_sorted(arr[0:i]), "arr[0:i] is sorted"
        assert set(arr) == set(original_arr), "Elements unchanged (only reordered)"

        key = arr[i]
        j = i - 1

        while j >= 0 and arr[j] > key:
            # Inner loop invariants
            assert -1 <= j < i, "j in valid range"
            assert arr[j] > key, "Current element larger than key"
            assert is_sorted(arr[0:j]), "Left part still sorted"
            assert arr[j+2:i+1] are shifted right and sorted

            arr[j + 1] = arr[j]
            j -= 1

        arr[j + 1] = key
        assert is_sorted(arr[0:i+1]), "arr[0:i+1] is now sorted"

    assert is_sorted(arr), "Entire array is sorted"

Tips for Effective Invariant Inference

Start with obvious properties:

  • Variable bounds (0 <= i < n)
  • Loop counter relationships
  • Data structure sizes

Look for accumulation patterns:

  • Sums, products, counts
  • Max/min tracking
  • Collection building

Identify preservation properties:

  • What stays constant? (array length, set of elements)
  • What grows/shrinks monotonically?
  • What relationships are maintained?

Think about the loop's purpose:

  • Why is this loop here?
  • What should be true when it finishes?
  • What must be true for each iteration to work?

Verify your invariants:

  • Check initialization (true before loop)
  • Check maintenance (preserved by loop body)
  • Check that invariant + termination ⟹ post-condition

Be specific:

  • Weak: i >= 0
  • Better: 0 <= i < len(arr)
  • Best: 0 <= i < len(arr) and sum_val == sum(arr[0:i])

Use helper predicates for clarity:

python
def is_sorted(arr):
    return all(arr[i] <= arr[i+1] for i in range(len(arr)-1))

def is_partition(arr, pivot, left, right):
    return (all(arr[i] <= pivot for i in range(left)) and
            all(arr[i] >= pivot for i in range(right, len(arr))))

Reference

For comprehensive invariant patterns across different loop types and languages, see invariant-patterns.md.

© ArabelaTso, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file (references) in skills/invariant-inference of ArabelaTso/Skills-4-SE.

  • SKILL.md
  • references/invariant-patterns.md

Open the folder on GitHubat commit 4f38503

Compare with similar skills

Invariant Inference next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Invariant Inference compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Invariant Inference this skillArabelaTso/Skills-4-SE253—~3.1kAutomated safety check: PassApache-2.0
Fory Releaseapache/fory4.6k—~2.9kAutomated safety check: PassApache-2.0
CodeQL Security Scantrailofbits/skills7.4k—~4.6kAutomated safety check: NotesCC-BY-SA-4.0
Fory Version Bumpapache/fory4.6k—~1.1kAutomated safety check: PassApache-2.0
Fory Performance Optimizationapache/fory4.6k—~2.2kAutomated safety check: PassApache-2.0
MCP Debuggerdebugmcp/mcp-debugger172—~3.8kAutomated safety check: PassMIT

Similar skills

  • Fory Release

    apache/fory

    Prepare an Apache Fory release candidate from a clean release branch, including the version bump, RC tag, JVM staging, ASF source artifacts, SVN upload, and vote email.

    4.6k GitHub stars~2.9k tokensUpdated yesterday
    Auto-check passed
  • CodeQL Security Scan

    trailofbits/skills

    Official

    Scans a codebase for vulnerabilities with CodeQL's data flow and taint tracking in run-all or important-only modes, including data extensions for project-specific sources and sinks.

    7.4k GitHub stars~4.6k tokensUpdated 2 days ago
    SecurityAuto-check: notes
  • Bump Apache Fory release or post-release development versions across Java, Kotlin, Scala, Python, Rust, Go, C++, C, Dart, JavaScript, Swift, integration tests, examples, and source docs.

    4.6k GitHub stars~1.1k tokensUpdated yesterday
    MobileAuto-check passed
  • Run profile-driven bottleneck optimization across Apache Fory implementations (Java, C++, Python/Cython, Go, Rust, Swift, C, JavaScript/TypeScript, Dart, Kotlin, Scala).

    4.6k GitHub stars~2.2k tokensUpdated yesterday
    MobileAuto-check passed
  • MCP Debugger

    debugmcp/mcp-debugger

    A skill your agent uses when investigating a bug, failing test, or unexpected runtime behavior and the mcp-debugger MCP server is available — drives real step-through debuggers (breakpoints, stack…

    172 GitHub stars~3.8k tokensUpdated 2 days ago
    DevelopmentAuto-check passed
  • Dbg

    theodo-group/debug-that

    Debug applications using the dbg CLI debugger. An agent skill from theodo-group/debug-that.

    158 GitHub stars~2.5k tokensUpdated yesterday
    DevelopmentAuto-check passed

More from ArabelaTso/Skills-4-SE

All 170 skills in this repo
  • Framework Migration Assistant

    ArabelaTso/Skills-4-SE

    Automatically migrate Python web applications between frameworks (Flask → FastAPI, Django → FastAPI).

    253 GitHub stars~1.9k tokensUpdated 1 mo ago
    Auto-check passed
  • Metamorphic Test Generator

    ArabelaTso/Skills-4-SE

    Generate test cases using metamorphic testing by applying transformations based on metamorphic properties.

    253 GitHub stars~798 tokensUpdated 1 mo ago
    Auto-check passed
  • Reproduction Trace Instrumenter

    ArabelaTso/Skills-4-SE

    Instruments programs to capture execution traces specifically for reproducing reported bugs, enabling consistent replay and diagnosis of failures.

    253 GitHub stars~2.4k tokensUpdated 1 mo ago
    Auto-check passed
  • Spring Mvc To Boot Migrator

    ArabelaTso/Skills-4-SE

    Automatically migrate Spring MVC applications to Spring Boot.

    253 GitHub stars~2.2k tokensUpdated 1 mo ago
    Auto-check passed
  • State Snapshot Instrumenter

    ArabelaTso/Skills-4-SE

    Instrument programs (Python, C/C++, Java) to capture snapshots of key program states at runtime, including variables, memory, and call stacks.

    253 GitHub stars~2.2k tokensUpdated 1 mo ago
    Auto-check passed

Works with

Questions about Invariant Inference

What does Invariant Inference do?

Automatically infer loop invariants for code verification and correctness proofs. Invariant Inference is an agent skill from ArabelaTso/Skills-4-SE. Automatically infer loop invariants for code verification and correctness proofs.

When should I use Invariant Inference?

Invariant Inference fits situations like: analyzing loops to identify properties that hold throughout execution; generating assertions for verification; proving loop correctness; documenting loop behavior.

How do I install Invariant Inference in Claude Code?

Run `npx skills add ArabelaTso/Skills-4-SE --skill invariant-inference -a claude-code`. Or copy the skill folder (skills/invariant-inference in ArabelaTso/Skills-4-SE) into .claude/skills/invariant-inference in your project. Claude Code loads it when a task matches its description.

How do I install Invariant Inference in Codex?

Run `npx skills add ArabelaTso/Skills-4-SE --skill invariant-inference -a codex`. Or copy the skill folder (skills/invariant-inference in ArabelaTso/Skills-4-SE) into .agents/skills/invariant-inference in your project. Codex loads it when a task matches its description.

Can I use Invariant Inference in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ArabelaTso/Skills-4-SE --skill invariant-inference -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/invariant-inference, .gemini/skills/invariant-inference, .github/skills/invariant-inference and .opencode/skills/invariant-inference in your project.

What does Invariant Inference need to run?

SKILL.md names no scripts, command-line tools or credentials: Invariant Inference is instructions for the agent only. Our summary lists: Python 3.

Does Invariant Inference access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Invariant Inference safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Invariant Inference use?

Invariant Inference is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Invariant Inference use?

About 3.1k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.5k tokens, read only when the agent opens those files.

What are the alternatives to Invariant Inference?

Skills that share tags, products or a category with Invariant Inference: Fory Release (apache/fory, 4.6k stars), CodeQL Security Scan (trailofbits/skills, 7.4k stars), Fory Version Bump (apache/fory, 4.6k stars) and Fory Performance Optimization (apache/fory, 4.6k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Invariant Inference?

ArabelaTso (a GitHub user) maintains it in ArabelaTso/Skills-4-SE, which has 253 GitHub stars. The repository holds 170 skills in this directory. The repository was last updated on August 21, 2026.

Source: ArabelaTso/Skills-4-SE on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.