| name | static-reasoning-verifier |
| description | Verify code correctness statically against specifications using type checking, contract verification, and formal methods. Use when: (1) Verifying type safety and null safety in Python, Java, or C/C++ code, (2) Checking design-by-contract specifications (preconditions, postconditions, invariants), (3) Validating code against formal specifications, (4) Ensuring code quality and correctness before runtime, (5) Finding potential bugs through static analysis. Supports Python (mypy, contracts), Java (javac, JML), and provides verification scripts and contract specification guidelines. |
Static Reasoning Verifier
Verify code correctness statically against specifications through type checking, contract verification, and formal reasoning.
Quick Start
Verify Python Code
python scripts/verify_python.py src/app.py
python scripts/verify_python.py src/ --strict
Verify Java Code
python scripts/verify_java.py src/Main.java
python scripts/verify_java.py src/ --strict
Verification Types
1. Type Checking
Verify type correctness using static type checkers:
Python (mypy):
def add(a: int, b: int) -> int:
return a + b
result: int = add(5, 10)
result: str = add(5, 10)
Java:
public int add(int a, int b) {
return a + b;
}
int result = add(5, 10);
String result = add(5, 10);
2. Contract Verification
Verify preconditions, postconditions, and invariants:
Python:
def sqrt(x: float) -> float:
"""
Calculate square root.
Requires:
- x >= 0
Ensures:
- result * result ≈ x
"""
assert x >= 0, "Input must be non-negative"
result = x ** 0.5
assert abs(result * result - x) < 1e-10
return result
Java (JML):
public static int sqrt(int x) {
}
3. Null Safety
Verify null pointer safety:
Java:
public @NonNull String getName(@NonNull User user) {
return user.getName();
}
Python:
from typing import Optional
def find_user(user_id: int) -> Optional[User]:
"""May return None if user not found."""
return database.get_user(user_id)
Verification Workflow
1. Write Specifications
Define contracts for functions/methods:
def divide(a: float, b: float) -> float:
"""
Divide two numbers.
Precondition:
- b != 0
Postcondition:
- result * b ≈ a
Raises:
ValueError: If b is zero
"""
if b == 0:
raise ValueError("Division by zero")
return a / b
2. Add Type Annotations
from typing import List, Optional
def process_items(items: List[int], threshold: int = 0) -> List[int]:
"""Filter items above threshold."""
return [item for item in items if item > threshold]
3. Run Verification
python scripts/verify_python.py src/
4. Review Issues
Found 3 issue(s): 1 error(s), 2 warning(s)
ERRORS:
❌ src/utils.py:15 [type]
Argument 1 to "divide" has incompatible type "str"; expected "float"
💡 Check argument type matches function signature
WARNINGS:
⚠️ src/math.py:42 [contract]
Function 'sqrt' has parameters but no preconditions specified
💡 Add 'Requires:' section in docstring or @requires decorator
5. Fix Issues
Update code to satisfy specifications:
result = divide("10", 5)
result = divide(10.0, 5.0)
Python Verification
Type Checking with mypy
The verification script uses mypy for static type checking:
python scripts/verify_python.py src/ --strict
Checks:
- Type compatibility
- Function signatures
- Return types
- Optional/None handling
Example:
def greet(name: str) -> str:
return f"Hello, {name}"
greet("Alice")
greet(123)
Contract Verification
Checks design-by-contract specifications:
Decorator-based:
from contracts import requires, ensures
@requires(lambda x: x >= 0)
@ensures(lambda result: result >= 0)
def sqrt(x: float) -> float:
return x ** 0.5
Docstring-based:
def withdraw(account: Account, amount: float) -> None:
"""
Withdraw money from account.
Requires:
- amount > 0
- amount <= account.balance
Ensures:
- account.balance == old(account.balance) - amount
"""
assert amount > 0
assert amount <= account.balance
account.balance -= amount
See python_contracts.md for complete guide on Python design-by-contract patterns.
Java Verification
Type and Null Safety
The verification script uses javac for compilation and type checking:
python scripts/verify_java.py src/ --strict
Checks:
- Type compatibility
- Null safety annotations (@NonNull, @Nullable)
- Method signatures
- Generic type parameters
Example:
public @NonNull String formatUser(@NonNull User user) {
return user.getName() + " (" + user.getEmail() + ")";
}
public @Nullable User findUser(int userId) {
return database.getUser(userId);
}
JML Contract Verification
Checks Java Modeling Language specifications:
public class BankAccount {
private double balance;
public void withdraw(double amount) {
balance -= amount;
}
public void deposit(double amount) {
balance += amount;
}
}
See java_jml.md for complete JML specification guide.
Common Verification Patterns
Range Validation
def set_age(person: Person, age: int) -> None:
"""
Requires: 0 <= age <= 150
Ensures: person.age == age
"""
assert 0 <= age <= 150, "Age must be between 0 and 150"
person.age = age
Collection Constraints
def process_batch(items: List[Item]) -> None:
"""
Requires:
- len(items) > 0
- len(items) <= 1000
"""
assert len(items) > 0, "Batch cannot be empty"
assert len(items) <= 1000, "Batch too large"
State Invariants
class Stack:
"""
Invariant:
- 0 <= self.size <= self.capacity
- All elements before size are not None
"""
def push(self, item):
"""
Requires: not self.is_full() and item is not None
Ensures: self.size == old(self.size) + 1
"""
assert not self.is_full()
assert item is not None
self.items[self.size] = item
self.size += 1
self._check_invariant()
Best Practices
1. Write Contracts First
Define specifications before implementation:
def sort_list(items: List[int]) -> List[int]:
"""
Sort list in ascending order.
Requires:
- items is a list
Ensures:
- len(result) == len(items)
- result is sorted ascending
- result contains same elements as items
"""
2. Keep Contracts Simple
def withdraw(amount: float):
"""Requires: amount > 0 and amount <= balance"""
assert amount > 0 and amount <= self.balance
def withdraw(amount: float):
"""Requires: (amount > 0 and amount <= balance) or (overdraft_allowed and amount <= balance + overdraft_limit)"""
3. Use Type Annotations Consistently
def calculate_total(items: List[Item], tax_rate: float) -> float:
return sum(item.price for item in items) * (1 + tax_rate)
def calculate_total(items, tax_rate):
return sum(item.price for item in items) * (1 + tax_rate)
4. Verify Early and Often
python scripts/verify_python.py src/
make verify
5. Document Side Effects
def update_database(user: User) -> None:
"""
Update user in database.
Requires:
- user.id is set
Ensures:
- Database contains updated user
Side effects:
- Modifies database
- May raise DatabaseError
"""
Troubleshooting
Type Errors
Problem: Incompatible type error
Solution:
result: int = int(value)
result = cast(int, value)
Problem: Optional type handling
Solution:
def get_name(user: Optional[User]) -> str:
if user is None:
return "Unknown"
return user.name
Contract Violations
Problem: Precondition failure
Solution:
if amount > 0 and amount <= account.balance:
account.withdraw(amount)
else:
raise ValueError("Invalid withdrawal amount")
Problem: Postcondition failure
Solution:
def sqrt(x: float) -> float:
result = x ** 0.5
assert abs(result * result - x) < 1e-10
return result
Reference Documentation
Python Contracts
See python_contracts.md for:
- Design by contract patterns
- Preconditions, postconditions, invariants
- Decorator-based contracts (icontract, deal)
- Docstring specifications
- Type annotations as contracts
- Common contract patterns
- Verification checklist
Java JML
See java_jml.md for:
- JML syntax and semantics
- Preconditions (@requires)
- Postconditions (@ensures)
- Class invariants
- Quantifiers and pure methods
- Assignable clauses
- Null safety with JML
- OpenJML verification tools
- Loop invariants
- Contract inheritance
Integration with Development Workflow
Pre-commit Hook
#!/bin/bash
echo "Running static verification..."
python scripts/verify_python.py src/
if [ $? -ne 0 ]; then
echo "Verification failed. Commit aborted."
exit 1
fi
CI/CD Pipeline
name: Static Verification
on: [push, pull_request]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: pip install mypy
- name: Run verification
run: python scripts/verify_python.py src/ --strict
IDE Integration
Most IDEs support type checking and linting:
- VS Code: Python extension with mypy integration
- PyCharm: Built-in type checker
- IntelliJ IDEA: Java type checking and JML plugins