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.
Files changed (51) hide show
  1. {lean_interact-0.10.0 → lean_interact-0.10.2}/PKG-INFO +2 -2
  2. {lean_interact-0.10.0 → lean_interact-0.10.2}/README.md +1 -1
  3. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/index.md +1 -1
  4. {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/beq_plus.py +18 -33
  5. {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/extract_mathlib_decls.py +7 -0
  6. lean_interact-0.10.2/examples/type_check.py +69 -0
  7. {lean_interact-0.10.0 → lean_interact-0.10.2}/mkdocs.yml +1 -1
  8. {lean_interact-0.10.0 → lean_interact-0.10.2}/pyproject.toml +1 -1
  9. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/utils.py +1 -1
  10. {lean_interact-0.10.0 → lean_interact-0.10.2}/tests/test_server.py +1 -25
  11. lean_interact-0.10.0/examples/type_check.py +0 -118
  12. {lean_interact-0.10.0 → lean_interact-0.10.2}/.devcontainer/devcontainer.json +0 -0
  13. {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/copilot-instructions.md +0 -0
  15. {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/workflows/ci.yml +0 -0
  16. {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/workflows/docs.yml +0 -0
  17. {lean_interact-0.10.0 → lean_interact-0.10.2}/.github/workflows/publish-to-pypi.yml +0 -0
  18. {lean_interact-0.10.0 → lean_interact-0.10.2}/.gitignore +0 -0
  19. {lean_interact-0.10.0 → lean_interact-0.10.2}/LICENSE +0 -0
  20. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/.nojekyll +0 -0
  21. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/config.md +0 -0
  22. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/interface.md +0 -0
  23. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/project.md +0 -0
  24. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/server.md +0 -0
  25. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/sessioncache.md +0 -0
  26. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/api/utils.md +0 -0
  27. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/contributing.md +0 -0
  28. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/generate_changelog.py +0 -0
  29. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/theme/main.html +0 -0
  30. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/basic-usage.md +0 -0
  31. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/custom-lean-configuration.md +0 -0
  32. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/data-extraction.md +0 -0
  33. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/examples.md +0 -0
  34. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/getting-started.md +0 -0
  35. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/installation.md +0 -0
  36. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/performance.md +0 -0
  37. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/set-options.md +0 -0
  38. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/tactic-mode.md +0 -0
  39. {lean_interact-0.10.0 → lean_interact-0.10.2}/docs/user-guide/troubleshooting.md +0 -0
  40. {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/parallelization.py +0 -0
  41. {lean_interact-0.10.0 → lean_interact-0.10.2}/examples/proof_generation_and_autoformalization.py +0 -0
  42. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/__init__.py +0 -0
  43. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/config.py +0 -0
  44. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/interface.py +0 -0
  45. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/project.py +0 -0
  46. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/py.typed +0 -0
  47. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/server.py +0 -0
  48. {lean_interact-0.10.0 → lean_interact-0.10.2}/src/lean_interact/sessioncache.py +0 -0
  49. {lean_interact-0.10.0 → lean_interact-0.10.2}/tests/test_concurrency.py +0 -0
  50. {lean_interact-0.10.0 → lean_interact-0.10.2}/tests/test_git_functionality.py +0 -0
  51. {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.0
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.25.1`.
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.25.1`.
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.25.1`
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
- repl_config: LeanREPLConfig,
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 = clean_last_theorem_string(base_thm, base_thm_name, add_sorry=True) + "\n\n"
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, context_env, formal_2_start_line, "sorry", timeout_per_proof) is None:
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
- repl_config: LeanREPLConfig,
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 = clean_last_theorem_string(base_thm, base_thm_name, add_sorry=True) + "\n\n"
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, context_env, formal_2_start_line, "sorry", timeout_per_proof) is None:
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, context_env, formal_2_start_line, "assumption", timeout_per_proof):
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
- repl_config,
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
- repl_config,
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 & Multi-processing: user-guide/performance.md
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.0"
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.8"
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