Isabelle RPC Host: call Python functions from Isabelle/ML
Project description
Isabelle_RPC: Call Python from Isabelle/ML
Isabelle_RPC lets Isabelle/ML call Python functions via RPC. Communication flows Isabelle → Python (with callbacks). For Python → Isabelle, use Isa-REPL instead.
Quick Start
- Start the Python RPC server:
python Isabelle_RPC/launcher.py
- In your theory file:
imports Remote_Procedure_Calling
- Call Python procedures from ML code
Writing RPC Procedures (Python Side)
Basic Pattern
Register Python functions that Isabelle can call:
from Isabelle_RPC_Host import isabelle_remote_procedure, Connection
@isabelle_remote_procedure("my_function") # the registered procedure name
def my_function(arg, connection: Connection):
# arg: data sent from Isabelle
# connection: can be used for callbacks or logging
result = ... # Your process
return result # returned to Isabelle
Examples
@isabelle_remote_procedure("heartbeat")
def _heartbeat_(arg, connection: Connection) -> None:
connection.server.logger.info(f"Heartbeat from {connection.client_addr}")
return None
@isabelle_remote_procedure("compute_sum")
def _compute_sum(arg, connection: Connection) -> int:
# arg is a list of integers from ML
return sum(arg)
Calling RPC Procedures (Isabelle/ML Side)
Define a Command
Create a typed command specification with MessagePack schemas:
type ('a,'b) command = {
name : string, (* registered procedure name *)
arg_schema : 'a MessagePackBinIO.Pack.packer, (* argument schema *)
ret_schema : 'b MessagePackBinIO.Unpack.unpacker, (* return-value schema *)
callback : (connection -> unit) option, (* optional callback during call *)
timeout : Time.time option (* optional timeout *)
}
Examples:
open MessagePackBinIO.Pack MessagePackBinIO.Unpack
val heartbeat_cmd = {
name = "heartbeat",
arg_schema = packUnit,
ret_schema = unpackUnit,
callback = NONE,
timeout = SOME (Time.fromSeconds 10)
}
val compute_sum_cmd = {
name = "compute_sum", (* Must match @isabelle_remote_procedure("compute_sum") *)
arg_schema = packList packInt, (* Send list of integers *)
ret_schema = unpackInt, (* Receive integer result *)
callback = NONE,
timeout = SOME (Time.fromSeconds 30)
}
Call the Command
(* Using connection pool *)
val result = Remote_Procedure_Calling.call_command compute_sum_cmd [1, 2, 3, 4]
(* With explicit connection *)
val conn = Remote_Procedure_Calling.get_connection ()
val result = Remote_Procedure_Calling.call_command' compute_sum_cmd conn [1, 2, 3, 4]
val _ = Remote_Procedure_Calling.release_connection conn
Using Callbacks
Callbacks allow Python to call back into Isabelle during RPC execution. This enables bidirectional communication within a single RPC call.
Defining Callbacks (Isabelle/ML Side)
Define callbacks that Python can invoke:
open MessagePackBinIO.Pack MessagePackBinIO.Unpack
val my_callback : (string, int) Remote_Procedure_Calling.callback = {
name = "my_callback", (* callback identifier *)
arg_schema = unpackString, (* Python → ML schema *)
ret_schema = packInt, (* ML → Python schema *)
function = (fn msg => String.size msg), (* callback logic *)
timeout = NONE
}
(* Either register globally using Remote_Procedure_Calling.register_global_callback *)
val _ = Theory.setup (Context.theory_map
(Remote_Procedure_Calling.register_global_callback my_callback))
(* Or pass as local callback in command definition *)
val my_cmd : (unit, string) Remote_Procedure_Calling.command = {
name = "my_rpc",
arg_schema = packUnit,
ret_schema = unpackString,
callback = [Remote_Procedure_Calling.mk_callback my_callback], (* local *)
timeout = SOME (Time.fromSeconds 10)
}
Calling Callbacks (Python Side)
Invoke Isabelle callbacks from Python RPC procedures:
@isabelle_remote_procedure("my_rpc")
def my_rpc(arg, connection: Connection):
# Call back to Isabelle's "my_callback"
result = connection.callback("my_callback", "hello")
# result = 5 (length of "hello")
return f"Callback returned: {result}"
Advanced: For custom bidirectional protocols, define ML callbacks using callback' type directly (bypassing structured schemas) and invoke with connection.raw_callback(name, action) where action is a function receiving the connection for arbitrary I/O operations.
The built-in isabelle_heartbeat callback (RPC.ML:328) provides a working example. See contrib/Isabelle_RPC/test_callback.py for complete examples.
Common MessagePack Schemas
Packing (ML → Python)
packUnit- unit/NonepackString- stringpackInt- integerpackBool- booleanpackReal- floatpackList schema- listpackPair (s1, s2)- 2-tuplepackTuple3 (s1, s2, s3)- 3-tuplepackTuple3,packTuple4,packTuple5- up to 8-tuplepackOption schema- option/OptionalpackPairList (s1, s2)- list of pairs (dict items)
Unpacking (Python → ML)
unpackUnit- unit/NoneunpackString- stringunpackInt- integerunpackBool- booleanunpackReal- floatunpackList schema- listunpackPair (s1, s2)- 2-tupleunpackTuple3 (s1, s2, s3)- 3-tupleunpackTuple4,unpackTuple5- up to 6-tupleunpackOption schema- option/OptionalunpackPairList (s1, s2)- list of pairs (dict items)
Schema reference: Performant_Isabelle_ML/contrib/mlmsgpack/mlmsgpack.sml (relocated from Isabelle_RPC; loaded by the Performant_Isabelle_ML base session)
Server Configuration
- Default address:
127.0.0.1:27182 - Change address: Set
RPC_Hostenvironment variable (e.g.,export RPC_Host=127.0.0.1:9999) - Auto-launch: ML code auto-launches server if not running
- Protocol: MessagePack over TCP
Key Files Reference
Entry points:
Remote_Procedure_Calling.thy- Main theory filelauncher.py- Server startup script
Python server:
Isabelle_RPC_Host/__init__.py- Server implementation and procedure registration
ML client:
Tools/RPC.ML- Client implementation (signatureREMOTE_PROCEDURE_CALLING)
Relationship with Other Projects
- Isa-REPL: Python → Isabelle (opposite direction from RPC)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file isabelle_rpc-0.3.0.tar.gz.
File metadata
- Download URL: isabelle_rpc-0.3.0.tar.gz
- Upload date:
- Size: 30.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
622ee0fbb551bc77d7998e1026d6639a8bcf328fb36d62f009ef5d7cb6f02682
|
|
| MD5 |
076e49fa53111d6eb9baa5e3871e60cd
|
|
| BLAKE2b-256 |
a2ba19f2c736c00b37e335330ae723110576bb8ba2b6110f54ffb1187ee8db50
|
File details
Details for the file isabelle_rpc-0.3.0-py3-none-any.whl.
File metadata
- Download URL: isabelle_rpc-0.3.0-py3-none-any.whl
- Upload date:
- Size: 34.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e5936df660757425e8ea4cff307fa32e673a248e1b1afbc1b57a5de5d8c4ec3
|
|
| MD5 |
ad959aeb7ba25748ba1fb50712f5debc
|
|
| BLAKE2b-256 |
25724f1eef5586cf176f7fad4c90ededf1f39a1043e6997a84f5390a39c594a7
|