imperative-to-coq-model-extractor — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited imperative-to-coq-model-extractor (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Extract abstract mathematical models from imperative code that can be used for formal reasoning and verification in Coq. This skill transforms imperative programs into functional Coq definitions with explicit state modeling, enabling formal proofs about program behavior.
Understand the program structure and semantics:
Plan the Coq representation:
Z for arbitrary precision integersnat for natural numbersbool for booleanslist for sequencesRecord for structured stateTranslate imperative constructs to Coq:
Pattern: Pure function
// Imperative
int add(int a, int b) {
return a + b;
}(* Coq Model *)
Definition add (a b : Z) : Z := a + b.Pattern: Function with state
// Imperative
int counter = 0;
void increment() {
counter++;
}(* Coq Model *)
Definition counter_state : Type := Z.
Definition increment (c : counter_state) : counter_state := c + 1.Pattern: Loop → Recursion
// Imperative
int sum(int n) {
int total = 0;
for (int i = 0; i < n; i++) {
total += i;
}
return total;
}(* Coq Model *)
Fixpoint sum_aux (n i total : nat) : nat :=
match n with
| 0 => total
| S n' =>
if i <? n then
sum_aux n (S i) (total + i)
else
total
end.
Definition sum (n : nat) : nat := sum_aux n 0 0.Enhance the model with formal specifications:
Definition abs (n : Z) : Z :=
if n <? 0 then -n else n.
Lemma abs_nonneg : forall n : Z, abs n >= 0.
Proof.
intros n. unfold abs.
destruct (n <? 0) eqn:E.
- apply Z.ltb_lt in E. lia.
- apply Z.ltb_ge in E. lia.
Qed. (* Invariant: sum = sum of first i elements *)
Lemma sum_invariant : forall n i total,
i <= n ->
sum_aux n i total = total + (sum of 0..i-1).
Proof.
(* Proof by induction *)
Admitted. Lemma sum_correct : forall n,
sum n = n * (n - 1) / 2.
Proof.
(* Proof *)
Admitted.Ensure the model is correct:
coqc model.v Compute add 2 3. (* Should output 5 *)
Compute sum 5. (* Should output 10 *)Improve the extracted model:
(* Computes the absolute value of an integer *)
Definition abs (n : Z) : Z := ...For detailed patterns, see extraction_patterns.md.
| Imperative | Coq Model |
|---|---|
int x = 10 | Definition x : Z := 10 |
x = x + 1 | x + 1 (functional update) |
if (x > 0) | if x >? 0 then ... else ... |
for (i=0; i<n; i++) | Fixpoint loop (i : nat) ... |
while (cond) | Fixpoint loop ... if cond then ... |
struct S { int x; } | Record S := { x : Z } |
int arr[5] | list Z or Definition arr := [...] |
return x | x (last expression) |
Imperative Input (C):
int factorial(int n) {
int result = 1;
while (n > 1) {
result *= n;
n--;
}
return result;
}Coq Model:
Fixpoint factorial (n : nat) : nat :=
match n with
| 0 => 1
| S n' => n * factorial n'
end.
Lemma factorial_positive : forall n,
factorial n >= 1.
Proof.
induction n.
- simpl. lia.
- simpl. lia.
Qed.Imperative Input (Python):
def find_max(arr):
max_val = arr[0]
for i in range(1, len(arr)):
if arr[i] > max_val:
max_val = arr[i]
return max_valCoq Model:
Require Import List.
Import ListNotations.
Fixpoint find_max (l : list Z) (default : Z) : Z :=
match l with
| [] => default
| [x] => x
| x :: xs => Z.max x (find_max xs default)
end.
Lemma find_max_in_list : forall l default,
l <> [] ->
In (find_max l default) l.
Proof.
(* Proof by induction *)
Admitted.
Lemma find_max_is_max : forall l default x,
In x l ->
x <= find_max l default.
Proof.
(* Proof by induction *)
Admitted.Imperative Input (Java):
class Counter {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}Coq Model:
Record CounterState : Type := mkCounter {
count : nat
}.
Definition init_counter : CounterState := {|
count := 0
|}.
Definition increment (s : CounterState) : CounterState := {|
count := S s.(count)
|}.
Definition getCount (s : CounterState) : nat :=
s.(count).
(* Specification *)
Lemma increment_increases : forall s,
getCount (increment s) = S (getCount s).
Proof.
intros s. unfold increment, getCount. simpl. reflexivity.
Qed.Imperative Input (C++):
int binary_search(int arr[], int n, int target) {
int left = 0, right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target)
return mid;
else if (arr[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return -1;
}Coq Model:
Require Import List.
Import ListNotations.
Fixpoint binary_search_aux (l : list Z) (target : Z)
(left right : nat) : option nat :=
match right - left with
| 0 =>
match nth_error l left with
| Some v => if v =? target then Some left else None
| None => None
end
| S _ =>
if left <=? right then
let mid := (left + right) / 2 in
match nth_error l mid with
| Some v =>
if v =? target then Some mid
else if v <? target then
binary_search_aux l target (S mid) right
else
binary_search_aux l target left (mid - 1)
| None => None
end
else None
end.
Definition binary_search (l : list Z) (target : Z) : option nat :=
binary_search_aux l target 0 (length l - 1).
(* Specification: if result is Some i, then l[i] = target *)
Lemma binary_search_correct : forall l target i,
binary_search l target = Some i ->
nth_error l i = Some target.
Proof.
(* Proof *)
Admitted.nat for non-negative values, Z for integers~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.