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.
Files changed (20) hide show
  1. {lean_interact-0.5.2 → lean_interact-0.5.3}/PKG-INFO +8 -4
  2. {lean_interact-0.5.2 → lean_interact-0.5.3}/README.md +7 -3
  3. {lean_interact-0.5.2 → lean_interact-0.5.3}/examples/proof_generation_and_autoformalization.py +15 -12
  4. {lean_interact-0.5.2 → lean_interact-0.5.3}/pyproject.toml +1 -1
  5. {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/config.py +9 -2
  6. {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/interface.py +5 -1
  7. {lean_interact-0.5.2 → lean_interact-0.5.3}/tests/test_concurrency.py +4 -1
  8. {lean_interact-0.5.2 → lean_interact-0.5.3}/tests/test_server.py +9 -1
  9. {lean_interact-0.5.2 → lean_interact-0.5.3}/.devcontainer/devcontainer.json +0 -0
  10. {lean_interact-0.5.2 → lean_interact-0.5.3}/.github/workflows/ci.yml +0 -0
  11. {lean_interact-0.5.2 → lean_interact-0.5.3}/.github/workflows/publish-to-pypi.yml +0 -0
  12. {lean_interact-0.5.2 → lean_interact-0.5.3}/.gitignore +0 -0
  13. {lean_interact-0.5.2 → lean_interact-0.5.3}/LICENSE +0 -0
  14. {lean_interact-0.5.2 → lean_interact-0.5.3}/examples/beq_plus.py +0 -0
  15. {lean_interact-0.5.2 → lean_interact-0.5.3}/examples/type_check.py +0 -0
  16. {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/__init__.py +0 -0
  17. {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/server.py +0 -0
  18. {lean_interact-0.5.2 → lean_interact-0.5.3}/src/lean_interact/utils.py +0 -0
  19. {lean_interact-0.5.2 → lean_interact-0.5.3}/tests/test_utils.py +0 -0
  20. {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.2
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) (Tip: use the `install-lean` command from LeanInteract)
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. **(Windows) Path too long error**: Windows has a maximum path length limitation of 260 characters.
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/lean-interact},
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) (Tip: use the `install-lean` command from LeanInteract)
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. **(Windows) Path too long error**: Windows has a maximum path length limitation of 260 characters.
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/lean-interact},
485
+ url = {https://github.com/augustepoiroux/LeanInteract},
482
486
  year = {2025}
483
487
  }
484
488
  ```
@@ -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=lambda x: len(x))
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=dataset,
379
- split=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=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.2"
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(["lake", "exe", "cache", "get"], cwd=self.directory, check=False, stdout=stdout, stderr=stderr)
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(["lake", "exe", "cache", "get"], cwd=project_dir, check=False, stdout=stdout, stderr=stderr)
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
- shutil.rmtree(self.temp_dir)
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