lean-interact 0.10.0__tar.gz → 0.10.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lean_interact-0.10.0 → lean_interact-0.10.2}/PKG-INFO +2 -2
- {lean_interact-0.10.0 → lean_interact-0.10.2}/README.md +1 -1
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/index.md +1 -1
- {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/beq_plus.py +18 -33
- {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/extract_mathlib_decls.py +7 -0
- lean_interact-0.10.2/examples/type_check.py +69 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/mkdocs.yml +1 -1
- {lean_interact-0.10.0 → lean_interact-0.10.2}/pyproject.toml +1 -1
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/utils.py +1 -1
- {lean_interact-0.10.0 → lean_interact-0.10.2}/tests/test_server.py +1 -25
- lean_interact-0.10.0/examples/type_check.py +0 -118
- {lean_interact-0.10.0 → lean_interact-0.10.2}/.devcontainer/devcontainer.json +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/copilot-instructions.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/workflows/ci.yml +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/workflows/docs.yml +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/workflows/publish-to-pypi.yml +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/.gitignore +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/LICENSE +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/.nojekyll +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/config.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/interface.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/project.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/server.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/sessioncache.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/utils.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/contributing.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/generate_changelog.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/theme/main.html +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/basic-usage.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/custom-lean-configuration.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/data-extraction.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/examples.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/getting-started.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/installation.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/performance.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/set-options.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/tactic-mode.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/troubleshooting.md +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/parallelization.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/proof_generation_and_autoformalization.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/__init__.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/config.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/interface.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/project.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/py.typed +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/server.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/sessioncache.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/tests/test_concurrency.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/tests/test_git_functionality.py +0 -0
- {lean_interact-0.10.0 → lean_interact-0.10.2}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lean-interact
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.2
|
|
4
4
|
Summary: LeanInteract is a Python package that allows you to interact with the Lean theorem prover.
|
|
5
5
|
Author-email: Auguste Poiroux <auguste.poiroux@epfl.ch>
|
|
6
6
|
License: MIT License
|
|
@@ -53,7 +53,7 @@ Check the [documentation](https://augustepoiroux.github.io/LeanInteract/) for de
|
|
|
53
53
|
- **🔗 Interactivity**: Execute Lean code and files directly from Python.
|
|
54
54
|
- **🚀 Ease of Use**: LeanInteract abstracts the complexities of Lean setup and interaction.
|
|
55
55
|
- **💻 Cross-platform**: Works on Windows, macOS, and Linux operating systems.
|
|
56
|
-
- **🔧 Compatibility**: Supports all Lean versions between `v4.8.0-rc1` and `v4.
|
|
56
|
+
- **🔧 Compatibility**: Supports all Lean versions between `v4.8.0-rc1` and `v4.26.0-rc2`.
|
|
57
57
|
- We backport the latest features of Lean REPL to older versions of Lean (see [fork](https://github.com/augustepoiroux/repl)).
|
|
58
58
|
- **📦 Temporary Projects**: Easily instantiate temporary Lean environments.
|
|
59
59
|
- Useful for experimenting with benchmarks depending on [Mathlib](https://github.com/leanprover-community/mathlib4) like [ProofNet#](https://huggingface.co/datasets/PAug/ProofNetSharp) and [MiniF2F](https://github.com/yangky11/miniF2F-lean4).
|
|
@@ -15,7 +15,7 @@ Check the [documentation](https://augustepoiroux.github.io/LeanInteract/) for de
|
|
|
15
15
|
- **🔗 Interactivity**: Execute Lean code and files directly from Python.
|
|
16
16
|
- **🚀 Ease of Use**: LeanInteract abstracts the complexities of Lean setup and interaction.
|
|
17
17
|
- **💻 Cross-platform**: Works on Windows, macOS, and Linux operating systems.
|
|
18
|
-
- **🔧 Compatibility**: Supports all Lean versions between `v4.8.0-rc1` and `v4.
|
|
18
|
+
- **🔧 Compatibility**: Supports all Lean versions between `v4.8.0-rc1` and `v4.26.0-rc2`.
|
|
19
19
|
- We backport the latest features of Lean REPL to older versions of Lean (see [fork](https://github.com/augustepoiroux/repl)).
|
|
20
20
|
- **📦 Temporary Projects**: Easily instantiate temporary Lean environments.
|
|
21
21
|
- Useful for experimenting with benchmarks depending on [Mathlib](https://github.com/leanprover-community/mathlib4) like [ProofNet#](https://huggingface.co/datasets/PAug/ProofNetSharp) and [MiniF2F](https://github.com/yangky11/miniF2F-lean4).
|
|
@@ -17,7 +17,7 @@ hide:
|
|
|
17
17
|
- **🔗 Interactivity**: Execute Lean code and files directly from Python
|
|
18
18
|
- **🚀 Ease of Use**: LeanInteract abstracts the complexities of Lean setup and interaction
|
|
19
19
|
- **💻 Cross-platform**: Works on Windows, macOS, and Linux operating systems
|
|
20
|
-
- **🔧 Compatibility**: Supports all Lean versions between `v4.8.0-rc1` and `v4.
|
|
20
|
+
- **🔧 Compatibility**: Supports all Lean versions between `v4.8.0-rc1` and `v4.26.0-rc2`
|
|
21
21
|
- We backport the latest features of Lean REPL to older versions of Lean (see [fork](https://github.com/augustepoiroux/repl)).
|
|
22
22
|
- **📦 Temporary Projects**: Easily instantiate temporary Lean environments
|
|
23
23
|
- Useful for experimenting with benchmarks depending on [Mathlib](https://github.com/leanprover-community/mathlib4) like [ProofNet#](https://huggingface.co/datasets/PAug/ProofNetSharp) and [MiniF2F](https://github.com/yangky11/miniF2F-lean4)
|
|
@@ -72,7 +72,6 @@ def extract_exact_proof(lean_output: CommandResponse, proof_start_line: int | No
|
|
|
72
72
|
def check_proof_sub(
|
|
73
73
|
server: AutoLeanServer,
|
|
74
74
|
formal_code: str,
|
|
75
|
-
context_env: int,
|
|
76
75
|
formal_2_start_line: int,
|
|
77
76
|
proof: str,
|
|
78
77
|
timeout: int,
|
|
@@ -98,7 +97,6 @@ def check_proof_sub(
|
|
|
98
97
|
lean_output = server.run(
|
|
99
98
|
Command(
|
|
100
99
|
cmd=formal_code + indent_code(prepended + proof, indent_level),
|
|
101
|
-
env=context_env,
|
|
102
100
|
),
|
|
103
101
|
timeout=timeout,
|
|
104
102
|
)
|
|
@@ -124,7 +122,7 @@ def beql(
|
|
|
124
122
|
formalization_1: str,
|
|
125
123
|
formalization_2: str,
|
|
126
124
|
src_header: str,
|
|
127
|
-
|
|
125
|
+
server: AutoLeanServer,
|
|
128
126
|
timeout_per_proof: int,
|
|
129
127
|
verbose: bool = False,
|
|
130
128
|
) -> bool:
|
|
@@ -141,11 +139,6 @@ def beql(
|
|
|
141
139
|
Returns:
|
|
142
140
|
True if both directions of the equivalence hold; False otherwise.
|
|
143
141
|
"""
|
|
144
|
-
server = AutoLeanServer(config=repl_config)
|
|
145
|
-
context_run = server.run(Command(cmd=src_header), add_to_session_cache=True)
|
|
146
|
-
assert isinstance(context_run, CommandResponse)
|
|
147
|
-
context_env = context_run.env
|
|
148
|
-
|
|
149
142
|
base_thm_name = "base_theorem"
|
|
150
143
|
reformulated_thm_name = "reformulated_theorem"
|
|
151
144
|
|
|
@@ -156,7 +149,9 @@ def beql(
|
|
|
156
149
|
if verbose:
|
|
157
150
|
console.print(f"=====\nChecking {'1 -> 2' if i == 0 else '2 -> 1'}")
|
|
158
151
|
try:
|
|
159
|
-
formal_1_code =
|
|
152
|
+
formal_1_code = (
|
|
153
|
+
src_header + "\n\n" + clean_last_theorem_string(base_thm, base_thm_name, add_sorry=True) + "\n\n"
|
|
154
|
+
)
|
|
160
155
|
formal_2_start_line = formal_1_code.count("\n") + 1
|
|
161
156
|
formal_2_code = f"{clean_last_theorem_string(reform_thm, reformulated_thm_name, add_sorry=False)} := by"
|
|
162
157
|
except ValueError:
|
|
@@ -166,14 +161,12 @@ def beql(
|
|
|
166
161
|
|
|
167
162
|
formal_code = formal_1_code + formal_2_code
|
|
168
163
|
# Preliminary check to ensure the formalization is well-typed.
|
|
169
|
-
if check_proof_sub(server, formal_code,
|
|
164
|
+
if check_proof_sub(server, formal_code, formal_2_start_line, "sorry", timeout_per_proof) is None:
|
|
170
165
|
if verbose:
|
|
171
166
|
console.print("Ill-typed formalization encountered, skipping this pair.")
|
|
172
167
|
break
|
|
173
168
|
|
|
174
|
-
proof_exact = check_proof_sub(
|
|
175
|
-
server, formal_code, context_env, formal_2_start_line, "exact?", timeout_per_proof
|
|
176
|
-
)
|
|
169
|
+
proof_exact = check_proof_sub(server, formal_code, formal_2_start_line, "exact?", timeout_per_proof)
|
|
177
170
|
if proof_exact and base_thm_name in proof_exact:
|
|
178
171
|
res[i] = True
|
|
179
172
|
if verbose:
|
|
@@ -189,7 +182,7 @@ def beq_plus(
|
|
|
189
182
|
formalization_1: str,
|
|
190
183
|
formalization_2: str,
|
|
191
184
|
src_header: str,
|
|
192
|
-
|
|
185
|
+
server: AutoLeanServer,
|
|
193
186
|
timeout_per_proof: int,
|
|
194
187
|
verbose: bool = False,
|
|
195
188
|
) -> bool:
|
|
@@ -206,11 +199,6 @@ def beq_plus(
|
|
|
206
199
|
Returns:
|
|
207
200
|
True if both directions of the equivalence hold; False otherwise.
|
|
208
201
|
"""
|
|
209
|
-
server = AutoLeanServer(config=repl_config)
|
|
210
|
-
context_run = server.run(Command(cmd=src_header), add_to_session_cache=True)
|
|
211
|
-
assert isinstance(context_run, CommandResponse)
|
|
212
|
-
context_env = context_run.env
|
|
213
|
-
|
|
214
202
|
base_thm_name = "base_theorem"
|
|
215
203
|
reformulated_thm_name = "reformulated_theorem"
|
|
216
204
|
|
|
@@ -231,7 +219,9 @@ def beq_plus(
|
|
|
231
219
|
if verbose:
|
|
232
220
|
console.print(f"=====\nChecking {'1 -> 2' if i == 0 else '2 -> 1'}")
|
|
233
221
|
try:
|
|
234
|
-
formal_1_code =
|
|
222
|
+
formal_1_code = (
|
|
223
|
+
src_header + "\n\n" + clean_last_theorem_string(base_thm, base_thm_name, add_sorry=True) + "\n\n"
|
|
224
|
+
)
|
|
235
225
|
formal_2_start_line = formal_1_code.count("\n") + 1
|
|
236
226
|
formal_2_code = f"{clean_last_theorem_string(reform_thm, reformulated_thm_name, add_sorry=False)} := by"
|
|
237
227
|
except ValueError:
|
|
@@ -240,15 +230,13 @@ def beq_plus(
|
|
|
240
230
|
break
|
|
241
231
|
|
|
242
232
|
formal_code = formal_1_code + formal_2_code
|
|
243
|
-
if check_proof_sub(server, formal_code,
|
|
233
|
+
if check_proof_sub(server, formal_code, formal_2_start_line, "sorry", timeout_per_proof) is None:
|
|
244
234
|
if verbose:
|
|
245
235
|
console.print("Ill-typed formalization encountered, skipping this pair.")
|
|
246
236
|
break
|
|
247
237
|
|
|
248
238
|
# 1. Use BEqL
|
|
249
|
-
proof_exact = check_proof_sub(
|
|
250
|
-
server, formal_code, context_env, formal_2_start_line, "exact?", timeout_per_proof
|
|
251
|
-
)
|
|
239
|
+
proof_exact = check_proof_sub(server, formal_code, formal_2_start_line, "exact?", timeout_per_proof)
|
|
252
240
|
if proof_exact and base_thm_name in proof_exact:
|
|
253
241
|
res[i] = True
|
|
254
242
|
if verbose:
|
|
@@ -257,7 +245,7 @@ def beq_plus(
|
|
|
257
245
|
continue
|
|
258
246
|
|
|
259
247
|
# If trivially provable by assumption, we skip
|
|
260
|
-
if check_proof_sub(server, formal_code,
|
|
248
|
+
if check_proof_sub(server, formal_code, formal_2_start_line, "assumption", timeout_per_proof):
|
|
261
249
|
if verbose:
|
|
262
250
|
console.print("Skipping as provable by assumption")
|
|
263
251
|
continue
|
|
@@ -266,7 +254,6 @@ def beq_plus(
|
|
|
266
254
|
proof_apply = check_proof_sub(
|
|
267
255
|
server,
|
|
268
256
|
formal_code,
|
|
269
|
-
context_env,
|
|
270
257
|
formal_2_start_line,
|
|
271
258
|
f"apply {base_thm_name}\n" + proof_all_apply,
|
|
272
259
|
timeout_per_proof,
|
|
@@ -284,9 +271,7 @@ def beq_plus(
|
|
|
284
271
|
# drawback of `have` strategy: variable names/types must match exactly
|
|
285
272
|
provable_without_have = False
|
|
286
273
|
try:
|
|
287
|
-
res_without_have = server.run(
|
|
288
|
-
Command(cmd=formal_code + proof_all_have, env=context_env), timeout=timeout_per_proof
|
|
289
|
-
)
|
|
274
|
+
res_without_have = server.run(Command(cmd=formal_2_code + proof_all_have), timeout=timeout_per_proof)
|
|
290
275
|
if isinstance(res_without_have, CommandResponse):
|
|
291
276
|
provable_without_have = res_without_have.lean_code_is_valid(allow_sorry=False)
|
|
292
277
|
except TimeoutError:
|
|
@@ -307,7 +292,6 @@ def beq_plus(
|
|
|
307
292
|
proof_have = check_proof_sub(
|
|
308
293
|
server,
|
|
309
294
|
formal_code,
|
|
310
|
-
context_env,
|
|
311
295
|
formal_2_start_line,
|
|
312
296
|
have_stmt_proof + proof_all_have,
|
|
313
297
|
timeout_per_proof,
|
|
@@ -324,7 +308,6 @@ def beq_plus(
|
|
|
324
308
|
proof_convert = check_proof_sub(
|
|
325
309
|
server,
|
|
326
310
|
formal_code,
|
|
327
|
-
context_env,
|
|
328
311
|
formal_2_start_line,
|
|
329
312
|
f"convert (config := .unfoldSameFun) {base_thm_name} using {max_step}\n" + proof_all_apply,
|
|
330
313
|
timeout_per_proof,
|
|
@@ -344,6 +327,7 @@ def beq_plus(
|
|
|
344
327
|
|
|
345
328
|
def examples_limitations(metric):
|
|
346
329
|
repl_config = LeanREPLConfig(project=TempRequireProject(lean_version="v4.8.0", require="mathlib"), verbose=True)
|
|
330
|
+
server = AutoLeanServer(config=repl_config)
|
|
347
331
|
|
|
348
332
|
src_header = """import Mathlib
|
|
349
333
|
|
|
@@ -414,7 +398,7 @@ open scoped BigOperators"""
|
|
|
414
398
|
formalization_1,
|
|
415
399
|
formalization_2,
|
|
416
400
|
src_header,
|
|
417
|
-
|
|
401
|
+
server,
|
|
418
402
|
timeout_per_proof=DEFAULT_TIMEOUT,
|
|
419
403
|
verbose=True,
|
|
420
404
|
)
|
|
@@ -429,6 +413,7 @@ open scoped BigOperators"""
|
|
|
429
413
|
|
|
430
414
|
def proofnetverif(metric, n_samples=100):
|
|
431
415
|
repl_config = LeanREPLConfig(project=TempRequireProject(lean_version="v4.8.0", require="mathlib"), verbose=True)
|
|
416
|
+
server = AutoLeanServer(config=repl_config)
|
|
432
417
|
|
|
433
418
|
dataset = load_dataset("PAug/ProofNetVerif", split="valid")
|
|
434
419
|
dataset = dataset.shuffle(seed=42).select(range(n_samples))
|
|
@@ -440,7 +425,7 @@ def proofnetverif(metric, n_samples=100):
|
|
|
440
425
|
example["lean4_formalization"],
|
|
441
426
|
example["lean4_prediction"],
|
|
442
427
|
example["lean4_src_header"],
|
|
443
|
-
|
|
428
|
+
server,
|
|
444
429
|
timeout_per_proof=DEFAULT_TIMEOUT,
|
|
445
430
|
verbose=False,
|
|
446
431
|
)
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.10"
|
|
3
|
+
# dependencies = [
|
|
4
|
+
# "lean-interact",
|
|
5
|
+
# "tqdm",
|
|
6
|
+
# ]
|
|
7
|
+
# ///
|
|
1
8
|
"""Clone mathlib4 and extract all Lean declarations in parallel (per-file tasks).
|
|
2
9
|
|
|
3
10
|
Output: mathlib_declarations.jsonl (JSONL, one declaration per line).
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.10"
|
|
3
|
+
# dependencies = [
|
|
4
|
+
# "datasets",
|
|
5
|
+
# "lean-interact",
|
|
6
|
+
# "rich",
|
|
7
|
+
# "tqdm",
|
|
8
|
+
# ]
|
|
9
|
+
# ///
|
|
10
|
+
"""
|
|
11
|
+
This module shows how to type-check / compile Lean4 snippets, leveraging automatic incremental state reuse.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from datasets import load_dataset
|
|
18
|
+
from rich.console import Console
|
|
19
|
+
from tqdm import tqdm
|
|
20
|
+
|
|
21
|
+
from lean_interact import AutoLeanServer, LeanREPLConfig
|
|
22
|
+
from lean_interact.interface import Command, CommandResponse
|
|
23
|
+
from lean_interact.project import TempRequireProject
|
|
24
|
+
|
|
25
|
+
console = Console()
|
|
26
|
+
DEFAULT_TIMEOUT = 60
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def type_check_sequential(dataset: list[dict[str, Any]], repl_config: LeanREPLConfig) -> list[bool]:
|
|
30
|
+
"""
|
|
31
|
+
Type-checks each formalization sequentially.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
dataset: A list of dictionaries with keys 'lean4_src_header' and 'lean4_formalization'.
|
|
35
|
+
repl_config: Configuration for the Lean REPL.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
A list of booleans indicating if each formalization is valid.
|
|
39
|
+
"""
|
|
40
|
+
server = AutoLeanServer(repl_config)
|
|
41
|
+
successes = [False for _ in dataset]
|
|
42
|
+
for idx, row in enumerate(tqdm(dataset)):
|
|
43
|
+
src_header = row["lean4_src_header"]
|
|
44
|
+
formalization = row["lean4_formalization"]
|
|
45
|
+
try:
|
|
46
|
+
server_output = server.run(
|
|
47
|
+
Command(cmd=src_header + "\n" + formalization + " sorry"), timeout=DEFAULT_TIMEOUT
|
|
48
|
+
)
|
|
49
|
+
if isinstance(server_output, CommandResponse):
|
|
50
|
+
successes[idx] = server_output.lean_code_is_valid()
|
|
51
|
+
except (TimeoutError, ConnectionAbortedError, json.JSONDecodeError) as e:
|
|
52
|
+
console.log(f"Error while type checking entry {idx}: {e}")
|
|
53
|
+
return successes
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if __name__ == "__main__":
|
|
57
|
+
proofnetsharp = load_dataset("PAug/ProofNetSharp", split="valid")
|
|
58
|
+
config = LeanREPLConfig(project=TempRequireProject(lean_version="v4.16.0-rc2", require="mathlib"), verbose=True)
|
|
59
|
+
|
|
60
|
+
type_check_results = type_check_sequential(proofnetsharp, config)
|
|
61
|
+
assert len(type_check_results) == len(proofnetsharp)
|
|
62
|
+
|
|
63
|
+
if any(not well_typed for well_typed in type_check_results):
|
|
64
|
+
console.log("Failures:")
|
|
65
|
+
for i, well_typed in enumerate(type_check_results):
|
|
66
|
+
if not well_typed:
|
|
67
|
+
console.log(proofnetsharp[i])
|
|
68
|
+
else:
|
|
69
|
+
console.log("All formalizations are well-typed!")
|
|
@@ -134,7 +134,7 @@ nav:
|
|
|
134
134
|
- Getting Started: user-guide/getting-started.md
|
|
135
135
|
- Basic Usage: user-guide/basic-usage.md
|
|
136
136
|
- Tactic Mode: user-guide/tactic-mode.md
|
|
137
|
-
- Performance &
|
|
137
|
+
- Performance & Parallelization: user-guide/performance.md
|
|
138
138
|
- Data Extraction: user-guide/data-extraction.md
|
|
139
139
|
- Set Lean Options: user-guide/set-options.md
|
|
140
140
|
- Examples: user-guide/examples.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "lean-interact"
|
|
3
|
-
version = "0.10.
|
|
3
|
+
version = "0.10.2"
|
|
4
4
|
description = "LeanInteract is a Python package that allows you to interact with the Lean theorem prover."
|
|
5
5
|
keywords = ["Lean", "theorem proving", "autoformalization", "REPL"]
|
|
6
6
|
license = { file = "LICENSE" }
|
|
@@ -22,7 +22,7 @@ logger.addHandler(handler)
|
|
|
22
22
|
ROOT_DIR = Path(__file__).resolve().parent
|
|
23
23
|
DEFAULT_CACHE_DIR = ROOT_DIR / "cache"
|
|
24
24
|
DEFAULT_REPL_GIT_URL = "https://github.com/augustepoiroux/repl"
|
|
25
|
-
DEFAULT_REPL_VERSION = "v1.3.
|
|
25
|
+
DEFAULT_REPL_VERSION = "v1.3.10"
|
|
26
26
|
|
|
27
27
|
os.makedirs(DEFAULT_CACHE_DIR, exist_ok=True)
|
|
28
28
|
|
|
@@ -71,8 +71,7 @@ class TestLeanServer(unittest.TestCase):
|
|
|
71
71
|
LeanREPLConfig(project=TempRequireProject(lean_version=cls.mostRecentVersion, require="mathlib"), verbose=True)
|
|
72
72
|
|
|
73
73
|
def test_init_with_lean_version(self):
|
|
74
|
-
for version in [self.oldestVersion, "v4.14.0"]:
|
|
75
|
-
# for version in [self.oldestVersion, "v4.14.0", self.mostRecentVersion]: # temporarily skip most recent because v4.25.1 wrongly returns v4.25.0
|
|
74
|
+
for version in [self.oldestVersion, "v4.14.0", self.mostRecentVersion]:
|
|
76
75
|
server = AutoLeanServer(config=LeanREPLConfig(lean_version=version, verbose=True))
|
|
77
76
|
self.assertEqual(server.lean_version, version)
|
|
78
77
|
self.assertEqual(
|
|
@@ -144,29 +143,6 @@ class TestLeanServer(unittest.TestCase):
|
|
|
144
143
|
response = server.run(Command(cmd="#eval Lean.versionString"), verbose=True)
|
|
145
144
|
self.assertIsInstance(response, CommandResponse)
|
|
146
145
|
|
|
147
|
-
def test_init_with_official_repl(self):
|
|
148
|
-
config = LeanREPLConfig(
|
|
149
|
-
repl_rev="v4.25.0-rc2", repl_git="https://github.com/leanprover-community/repl", verbose=True
|
|
150
|
-
)
|
|
151
|
-
server = AutoLeanServer(config=config)
|
|
152
|
-
self.assertEqual(server.lean_version, "v4.25.0-rc2")
|
|
153
|
-
response = server.run(Command(cmd="#eval Lean.versionString"), verbose=True)
|
|
154
|
-
self.assertIsInstance(response, CommandResponse)
|
|
155
|
-
self.assertEqual(
|
|
156
|
-
response,
|
|
157
|
-
CommandResponse(
|
|
158
|
-
messages=[
|
|
159
|
-
Message(
|
|
160
|
-
start_pos=Pos(line=1, column=0),
|
|
161
|
-
end_pos=Pos(line=1, column=5),
|
|
162
|
-
severity="info",
|
|
163
|
-
data='"4.25.0-rc2"',
|
|
164
|
-
)
|
|
165
|
-
],
|
|
166
|
-
env=0,
|
|
167
|
-
),
|
|
168
|
-
)
|
|
169
|
-
|
|
170
146
|
def test_temp_project_creation(self):
|
|
171
147
|
# Create a simple temporary project
|
|
172
148
|
temp_content = """
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# /// script
|
|
2
|
-
# requires-python = ">=3.10"
|
|
3
|
-
# dependencies = [
|
|
4
|
-
# "datasets",
|
|
5
|
-
# "lean-interact",
|
|
6
|
-
# "rich",
|
|
7
|
-
# "tqdm",
|
|
8
|
-
# ]
|
|
9
|
-
# ///
|
|
10
|
-
"""
|
|
11
|
-
This module provides functions to type-check Lean formalizations
|
|
12
|
-
using sequential and optimized batch methods.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
import json
|
|
16
|
-
from typing import Any
|
|
17
|
-
|
|
18
|
-
from datasets import load_dataset
|
|
19
|
-
from rich.console import Console
|
|
20
|
-
from tqdm import tqdm
|
|
21
|
-
|
|
22
|
-
from lean_interact import AutoLeanServer, LeanREPLConfig
|
|
23
|
-
from lean_interact.interface import Command, CommandResponse
|
|
24
|
-
from lean_interact.project import TempRequireProject
|
|
25
|
-
|
|
26
|
-
console = Console()
|
|
27
|
-
DEFAULT_TIMEOUT = 60
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def type_check_sequential(dataset: list[dict[str, Any]], repl_config: LeanREPLConfig) -> list[bool]:
|
|
31
|
-
"""
|
|
32
|
-
Type-checks each formalization sequentially.
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
dataset: A list of dictionaries with keys 'lean4_src_header' and 'lean4_formalization'.
|
|
36
|
-
repl_config: Configuration for the Lean REPL.
|
|
37
|
-
|
|
38
|
-
Returns:
|
|
39
|
-
A list of booleans indicating if each formalization is valid.
|
|
40
|
-
"""
|
|
41
|
-
server = AutoLeanServer(repl_config)
|
|
42
|
-
successes = [False for _ in dataset]
|
|
43
|
-
for idx, row in enumerate(tqdm(dataset)):
|
|
44
|
-
src_header = row["lean4_src_header"]
|
|
45
|
-
formalization = row["lean4_formalization"]
|
|
46
|
-
try:
|
|
47
|
-
server_output = server.run(
|
|
48
|
-
Command(cmd=src_header + "\n" + formalization + " sorry"), timeout=DEFAULT_TIMEOUT
|
|
49
|
-
)
|
|
50
|
-
if isinstance(server_output, CommandResponse):
|
|
51
|
-
successes[idx] = server_output.lean_code_is_valid()
|
|
52
|
-
except (TimeoutError, ConnectionAbortedError, json.JSONDecodeError) as e:
|
|
53
|
-
console.log(f"Error while type checking entry {idx}: {e}")
|
|
54
|
-
return successes
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def type_check_sequential_optimized(dataset: list[dict[str, Any]], repl_config: LeanREPLConfig) -> list[bool]:
|
|
58
|
-
"""
|
|
59
|
-
Optimized type-checking by batching formalizations with a common context.
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
dataset: A list of dictionaries with keys 'lean4_src_header' and 'lean4_formalization'.
|
|
63
|
-
repl_config: Configuration for the Lean REPL.
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
A list of booleans indicating if each formalization is valid.
|
|
67
|
-
"""
|
|
68
|
-
# Group by common src header
|
|
69
|
-
formalizations_idx = list(enumerate(dataset))
|
|
70
|
-
formalizations_grouped: dict[str, list] = {}
|
|
71
|
-
for idx, row in formalizations_idx:
|
|
72
|
-
header = row["lean4_src_header"]
|
|
73
|
-
formalizations_grouped.setdefault(header, []).append((idx, row["lean4_formalization"]))
|
|
74
|
-
|
|
75
|
-
def type_check_group(src_header: str, group: list) -> list[int]:
|
|
76
|
-
server = AutoLeanServer(repl_config)
|
|
77
|
-
context_res = server.run(Command(cmd=src_header), add_to_session_cache=True)
|
|
78
|
-
if not isinstance(context_res, CommandResponse):
|
|
79
|
-
console.log(f"Error while loading context for header '{src_header}': {context_res}")
|
|
80
|
-
return []
|
|
81
|
-
context_env = context_res.env
|
|
82
|
-
valid_indices = []
|
|
83
|
-
for idx, formalization in group:
|
|
84
|
-
try:
|
|
85
|
-
server_output = server.run(
|
|
86
|
-
Command(cmd=formalization + " sorry", env=context_env), timeout=DEFAULT_TIMEOUT
|
|
87
|
-
)
|
|
88
|
-
if isinstance(server_output, CommandResponse) and server_output.lean_code_is_valid():
|
|
89
|
-
valid_indices.append(idx)
|
|
90
|
-
except (TimeoutError, ConnectionAbortedError, json.JSONDecodeError) as e:
|
|
91
|
-
console.log(f"Error in group with header '{src_header}': {e}")
|
|
92
|
-
return valid_indices
|
|
93
|
-
|
|
94
|
-
res: list[bool] = [False for _ in dataset]
|
|
95
|
-
for idx, group in enumerate(tqdm(formalizations_grouped.items())):
|
|
96
|
-
src_header, group = group
|
|
97
|
-
valid_indices = type_check_group(src_header, group)
|
|
98
|
-
for idx in valid_indices:
|
|
99
|
-
res[idx] = True
|
|
100
|
-
return res
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if __name__ == "__main__":
|
|
104
|
-
proofnetsharp = load_dataset("PAug/ProofNetSharp", split="valid")
|
|
105
|
-
config = LeanREPLConfig(project=TempRequireProject(lean_version="v4.16.0-rc2", require="mathlib"), verbose=True)
|
|
106
|
-
|
|
107
|
-
# type_check_results = type_check_sequential(proofnetsharp, config)
|
|
108
|
-
type_check_results = type_check_sequential_optimized(proofnetsharp, config)
|
|
109
|
-
|
|
110
|
-
assert len(type_check_results) == len(proofnetsharp)
|
|
111
|
-
|
|
112
|
-
if any(not well_typed for well_typed in type_check_results):
|
|
113
|
-
console.log("Failures:")
|
|
114
|
-
for i, well_typed in enumerate(type_check_results):
|
|
115
|
-
if not well_typed:
|
|
116
|
-
console.log(proofnetsharp[i])
|
|
117
|
-
else:
|
|
118
|
-
console.log("All formalizations are well-typed!")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lean_interact-0.10.0 → lean_interact-0.10.2}/examples/proof_generation_and_autoformalization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|