Files
lean-bench/datasets/goodman-1.6-exercises.jsonl
T
claude-bot 04d827b3b3 Split pipeline into real bench (exercises) vs library candidates (body)
Restructures the textbook pipeline around the distinction the body-derived
dataset had been blurring: a bench should be actual unsolved problems, and
a reusable premise library should only ever contain statements that have
really been proven, the way Mathlib itself works.

- library_candidates/goodman-1.6.jsonl (renamed from datasets/goodman-1.6.jsonl):
  the book's own Theorem/Proposition/Lemma/Corollary claims from the main
  text. Not bench targets -- premises waiting to be proven once via a real
  lean-bench run, then assembled into the reusable library by
  build_library.py (which already only keeps success:true entries with
  their checked proof, unchanged by this commit).
- datasets/goodman-1.6-exercises.jsonl (new): the actual bench, sourced
  from the book's Exercises 1.6 block via two new scripts,
  textbook/extract_exercises.py (slices the Exercises block, lists its
  numbered items, drops a known false-positive class where a wrapped
  cross-reference like "...Proposition\n1.6.19." looks like a real
  exercise heading) and textbook/formalize_exercises.py (LLM step, given
  both the exercises and body text together since many exercises say
  "Prove Proposition N.N.N" instead of restating the claim).
- Both formalize.py and formalize_exercises.py's validate() now enforce
  that every checklist item is covered by at least one output entry
  (included or explicitly excluded with a reason); formalize_exercises.py
  did not have this yet and a first real run silently dropped 7 of 15
  checklist items with no trace before this was added.
- All 12 model-produced exercise entries needed real fixes before commit,
  the same review pass applied to the body pilot: 3 exercises literally
  ask to prove an already-stated body claim (Exercise 1.6.1 -> Proposition
  1.6.7, 1.6.2 -> Proposition 1.6.9, 1.6.7 -> Proposition 1.6.18, 1.6.9 ->
  Corollary 1.6.20, 1.6.15 -> Lemma 1.6.26) and now reuse that claim's own
  already-checked statement verbatim instead of an independently
  re-derived (and in one case strictly weaker) restatement; two entries
  (1.6.2, 1.6.11) had literal math prose like "I(m, n)" or
  "gcd(n1,...,nk)" leaked into the statement field, which is not valid
  Lean; several had untyped/ambiguous gcd or Prime usage fixed the same
  way the earlier body fixes were (Nat.Prime, IsCoprime, explicit casts,
  IsGreatest instead of max on a Set); and Exercise 1.6.12 part (a) turned
  out to be a discussion question whose unconditional-identity reading is
  actually false (6, 10, 15 are jointly coprime but not pairwise coprime),
  so it was moved to the excluded file with a reason instead of committed
  as a false theorem.
- Definitions can now be real, compiled Lean, not only JSON metadata:
  Definition 1.6.22 (gcd of a list of integers, previously a null
  placeholder since no single Mathlib constant matches it) now has a real
  hand-written `def IsGCDOfList`, and textbook/build_definitions.py
  compiles any manifest's non-null lean_code entries into
  lib/Definitions.lean. goodman-1-6-24 (library) and the new
  goodman-1-6-ex-11-b/c, goodman-1-6-ex-12 (bench) all now use
  IsGCDOfList instead of repeating an inline existential.
- textbook/README.md rewritten around the two-track design and records
  how this is meant to connect to lean-agent's eventual goal-directed
  proof search against the growing library (not yet built).
- New tests for extract_exercises.py and build_definitions.py; full
  local suite still green (18/19, the one failure is the pre-existing,
  unrelated lean_agent import error in test_dataset.py).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vbLFFJiHSZqGZHEkjvG5x
2026-09-18 19:27:40 +00:00

