Add textbook formalization pipeline (extract -> LLM formalize -> elaboration check -> library assembly)
- extract_section.py: slice a book section out of a pdftotext -layout dump and list its labeled Theorem/Proposition/Lemma/Corollary/Definition items. - formalize.py: LLM-formalize a section into Lean 4 candidate statements (preferring Mathlib vocabulary) plus a definitions manifest. - check_statements.py: elaboration-only sanity check against a real Mathlib-backed Lean project (must run outside the Cowork sandbox, which has no Lean toolchain and can't run macOS binaries anyway). - build_library.py: assemble solved lean-bench results into a reusable .lean file, reusing each winning proof verbatim. - llm.py: standalone OpenAI-compatible chat client + .env loader, kept independent of lean_agent so this pipeline works without it installed. - Source PDFs and raw/layout text dumps are gitignored (copyrighted material); only code and the final short Lean statement datasets are tracked.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import unittest
|
||||
from textbook.extract_section import extract_section, labeled_statements
|
||||
|
||||
FIXTURE = """\
|
||||
1.6. Divisibility in the Integers
|
||||
intro text
|
||||
|
||||
Proposition 1.6.1.
|
||||
body
|
||||
|
||||
Theorem 1.6.6. There are infinitely many prime numbers.
|
||||
Proof. blah
|
||||
36 1. ALGEBRAIC THEMES
|
||||
|
||||
|
||||
Theorem 1.6.6. There are infinitely many prime numbers.
|
||||
Proof continues after a page break, repeats the label.
|
||||
|
||||
1.7. Modular Arithmetic
|
||||
next section text
|
||||
"""
|
||||
|
||||
|
||||
class ExtractSectionTests(unittest.TestCase):
|
||||
def test_extract_section_slices_between_headings(self):
|
||||
section = extract_section(FIXTURE, '1.6. Divisibility in the Integers', '1.7. Modular Arithmetic')
|
||||
self.assertIn('Theorem 1.6.6', section)
|
||||
self.assertNotIn('next section text', section)
|
||||
|
||||
def test_extract_section_missing_heading_raises(self):
|
||||
with self.assertRaises(ValueError):
|
||||
extract_section(FIXTURE, '1.6. Divisibility in the Integers', '9.9. Does Not Exist')
|
||||
|
||||
def test_labeled_statements_dedupes_and_orders(self):
|
||||
section = extract_section(FIXTURE, '1.6. Divisibility in the Integers', '1.7. Modular Arithmetic')
|
||||
items = labeled_statements(section, '1.6.')
|
||||
labels = [item['label'] for item in items]
|
||||
# Theorem 1.6.6 appears twice (page-break repeat) but must be kept once, and
|
||||
# book order (1.6.1 before 1.6.6) must be preserved.
|
||||
self.assertEqual(labels, ['1.6.1', '1.6.6'])
|
||||
|
||||
def test_labeled_statements_filters_by_prefix(self):
|
||||
section = extract_section(FIXTURE, '1.6. Divisibility in the Integers', '1.7. Modular Arithmetic')
|
||||
items = labeled_statements(section, '1.7.')
|
||||
self.assertEqual(items, [])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user