Restructure and improve Isabelle or Coq proofs to enhance readability, modularity, and maintainability without changing semantics. Use when proofs are long and monolithic, have repeated patterns, use unclear naming, lack documentation, or when the user asks to refactor, clean up, improve, or reorganize their formal proofs.
91
86%
Does it follow best practices?
Impact
100%
1.00xAverage score across 3 eval scenarios
Passed
No known issues
Improve proof quality by restructuring Isabelle and Coq proofs for better readability, modularity, and maintainability while preserving semantics. This skill applies proven refactoring patterns to make proofs easier to understand and maintain.
Identify code smells and improvement opportunities:
Structure issues:
Naming issues:
Documentation issues:
Modularity issues:
Complexity issues:
Choose appropriate refactoring patterns:
Extract Helper Lemma:
Inline Trivial Lemma:
Break Down Long Proof:
Extract Common Pattern:
Simplify Proof Structure:
Improve Naming:
Add Documentation:
Strengthen Induction Hypothesis:
Generalize Lemma:
Replace Manual Proof with Automation:
Execute the refactoring safely:
Preserve semantics:
Make incremental changes:
Test continuously:
Document changes:
Ensure refactoring achieved goals:
Readability:
Modularity:
Maintainability:
Performance:
For detailed patterns and examples, see refactoring_patterns.md.
| Code Smell | Refactoring | When to Apply |
|---|---|---|
| Long proof (>20 lines) | Extract Helper Lemma | Complex subgoals, repeated reasoning |
| One-use trivial lemma | Inline Trivial Lemma | Proof is simple, used once |
| Many cases | Break Down Long Proof | Complex case analysis |
| Repeated pattern | Extract Common Pattern | Same proof multiple times |
| Complex tactics | Simplify Proof Structure | Simpler tactics available |
| Generic names | Improve Naming | Unclear what lemma proves |
| No comments | Add Documentation | Complex or non-obvious proof |
| Stuck induction | Strengthen Hypothesis | Need more general statement |
| Too specific | Generalize Lemma | Could be more reusable |
| Tedious manual proof | Use Automation | Standard tactics available |
Before (Coq):
Lemma complex_theorem : forall n m : nat,
n > 0 -> m > 0 -> n + m > 0 /\ n * m > 0.
Proof.
intros n m Hn Hm.
split.
- destruct n. inversion Hn.
destruct m. inversion Hm.
simpl. lia.
- destruct n. inversion Hn.
destruct m. inversion Hm.
simpl. apply Nat.mul_pos_pos; lia.
Qed.After (Coq):
Lemma add_pos : forall n m : nat,
n > 0 -> m > 0 -> n + m > 0.
Proof. intros. lia. Qed.
Lemma mul_pos : forall n m : nat,
n > 0 -> m > 0 -> n * m > 0.
Proof. intros. apply Nat.mul_pos_pos; lia. Qed.
Lemma complex_theorem : forall n m : nat,
n > 0 -> m > 0 -> n + m > 0 /\ n * m > 0.
Proof.
intros. split.
- apply add_pos; assumption.
- apply mul_pos; assumption.
Qed.Improvements:
Before (Coq):
Lemma add_comm : forall n m : nat, n + m = m + n.
Proof.
intros n m.
induction n.
- simpl. rewrite <- plus_n_O. reflexivity.
- simpl. rewrite IHn. rewrite <- plus_n_Sm. reflexivity.
Qed.After (Coq):
Lemma add_comm : forall n m : nat, n + m = m + n.
Proof.
intros. lia.
Qed.Improvements:
Before (Isabelle):
lemma l1: "length (xs @ ys) = length xs + length ys"
by (induction xs) auto
lemma l2: "length (rev xs) = length xs"
by (induction xs) auto
lemma thm: "length (xs @ ys) = length xs + length ys ∧
length (rev xs) = length xs"
using l1 l2 by simpAfter (Isabelle):
lemma append_length: "length (xs @ ys) = length xs + length ys"
by (induction xs) auto
lemma rev_length: "length (rev xs) = length xs"
by (induction xs) auto
lemma list_length_properties:
"length (xs @ ys) = length xs + length ys ∧
length (rev xs) = length xs"
using append_length rev_length by simpImprovements:
Before (Coq):
Lemma partition_spec : forall (A : Type) (f : A -> bool) (l : list A),
let (l1, l2) := partition f l in
filter f l = l1 /\ filter (fun x => negb (f x)) l = l2.
Proof.
(* Complex 20-line proof *)
Admitted.After (Coq):
(** Specification of list partition function.
Given a predicate f and a list l, partition splits l into two lists:
- l1 contains all elements satisfying f
- l2 contains all elements not satisfying f
This lemma proves that partition is equivalent to filtering twice.
Proof strategy: Induction on l, with case analysis on f(head).
*)
Lemma partition_spec : forall (A : Type) (f : A -> bool) (l : list A),
let (l1, l2) := partition f l in
filter f l = l1 /\ filter (fun x => negb (f x)) l = l2.
Proof.
(* Complex 20-line proof *)
Admitted.Improvements:
Before (Isabelle):
lemma complex_cases: "P x"
proof (cases x)
case (C1 a b c)
(* 15 lines of proof *)
then show ?thesis by auto
next
case (C2 d e)
(* 12 lines of proof *)
then show ?thesis by auto
next
case (C3 f)
(* 10 lines of proof *)
then show ?thesis by auto
qedAfter (Isabelle):
lemma case_C1: "⋀a b c. x = C1 a b c ⟹ P x"
(* 15 lines of proof *)
by auto
lemma case_C2: "⋀d e. x = C2 d e ⟹ P x"
(* 12 lines of proof *)
by auto
lemma case_C3: "⋀f. x = C3 f ⟹ P x"
(* 10 lines of proof *)
by auto
lemma complex_cases: "P x"
by (cases x) (auto simp: case_C1 case_C2 case_C3)Improvements:
Before (Coq):
Fixpoint sum (n : nat) : nat :=
match n with
| 0 => 0
| S n' => n + sum n'
end.
Lemma sum_formula : forall n : nat, 2 * sum n = n * (n + 1).
Proof.
induction n.
- reflexivity.
- simpl. (* Gets stuck - IH not strong enough *)
Admitted.After (Coq):
(* Strengthen by generalizing with accumulator *)
Lemma sum_formula_gen : forall n acc : nat,
2 * (sum n + acc) = n * (n + 1) + 2 * acc.
Proof.
induction n; intros.
- simpl. lia.
- simpl. rewrite IHn. lia.
Qed.
Lemma sum_formula : forall n : nat, 2 * sum n = n * (n + 1).
Proof.
intros. pose proof (sum_formula_gen n 0). lia.
Qed.Improvements:
Good times:
Bad times:
High priority:
Low priority:
Balance:
Guidelines:
Before:
During:
After:
0f00a4f
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.