15 lines
11 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"id": "goodman-1-6-ex-1", "source_label": "Exercise 1.6.1", "kind": "exercise", "statement": "∀ (a d : ℤ), d ≥ 1 → ∃! qr : ℤ × ℤ, a = qr.1 * d + qr.2 ∧ 0 ≤ qr.2 ∧ qr.2 < d", "prelude": "import Mathlib.Data.Int.Basic", "natural_language": "For all integers a and d, with d ≥ 1, there exist unique integers q and r such that a = qd + r and 0 ≤ r < d. [fix note: Exercise 1.6.1 literally asks to complete the proof of Proposition 1.6.7 via well-ordering; reused Proposition 1.6.7's own (already elaboration-checked) statement verbatim instead of re-deriving a weaker one -- the model's first draft dropped the uniqueness clause (`∃` instead of `∃!`), which is a materially different, weaker claim.]", "requires": ["Mathlib.Data.Int.Basic"], "references": ["Proposition 1.6.7"], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-2", "source_label": "Exercise 1.6.2", "kind": "exercise", "statement": "∀ (m n : ℤ), let I := {v : ℤ | ∃ a b : ℤ, v = a * m + b * n}; (∀ x ∈ I, ∀ y ∈ I, x + y ∈ I) ∧ (∀ x ∈ I, -x ∈ I) ∧ (∀ x : ℤ, ∀ z ∈ I, x * z ∈ I) ∧ (∀ b : ℤ, b ∣ m ∧ b ∣ n → ∀ z ∈ I, b ∣ z)", "prelude": "import Mathlib.Data.Int.Basic", "natural_language": "For integers m and n, the set I(m, n) has the properties: (a) For x, y in I(m, n), x + y and -x are in I(m, n). (b) For all x in Z, xI(m, n) is a subset of I(m, n). (c) If b divides m and n, then b divides all elements of I(m, n). [fix note: Exercise 1.6.2 literally asks to prove Proposition 1.6.9; reused Proposition 1.6.9's own statement verbatim. The model's first draft used bare `I(m, n)` as if it were a function call, which is not valid Lean -- there is no such function.]", "requires": ["Mathlib.Data.Int.Basic"], "references": ["Proposition 1.6.9"], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-3", "source_label": "Exercise 1.6.3", "kind": "exercise", "statement": "∀ (p : ℕ), p > 1 → (∀ (a b : ℤ), a ≠ 0 → b ≠ 0 → (p:ℤ) ∣ (a * b) → ((p:ℤ) ∣ a ∨ (p:ℤ) ∣ b)) → Nat.Prime p", "prelude": "import Mathlib.Data.Nat.Prime", "natural_language": "If a natural number p > 1 has the property that for all nonzero integers a and b, if p divides the product ab, then p divides a or p divides b, then p is prime. [fix note: Fixed two type mismatches: bare `Prime p` (ambiguous which typeclass instance) changed to `Nat.Prime p` to match convention elsewhere; and `p ∣ (a * b)` for `p : ℕ`, `a b : ℤ` needed an explicit `(p:ℤ)` cast, same class of bug as the earlier library fixes.]", "requires": ["Mathlib.Data.Nat.Prime"], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-5", "source_label": "Exercise 1.6.5", "kind": "exercise", "statement": "∀ (m n : ℤ), m ≠ 0 → n ≠ 0 → Int.gcd m n = Int.gcd (|m|) (|n|)", "prelude": "import Mathlib.Data.Int.GCD", "natural_language": "For nonzero integers m and n, the greatest common divisor of m and n is equal to the greatest common divisor of their absolute values. [fix note: Original used bare `gcd m n` with `m n : ℤ`, ambiguous between the generic `GCDMonoid.gcd` (returns ℤ) and `Int.gcd` (returns ℕ); switched to `Int.gcd` explicitly (returns ℕ, matches the rest of the dataset's convention for integer gcd).]", "requires": ["Mathlib.Data.Int.GCD"], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-6", "source_label": "Exercise 1.6.6", "kind": "exercise", "statement": "∀ (m n : ℤ), m ≠ 0 → n ≠ 0 → IsGreatest {d : ℕ | (d:ℤ) ∣ m ∧ (d:ℤ) ∣ n} (Int.gcd m n)", "prelude": "import Mathlib.Data.Int.GCD", "natural_language": "For nonzero integers m and n, the greatest common divisor of m and n is the largest natural number dividing both m and n. [fix note: Original wrote `gcd m n = max {d : ℕ | ...}`, but `max` is not a function on `Set` in Mathlib (same bug class as an earlier library fix that needed `IsLeast`); 'is the largest natural number dividing both' is `IsGreatest` on the set of common divisors.]", "requires": ["Mathlib.Data.Int.GCD"], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-7", "source_label": "Exercise 1.6.7", "kind": "exercise", "statement": "∀ (p : ℕ) (a : ℤ), Nat.Prime p ∧ a ≠ 0 → (p:ℤ) ∣ a ∨ IsCoprime (p:ℤ) a", "prelude": "import Mathlib.Data.Nat.Prime Mathlib.Data.Int.GCD", "natural_language": "If p is a prime number and a is any nonzero integer, then either p divides a or p and a are relatively prime. [fix note: Exercise 1.6.7 is exactly Proposition 1.6.18's claim; reused Proposition 1.6.18's own statement verbatim rather than re-deriving (the model's draft had the same `Prime p` / untyped `gcd p a = 1` issues as Exercise 1.6.3).]", "requires": ["Mathlib.Data.Nat.Prime", "Mathlib.Data.Int.GCD"], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-8", "source_label": "Exercise 1.6.8", "kind": "exercise", "statement": "∀ (a b x : ℤ), IsCoprime a b → a ∣ (b * x) → a ∣ x", "prelude": "import Mathlib.Data.Int.GCD", "natural_language": "If a and b are relatively prime integers and x is an integer, then if a divides the product bx, a divides x. [fix note: Original wrote `gcd a b = 1`; switched to `IsCoprime a b` for consistency with how 'relatively prime' is formalized everywhere else in this dataset (Definition 1.6.14).]", "requires": ["Mathlib.Data.Int.GCD"], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-9", "source_label": "Exercise 1.6.9", "kind": "exercise", "statement": "∀ (p : ℕ) (as : List ℤ), Nat.Prime p → (∀ (a : ℤ), a ∈ as → a ≠ 0) → (p:ℤ) ∣ List.prod as → ∃ (a : ℤ), a ∈ as ∧ (p:ℤ) ∣ a", "prelude": "import Mathlib.Data.Nat.Prime", "natural_language": "If a prime number p divides a product a₁ * a₂ * ... * aₙ of nonzero integers, then p divides one of the factors. [fix note: Exercise 1.6.9 is exactly Corollary 1.6.20's claim; reused Corollary 1.6.20's own statement verbatim. The model's draft used invalid variadic-ellipsis notation (`a₁ a₂ ... aₙ`) that is not valid Lean syntax at all -- an indexed list is required, matching how the body handles the same claim.]", "requires": ["Mathlib.Data.Nat.Prime"], "references": ["Proposition 1.6.19"], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-11-a", "source_label": "Exercise 1.6.11(a)", "kind": "exercise", "statement": "∀ (ns : List ℤ), let I := {v : ℤ | ∃ ms : List ℤ, ms.length = ns.length ∧ v = (List.zipWith (· * ·) ms ns).sum}; (∀ x ∈ I, ∀ y ∈ I, x + y ∈ I) ∧ (∀ x ∈ I, -x ∈ I) ∧ (∀ (c : ℤ), ∀ x ∈ I, c * x ∈ I)", "prelude": "import Mathlib", "natural_language": "For a list of nonzero integers n1..nk with I the set of integer combinations of them, I is closed under addition, negation, and scalar multiplication.", "requires": [], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-11-b", "source_label": "Exercise 1.6.11(b)", "kind": "exercise", "statement": "∀ (ns : List ℤ) (d : ℕ), IsGCDOfList d ns → IsLeast {v : ℤ | v ∈ {v : ℤ | ∃ ms : List ℤ, ms.length = ns.length ∧ v = (List.zipWith (· * ·) ms ns).sum} ∧ 0 < v} (d : ℤ)", "prelude": "import Mathlib\ndef IsGCDOfList (d : ℕ) (as : List ℤ) : Prop :=\n (∀ a ∈ as, (d:ℤ) ∣ a) ∧ ∀ e : ℤ, (∀ a ∈ as, e ∣ a) → e ∣ (d:ℤ)", "natural_language": "The gcd of n1..nk is the least positive element of I (the set of their integer combinations).", "requires": [], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-11-c", "source_label": "Exercise 1.6.11(c)", "kind": "exercise", "statement": "∀ (ns : List ℤ) (d : ℕ), IsGCDOfList d ns → {v : ℤ | ∃ ms : List ℤ, ms.length = ns.length ∧ v = (List.zipWith (· * ·) ms ns).sum} = {v : ℤ | (d:ℤ) ∣ v}", "prelude": "import Mathlib\ndef IsGCDOfList (d : ℕ) (as : List ℤ) : Prop :=\n (∀ a ∈ as, (d:ℤ) ∣ a) ∧ ∀ e : ℤ, (∀ a ∈ as, e ∣ a) → e ∣ (d:ℤ)", "natural_language": "I (the set of integer combinations of n1..nk) equals the set of multiples of their gcd d.", "requires": [], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-12", "source_label": "Exercise 1.6.12(b)", "kind": "exercise", "statement": "∀ (ns : List ℤ), (∃ d : ℕ, IsGCDOfList d ns ∧ d = 1) ↔ (1 : ℤ) ∈ {v : ℤ | ∃ ms : List ℤ, ms.length = ns.length ∧ v = (List.zipWith (· * ·) ms ns).sum}", "prelude": "import Mathlib\ndef IsGCDOfList (d : ℕ) (as : List ℤ) : Prop :=\n (∀ a ∈ as, (d:ℤ) ∣ a) ∧ ∀ e : ℤ, (∀ a ∈ as, e ∣ a) → e ∣ (d:ℤ)", "natural_language": "(a) Determine if the integers n₁, n₂, ..., nₖ are relatively prime if and only if they are pairwise relatively prime. (b) Show that n₁, n₂, ..., nₖ are relatively prime if and only if 1 ∈ I(n₁, n₂, ..., nₖ). [fix note: Part (a) ('is relatively prime the same as pairwise relatively prime?') is a discussion question, not a fixed claim to formalize -- and its unconditional-identity reading is actually FALSE in general (e.g. 6, 10, 15 are jointly coprime but not pairwise coprime), so it cannot be stated as an unconditional theorem. Moved to the excluded file with a reason. This entry keeps only part (b), the genuine 'relatively prime iff 1 in I' claim, rewritten with `ns : List ℤ` / `IsGCDOfList` instead of the model's invalid variadic `gcd(n₁, n₂, ..., nₖ)` and `I(n₁, ..., nₖ)` notation.]", "requires": ["Mathlib.Data.Int.GCD"], "references": [], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-14", "source_label": "Exercise 1.6.14", "kind": "exercise", "statement": "∀ (m n : ℤ), m ≠ 0 → n ≠ 0 → (IsCoprime m n ↔ ∀ (p : ℕ), Nat.Prime p → (p:ℤ) ∣ m → ¬((p:ℤ) ∣ n))", "prelude": "import Mathlib.Data.Int.GCD Mathlib.Data.Nat.Prime", "natural_language": "Show that two nonzero integers are relatively prime if and only if they have no common prime factors. Use this to give a different proof of Corollary 1.6.17, relying on the uniqueness of the prime factorization of an integer. [fix note: Fixed the same `Prime p` / untyped `gcd m n = 1` / missing ℤ casts as the other exercises; used `IsCoprime m n` for consistency.]", "requires": ["Mathlib.Data.Int.GCD", "Mathlib.Data.Nat.Prime"], "references": ["Corollary 1.6.17"], "include_in_bench": true, "exclude_reason": null}
{"id": "goodman-1-6-ex-15", "source_label": "Exercise 1.6.15", "kind": "exercise", "statement": "∀ (as : List ℤ) (z : ℤ), as.length ≥ 2 → (∀ (i j : ℕ), i ≠ j → i < as.length → j < as.length → IsCoprime (as[i]) (as[j])) → (∀ (a : ℤ), a ∈ as → a ≠ 0) → (∀ (a : ℤ), a ∈ as → a ∣ z) → List.prod as ∣ z", "prelude": "import Mathlib.Data.Int.GCD", "natural_language": "Let a₁, a₂, ..., aₙ be pairwise relatively prime integers, and let a = a₁ * a₂ * ... * aₙ. If an integer z is divisible by each aᵢ, then z is divisible by a. [fix note: Exercise 1.6.15 literally asks to prove Lemma 1.6.26; reused Lemma 1.6.26's own statement verbatim instead of the model's invalid variadic-ellipsis draft.]", "requires": ["Mathlib.Data.Int.GCD"], "references": ["Lemma 1.6.26"], "include_in_bench": true, "exclude_reason": null}