Pytanque is a Python API for lightweight communication with the Rocq proof assistant via coq-lsp.
- Pytanque is a lightweight Python client for Petanque
- Petanque is part of coq-lsp and provides a machine-to-machine protocol based on JSON-RPC to communicate with the Rocq prover.
- pet-server/pet are the commands that start a Petanque server which can interpret requests for the Rocq prover
- Two communication modes: Socket mode (via
pet-server) for multi-client usage or stdio mode (viapet) for single-client simplicity - Interactive theorem proving: Execute tactics and commands step by step
- Comprehensive feedback: Access all Rocq messages (errors, warnings, search results)
- State management: Navigate proof states and compare them
- AST parsing: Get abstract syntax trees for commands and file positions (only with the dev version of coq-lsp)
- Position-based queries: Get states at specific file positions (only with the dev version of coq-lsp)
First, install coq-lsp with the required dependencies:
# Install dependencies
opam install lwt logs coq-lsp
# Or install one of the dev versions of coq-lsp, e.g., for Coq.8.20
opam install lwt logs coq.8.20.0
opam pin add coq-lsp https://github.com/ejgallego/coq-lsp.git#v8.20pip install git+https://github.com/llm4rocq/pytanque.gitWe recommend using uv.
- Clone this repository
- Use the project workflow:
cd pytanque uv sync
Pytanque supports two communication modes with the Petanque backend:
$ pet-server # Default port: 8765
# Or specify a custom port:
$ pet-server -p 9000from pytanque import Pytanque
with Pytanque("127.0.0.1", 8765) as client:
# Start a proof
state = client.start("./examples/foo.v", "addnC")
print(f"Initial state: {state.st}, finished: {state.proof_finished}")
# Execute tactics step by step
state = client.run(state, "induction n.", verbose=True)
state = client.run(state, "auto.", verbose=True)
# Check current goals
goals = client.goals(state)
print(f"Current goals: {len(goals)}")You can quickly try this example with:
# Socket mode example
python examples/foo.pySee also the notebook examples/getting_started.ipynb for more examples.
For direct communication without a server, use subprocess mode:
from pytanque import Pytanque
with Pytanque(stdio=True) as client:
# Same API as socket mode
state = client.start("./examples/foo.v", "addnC")
print(f"Initial state: {state.st}, finished: {state.proof_finished}")
# Execute tactics step by step
state = client.run(state, "induction n.", verbose=True)
state = client.run(state, "auto.", verbose=True)
# Check current goals
goals = client.goals(state)
print(f"Current goals: {len(goals)}")start(file, theorem): Begin a proof sessionrun(state, command): Execute tactics or commandsgoals(state): Get current proof goalspremises(state): Get available premises/lemmas
get_root_state(file): Get initial document statestate_equal(st1, st2, kind): Compare proof statesstate_hash(state): Get state hashtoc(file): Get table of contentsast(state, text): Parse command to AST (only with the dev version of coq-lsp)ast_at_pos(file, line, char): Get AST at file position (only with the dev version of coq-lsp)get_state_at_pos(file, line, char): Get proof state at position (only with the dev version of coq-lsp)
All commands return states with feedback containing Rocq messages:
state = client.run(state, "Search nat.")
for level, message in state.feedback:
print(f"Level {level}: {message}")First install dev dependencies for testing:
uv sync --devYou can launch all the tests with pytest. The test suite includes tests for both communication modes:
# Run all tests (socket + subprocess modes)
uv run pytest -v .
# Run only socket mode tests
uv run pytest tests/test_unit.py tests/test_integration.py -v
# Run only stdio mode tests
uv run pytest tests/test_stdio.py -vNote: Socket mode tests require pet-server to be running. Subprocess mode tests require the pet command to be available in PATH.
The complete API documentation is available at: https://llm4rocq.github.io/pytanque
To build the documentation locally:
# Install documentation dependencies
uv sync --extra docs
# Build the documentation
cd docs
uv run sphinx-build -b html . _build/html
# Open the documentation
open _build/html/index.htmlWe use atdpy to automatically generate serializers/deserializers from protocol type definitions. These types definition should match the ocaml code of petanque in coq-lsp.
To add a new method:
- Add type definitions in
protocol.atd - Run
atdpy protocol.atdto generateprotocol.py - Update
client.pywith the new method
Socket Mode Connection Errors
- Ensure
pet-serveris running:pet-server -p 8765 - Verify port availability and network connectivity
- Check firewall settings if connecting remotely
Subprocess Mode Errors
- Ensure
petcommand is available in PATH:which pet - Verify coq-lsp installation includes the
petbinary - Check that the
petprocess can access your Rocq/Coq files
File Path Issues
- Use absolute paths or ensure working directory is correct
- Check file exists and has proper Coq/Rocq syntax
- Ensure workspace is set correctly with
client.set_workspace()
Installation Issues
- Ensure coq-lsp is properly installed with both
petandpet-server - Install
lwtandlogsbeforecoq-lsp(required for both modes) - Verify installation:
pet --versionandpet-server --version
Performance Considerations
- Socket mode: Better for multiple clients or long-running sessions
- Subprocess mode: Better for single-client usage or automation
- Choose the appropriate mode based on your use case