Once you have built and certified an ExactProgram, you can serialize it to JSON for storage, transmission, or caching. b01t includes a round-trip serialization format called exact-oracle-v1 that captures the full program structure — registers, operations, ancilla discipline, and certification level — and re-validates all structural invariants on load.
Serializing an ExactProgram
Import the serialization functions from b01t:
from b01t import (
exact_program_to_json,
exact_program_from_json,
exact_program_to_dict,
exact_program_from_dict,
)
To JSON
from b01t import coherent, QReg, cx, z, Certification
from b01t import ancilla, compute, phase, uncompute
from b01t import exact_program_to_json
@coherent
def oracle(sys: QReg):
with ancilla(1) as anc:
compute(lambda: cx(sys[0], anc[0]))
phase(lambda: z(anc[0]))
uncompute()
prog = oracle.build_exact(("sys", 1))
json_str = exact_program_to_json(prog)
print(json_str)
exact_program_to_json() returns a deterministic, sorted-key JSON string. The output is always consistent for the same program.
To dict
If you need to embed the program data in a larger JSON object or manipulate it as a Python dictionary:
from b01t import exact_program_to_dict
data = exact_program_to_dict(prog)
print(data["format"]) # "exact-oracle-v1"
print(data["name"]) # "oracle"
print(data["certification"]) # "safe"
The serialized format uses the tag "exact-oracle-v1" in the "format" field. Here is an example of what the JSON looks like for the single-qubit oracle above:
{
"certification": "safe",
"format": "exact-oracle-v1",
"name": "oracle",
"ops": [
{
"ancilla": {
"kind": "anc",
"name": "anc0",
"size": 1
},
"compute": [
{
"gate": "CX",
"op": "gate",
"wires": [
{"index": 0, "kind": "sys", "reg": "sys"},
{"index": 0, "kind": "anc", "reg": "anc0"}
]
}
],
"middle": [
{
"gate": "Z",
"op": "gate",
"wires": [{"index": 0, "kind": "anc", "reg": "anc0"}]
}
],
"middle_kind": "phase",
"op": "ancilla",
"uncompute": [
{
"gate": "CX",
"op": "gate",
"wires": [
{"index": 0, "kind": "sys", "reg": "sys"},
{"index": 0, "kind": "anc", "reg": "anc0"}
]
}
]
}
],
"regs": [
{"kind": "sys", "name": "sys", "size": 1},
{"kind": "anc", "name": "anc0", "size": 1}
]
}
Each operation is tagged with "op": "gate" for a single gate, "ancilla" for an ancilla block, and "par" for parallel composition. Ancilla blocks include the "middle_kind" field — either "phase" for the CPU pattern or "apply" for the CMA pattern.
Deserializing
From JSON
from b01t import exact_program_from_json
restored = exact_program_from_json(json_str)
print(restored.name) # "oracle"
print(restored.certification) # Certification.SAFE
From dict
from b01t import exact_program_from_dict
restored = exact_program_from_dict(data)
Deserialization validates the "format" field. If it is missing or wrong, a DSLValidationError is raised:
DSLValidationError: unsupported exact oracle format: 'my-format' (expected 'exact-oracle-v1')
All structural invariants — wire declarations, ancilla discipline, gate classifications — are re-checked on load. A program that was safe when serialized is safe when restored.
Round-trip example
from b01t import coherent, QReg, cx, z, Certification
from b01t import ancilla, compute, phase, uncompute
from b01t import exact_program_to_json, exact_program_from_json
@coherent
def oracle(sys: QReg):
with ancilla(1) as anc:
compute(lambda: cx(sys[0], anc[0]))
phase(lambda: z(anc[0]))
uncompute()
# Build
prog = oracle.build_exact(("sys", 1))
assert prog.certification == Certification.SAFE
# Serialize
json_str = exact_program_to_json(prog)
# Deserialize
restored = exact_program_from_json(json_str)
# Verify
assert restored.name == prog.name
assert restored.certification == prog.certification
assert len(restored.ops) == len(prog.ops)
Managing collections with PackageRegistry
PackageRegistry lets you publish, save, and load a collection of programs. Each entry is a PackageMeta that holds a program alongside metadata like tags, version, and documentation.
from b01t import PackageRegistry, PackageMeta, Certification
from b01t import coherent, QReg, cx, z
from b01t import ancilla, compute, phase, uncompute
registry = PackageRegistry()
# Build a program
@coherent
def oracle(sys: QReg):
with ancilla(1) as anc:
compute(lambda: cx(sys[0], anc[0]))
phase(lambda: z(anc[0]))
uncompute()
prog = oracle.build_exact(("sys", 1))
# Publish it to the registry
registry.publish(PackageMeta(
name="oracle",
effect="coherent",
safe=True,
tags=["oracle", "phase"],
docs="Single-qubit phase oracle.",
inputs=[("sys", 1)],
exact_program=prog,
))
# Save the entire registry to a file
registry.save("my_programs.json")
Load the registry back later:
registry2 = PackageRegistry()
registry2.load("my_programs.json")
meta = registry2.get("oracle")
print(meta.exact_program.certification) # Certification.SAFE
The saved file is a JSON array. Each entry that has an exact_program includes it under the "exact_oracle" key in exact-oracle-v1 format, with full structural validation on load.
Use registry.find_by_tag("oracle") to retrieve all programs with a particular tag. This is useful when you have a collection of related circuits and want to filter by purpose.