lean-interact 0.5.2__tar.gz → 0.5.3__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.5.2 → lean_interact-0.5.3}/PKG-INFO +8 -4
- {lean_interact-0.5.2 → lean_interact-0.5.3}/README.md +7 -3
- {lean_interact-0.5.2 → lean_interact-0.5.3}/examples/proof_generation_and_autoformalization.py +15 -12
- {lean_interact-0.5.2 → lean_interact-0.5.3}/pyproject.toml +1 -1
- {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/config.py +9 -2
- {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/interface.py +5 -1
- {lean_interact-0.5.2 → lean_interact-0.5.3}/tests/test_concurrency.py +4 -1
- {lean_interact-0.5.2 → lean_interact-0.5.3}/tests/test_server.py +9 -1
- {lean_interact-0.5.2 → lean_interact-0.5.3}/.devcontainer/devcontainer.json +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/.github/workflows/ci.yml +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/.github/workflows/publish-to-pypi.yml +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/.gitignore +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/LICENSE +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/examples/beq_plus.py +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/examples/type_check.py +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/__init__.py +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/server.py +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/utils.py +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/tests/test_utils.py +0 -0
- {lean_interact-0.5.2 → lean_interact-0.5.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lean-interact
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
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
|
|
@@ -95,7 +95,9 @@ Requirements:
|
|
|
95
95
|
|
|
96
96
|
- Python >= 3.10
|
|
97
97
|
- git
|
|
98
|
-
- [Lean 4](https://leanprover-community.github.io/get_started.html)
|
|
98
|
+
- [Lean 4](https://leanprover-community.github.io/get_started.html)
|
|
99
|
+
- **Tip:** use the cross-platform `install-lean` command from LeanInteract.
|
|
100
|
+
- Your `elan` version should be at least `4.0.0` (`elan --version`).
|
|
99
101
|
|
|
100
102
|
## Script examples
|
|
101
103
|
|
|
@@ -481,7 +483,9 @@ Common issues and their solutions:
|
|
|
481
483
|
|
|
482
484
|
3. **Long waiting times during first run**: This is expected as Lean REPL is being downloaded and built. Additionally, if you are importing Mathlib it will take even more time. Subsequent runs will be much faster.
|
|
483
485
|
|
|
484
|
-
4.
|
|
486
|
+
4. **`Failed during Lean project setup: Command '['lake', 'update']' returned non-zero exit status 1.`**: This error may occur if your `elan` version is outdated (i.e. < 4.0.0). To resolve this, update `elan` using `elan self update` or read the documentation [here](https://leanprover-community.github.io/get_started.html).
|
|
487
|
+
|
|
488
|
+
5. **(Windows) Path too long error**: Windows has a maximum path length limitation of 260 characters.
|
|
485
489
|
If you get an error similar to the following one, you are likely affected by this problem:
|
|
486
490
|
|
|
487
491
|
```
|
|
@@ -515,7 +519,7 @@ If you use LeanInteract in your research, please cite it as follows:
|
|
|
515
519
|
@software{leaninteract,
|
|
516
520
|
author = {Poiroux, Auguste and Kuncak, Viktor and Bosselut, Antoine},
|
|
517
521
|
title = {LeanInteract: A Python Interface for Lean 4},
|
|
518
|
-
url = {https://github.com/augustepoiroux/
|
|
522
|
+
url = {https://github.com/augustepoiroux/LeanInteract},
|
|
519
523
|
year = {2025}
|
|
520
524
|
}
|
|
521
525
|
```
|
|
@@ -58,7 +58,9 @@ Requirements:
|
|
|
58
58
|
|
|
59
59
|
- Python >= 3.10
|
|
60
60
|
- git
|
|
61
|
-
- [Lean 4](https://leanprover-community.github.io/get_started.html)
|
|
61
|
+
- [Lean 4](https://leanprover-community.github.io/get_started.html)
|
|
62
|
+
- **Tip:** use the cross-platform `install-lean` command from LeanInteract.
|
|
63
|
+
- Your `elan` version should be at least `4.0.0` (`elan --version`).
|
|
62
64
|
|
|
63
65
|
## Script examples
|
|
64
66
|
|
|
@@ -444,7 +446,9 @@ Common issues and their solutions:
|
|
|
444
446
|
|
|
445
447
|
3. **Long waiting times during first run**: This is expected as Lean REPL is being downloaded and built. Additionally, if you are importing Mathlib it will take even more time. Subsequent runs will be much faster.
|
|
446
448
|
|
|
447
|
-
4.
|
|
449
|
+
4. **`Failed during Lean project setup: Command '['lake', 'update']' returned non-zero exit status 1.`**: This error may occur if your `elan` version is outdated (i.e. < 4.0.0). To resolve this, update `elan` using `elan self update` or read the documentation [here](https://leanprover-community.github.io/get_started.html).
|
|
450
|
+
|
|
451
|
+
5. **(Windows) Path too long error**: Windows has a maximum path length limitation of 260 characters.
|
|
448
452
|
If you get an error similar to the following one, you are likely affected by this problem:
|
|
449
453
|
|
|
450
454
|
```
|
|
@@ -478,7 +482,7 @@ If you use LeanInteract in your research, please cite it as follows:
|
|
|
478
482
|
@software{leaninteract,
|
|
479
483
|
author = {Poiroux, Auguste and Kuncak, Viktor and Bosselut, Antoine},
|
|
480
484
|
title = {LeanInteract: A Python Interface for Lean 4},
|
|
481
|
-
url = {https://github.com/augustepoiroux/
|
|
485
|
+
url = {https://github.com/augustepoiroux/LeanInteract},
|
|
482
486
|
year = {2025}
|
|
483
487
|
}
|
|
484
488
|
```
|
{lean_interact-0.5.2 → lean_interact-0.5.3}/examples/proof_generation_and_autoformalization.py
RENAMED
|
@@ -268,7 +268,7 @@ def run_proof_generation_pipeline(
|
|
|
268
268
|
proofs = [f"by\n{proof}" for proof in proofs]
|
|
269
269
|
|
|
270
270
|
# Sort the proofs by their frequency and length while keeping only unique proofs
|
|
271
|
-
proofs = sorted(proofs, key=
|
|
271
|
+
proofs = sorted(proofs, key=len)
|
|
272
272
|
proofs_freq = Counter(proofs)
|
|
273
273
|
proofs = list(proofs_freq.keys())
|
|
274
274
|
|
|
@@ -364,21 +364,24 @@ def default_goedelprover() -> dict:
|
|
|
364
364
|
if __name__ == "__main__":
|
|
365
365
|
## For DeepSeek Prover V1.5 and Goedel Prover, make sure to run this script on a GPU with at least 24GB of VRAM.
|
|
366
366
|
|
|
367
|
-
# dataset = "minif2f"
|
|
368
|
-
# split = "validation"
|
|
369
|
-
# lean_version = "v4.8.0"
|
|
370
|
-
|
|
371
|
-
dataset = "proofnetsharp"
|
|
372
|
-
split = "valid"
|
|
373
|
-
lean_version = "v4.8.0"
|
|
374
|
-
|
|
375
367
|
gen_config = default_goedelprover()
|
|
376
368
|
|
|
369
|
+
# MiniF2F benchmark
|
|
370
|
+
run_proof_generation_pipeline(
|
|
371
|
+
dataset_name="minif2f",
|
|
372
|
+
split="validation",
|
|
373
|
+
use_nl_proof_hint=False,
|
|
374
|
+
gen_config=gen_config,
|
|
375
|
+
lean_version="v4.8.0",
|
|
376
|
+
verbose=True,
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
# ProofNet# benchmark
|
|
377
380
|
run_proof_generation_pipeline(
|
|
378
|
-
dataset_name=
|
|
379
|
-
split=
|
|
381
|
+
dataset_name="proofnetsharp",
|
|
382
|
+
split="valid",
|
|
380
383
|
use_nl_proof_hint=False, # Set to True for proof autoformalization (only available for ProofNet#)
|
|
381
384
|
gen_config=gen_config,
|
|
382
|
-
lean_version=
|
|
385
|
+
lean_version="v4.8.0",
|
|
383
386
|
verbose=True,
|
|
384
387
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "lean-interact"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.3"
|
|
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" }
|
|
@@ -47,6 +47,7 @@ class LocalProject(BaseProject):
|
|
|
47
47
|
"""Use an existing local Lean project directory"""
|
|
48
48
|
|
|
49
49
|
directory: str
|
|
50
|
+
build: bool = True
|
|
50
51
|
|
|
51
52
|
def _get_directory(self, cache_dir: str, lean_version: str | None = None) -> str:
|
|
52
53
|
"""Get the project directory."""
|
|
@@ -54,12 +55,16 @@ class LocalProject(BaseProject):
|
|
|
54
55
|
|
|
55
56
|
def _instantiate(self, cache_dir: str, lean_version: str, verbose: bool = True):
|
|
56
57
|
"""Instantiate the local project."""
|
|
58
|
+
if not self.build:
|
|
59
|
+
return
|
|
57
60
|
stdout = None if verbose else subprocess.DEVNULL
|
|
58
61
|
stderr = None if verbose else subprocess.DEVNULL
|
|
59
62
|
|
|
60
63
|
with FileLock(f"{self.directory}.lock"):
|
|
61
64
|
try:
|
|
62
|
-
subprocess.run(
|
|
65
|
+
subprocess.run(
|
|
66
|
+
["lake", "exe", "cache", "get"], cwd=self.directory, check=False, stdout=stdout, stderr=stderr
|
|
67
|
+
)
|
|
63
68
|
subprocess.run(["lake", "build"], cwd=self.directory, check=True, stdout=stdout, stderr=stderr)
|
|
64
69
|
except subprocess.CalledProcessError as e:
|
|
65
70
|
logger.error("Failed to build local project: %s", e)
|
|
@@ -103,7 +108,9 @@ class GitProject(BaseProject):
|
|
|
103
108
|
repo.submodule_update(init=True, recursive=True)
|
|
104
109
|
|
|
105
110
|
try:
|
|
106
|
-
subprocess.run(
|
|
111
|
+
subprocess.run(
|
|
112
|
+
["lake", "exe", "cache", "get"], cwd=project_dir, check=False, stdout=stdout, stderr=stderr
|
|
113
|
+
)
|
|
107
114
|
subprocess.run(["lake", "build"], cwd=project_dir, check=True, stdout=stdout, stderr=stderr)
|
|
108
115
|
except subprocess.CalledProcessError as e:
|
|
109
116
|
logger.error("Failed to build the git project: %s", e)
|
|
@@ -238,7 +238,11 @@ class BaseREPLResponse(REPLBaseModel):
|
|
|
238
238
|
for message in self.messages
|
|
239
239
|
if message_intersects_code(message, start_pos, end_pos) and message.severity == "error"
|
|
240
240
|
]
|
|
241
|
-
sorries = [message for message in self.sorries if message_intersects_code(message, start_pos, end_pos)]
|
|
241
|
+
sorries = [message for message in self.sorries if message_intersects_code(message, start_pos, end_pos)] + [
|
|
242
|
+
message
|
|
243
|
+
for message in self.messages
|
|
244
|
+
if message_intersects_code(message, start_pos, end_pos) and message.data == "declaration uses 'sorry'"
|
|
245
|
+
]
|
|
242
246
|
return not errors and (allow_sorry or not sorries)
|
|
243
247
|
|
|
244
248
|
|
|
@@ -60,7 +60,10 @@ class TestFileLocks(unittest.TestCase):
|
|
|
60
60
|
def tearDown(self):
|
|
61
61
|
# Clean up temporary directory
|
|
62
62
|
if os.path.exists(self.temp_dir):
|
|
63
|
-
|
|
63
|
+
try:
|
|
64
|
+
shutil.rmtree(self.temp_dir)
|
|
65
|
+
except PermissionError:
|
|
66
|
+
pass
|
|
64
67
|
|
|
65
68
|
def test_config_repl_setup_lock(self):
|
|
66
69
|
"""Test that the REPL setup lock prevents concurrent access."""
|
|
@@ -110,7 +110,15 @@ class TestLeanServer(unittest.TestCase):
|
|
|
110
110
|
base_config = LeanREPLConfig(project=TempRequireProject("mathlib"), verbose=True)
|
|
111
111
|
new_config = LeanREPLConfig(project=LocalProject(base_config._working_dir), verbose=True)
|
|
112
112
|
server = AutoLeanServer(new_config)
|
|
113
|
-
server.run(Command(cmd="#eval Lean.versionString"), verbose=True)
|
|
113
|
+
response = server.run(Command(cmd="#eval Lean.versionString"), verbose=True)
|
|
114
|
+
self.assertIsInstance(response, CommandResponse)
|
|
115
|
+
# Re-use the existing build
|
|
116
|
+
with unittest.mock.patch("subprocess.run") as run_mock:
|
|
117
|
+
new_config = LeanREPLConfig(project=LocalProject(base_config._working_dir, build=False), verbose=True)
|
|
118
|
+
run_mock.assert_called_once() # it should be called only once (to build the REPL, but not the local project)
|
|
119
|
+
server = AutoLeanServer(new_config)
|
|
120
|
+
response = server.run(Command(cmd="#eval Lean.versionString"), verbose=True)
|
|
121
|
+
self.assertIsInstance(response, CommandResponse)
|
|
114
122
|
|
|
115
123
|
def test_temp_project_creation(self):
|
|
116
124
|
# Create a simple temporary project
|
|
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
|