pub struct Bloq { /* private fields */ }Expand description
The compiled bloq circuit IR: a graph of quantum, classical, and region
nodes produced by bloq_compile, consumed by emitters and the verifier.
The top level is a SubGraph — the same graph-level type region bodies
use — so every read accessor (SubGraph::node, SubGraph::nodes,
SubGraph::incoming, …) works uniformly at any nesting level. Bloq
delegates the common calls and adds whole-program state (templates,
frames, provenance) plus recursive traversal (Bloq::walk,
Bloq::levels).
Cloning shares graph levels, quantum payloads, and templates; edits detach the affected storage. Metadata and populated layout caches are still copied.
Implementations§
Source§impl Bloq
impl Bloq
Sourcepub fn to_binary(&self) -> Vec<u8> ⓘ
pub fn to_binary(&self) -> Vec<u8> ⓘ
Encode this program as a binary .bloq artifact.
§Panics
Panics if the in-memory IR violates postcard’s sequence contract.
Sourcepub fn from_binary(bytes: &[u8]) -> Result<Self, BinaryDecodeError>
pub fn from_binary(bytes: &[u8]) -> Result<Self, BinaryDecodeError>
Decode a binary .bloq artifact.
Decoding rejects structurally malformed payloads (trailing bytes,
duplicate node ids, dangling edges, an implausibly sparse node-id
space, unsorted registry/PauliMap entries) but does not check IR
semantics — run Bloq::validate on untrusted input.
§Errors
Returns BinaryDecodeError for an invalid header, unsupported
version, malformed payload, or trailing data.
Source§impl Bloq
impl Bloq
Sourcepub fn insert_memory_rounds(
&mut self,
target: MemoryRoundTarget,
rounds: u32,
) -> Result<BloqNodeId, EditError>
pub fn insert_memory_rounds( &mut self, target: MemoryRoundTarget, rounds: u32, ) -> Result<BloqNodeId, EditError>
Insert physical memory rounds at a level-qualified quantum edge or after a region body’s terminal quantum node.
Templates come from compiler-recorded padding provenance, so the edit
works on a deserialized program without its source graph. The edit is
transactional: any error leaves self unchanged.
§Errors
Returns EditError when the target or stored seam provenance is
invalid, membership is unresolved, or rounds is zero.
Sourcepub fn set_template_repetitions(
&mut self,
template: TemplateId,
repetitions: u32,
) -> Result<(), EditError>
pub fn set_template_repetitions( &mut self, template: TemplateId, repetitions: u32, ) -> Result<(), EditError>
Retune a template’s bulk duration: rewrite the repetition count of its
single top-level REPEAT.
This is how a compiled program’s memory-round budget is changed without recompiling, and it is a structural rewrite: neither the template’s side tables nor its boundary flows depend on the repetition count (a loop’s recurrence is stated per iteration), so nothing else has to move. Measurement ids are per body, not per iteration, so the program’s measurement registry is unaffected too.
Templates are pooled and shared, so every instance of template
changes with it. That is usually the point — one cube kind, one bulk
duration — but a caller that means to retune only some placements must
check the sharing itself; this call cannot tell the two intents apart.
§Errors
Returns EditError::UnknownTemplate for an id outside the pool, and
EditError::TemplateNotSingleLooped when the template’s entry body
has anything other than exactly one top-level REPEAT — with zero
there is no loop to retune, and with several the call would silently
mean “all of them”.
§Panics
Panics only if a template disappears after it is read from the pool.
Sourcepub fn insert_memory_rounds_batch(
&mut self,
targets: &[MemoryRoundTarget],
rounds: u32,
) -> Result<Vec<BloqNodeId>, EditError>
pub fn insert_memory_rounds_batch( &mut self, targets: &[MemoryRoundTarget], rounds: u32, ) -> Result<Vec<BloqNodeId>, EditError>
Insert memory rounds at every target or at none, returning node ids in target order. Targets may mix edges and terminal nodes at any level. An empty target list is a no-op, but zero rounds is always rejected.
§Errors
Returns EditError if membership is unresolved, any target or seam
is invalid, or rounds is zero. Any error leaves self unchanged.
Editing a clone and swapping on success costs one clone for the whole
batch, where looping over the public Bloq::insert_memory_rounds
would clone once per target and leave the earlier targets padded when
a later one fails. Targets are applied in order. A duplicate or overlapping
target that becomes invalid also rolls back the whole batch.
Sourcepub fn subdivide_quantum_edge(
&mut self,
from: BloqNodeId,
to: BloqNodeId,
padding: &[PaddingInstance],
rounds: u32,
) -> Result<BloqNodeId, EditError>
pub fn subdivide_quantum_edge( &mut self, from: BloqNodeId, to: BloqNodeId, padding: &[PaddingInstance], rounds: u32, ) -> Result<BloqNodeId, EditError>
Splice padding into from -> to, producing from -> padding -> to.
Before mutation, this allocates fresh instance ids and verifies the
original stored seam entries before recomposing both replacement
halves. Partial seams leaving a merge may move closures between nodes
and retarget output-face operators; full-node seams preserve side-table
entries one-for-one. rounds is recorded as memory-padding provenance
on the new node.
Returns the new padding node id. Re-resolve node ids held across this call because vacant slots may be recycled.
§Errors
Returns EditError when the seam, padding instances, or stored
detector composition is invalid.
Source§impl Bloq
impl Bloq
Sourcepub fn flatten(&mut self) -> Result<(), FlattenError>
pub fn flatten(&mut self) -> Result<(), FlattenError>
Flatten every repeat block in the program (see the module docs):
each template an instance references is flattened once via
BloqTemplate::flatten (flattened copies are appended to the pool —
it is append-only — and instances re-pointed), expanding repeat-scoped
detectors into per-iteration detectors and clearing all loop-carried
detector state. Instance-space side tables (node detectors,
observable record reads, boundary operators) stay valid untouched because
final occurrences keep their measurement ids.
Verify-before-apply: all templates are flattened and all checks run before any instance is re-pointed, so the program is unmodified on error. Decoder-wait insertion after flattening splices looped padding templates again; flatten again afterwards if needed.
§Errors
See FlattenError.
Sourcepub fn flatten_with_limits(
&mut self,
limits: FlattenLimits,
) -> Result<(), FlattenError>
pub fn flatten_with_limits( &mut self, limits: FlattenLimits, ) -> Result<(), FlattenError>
Self::flatten with a cumulative allowance across all distinct
referenced templates and their side tables. Repeated instances share
one flattened template; an exhausted allowance leaves the Bloq intact.
§Errors
Returns FlattenError for invalid references or exhausted cumulative
work; self remains unchanged.
Source§impl Bloq
impl Bloq
Sourcepub fn node_detector_count(
&self,
node: &QuantumNode,
) -> Result<usize, DetectorBundleError>
pub fn node_detector_count( &self, node: &QuantumNode, ) -> Result<usize, DetectorBundleError>
Count inline and bound detector rows after checking local bundle structure.
§Errors
Returns a DetectorBundleError for a missing bundle, invalid binding,
invalid local owner slot, or a count/address overflow.
Sourcepub fn check_detector_bundle_bindings(
&self,
node: &QuantumNode,
lookup: impl FnMut(TemplateInstanceId) -> Option<TemplateId>,
) -> Result<(), DetectorBundleError>
pub fn check_detector_bundle_bindings( &self, node: &QuantumNode, lookup: impl FnMut(TemplateInstanceId) -> Option<TemplateId>, ) -> Result<(), DetectorBundleError>
Check every bundle owner binding against a caller’s instance registry.
§Errors
Returns local structure errors from Self::node_detector_count, or
DetectorBundleError::UnknownBoundInstance / DetectorBundleError::OwnerTemplateMismatch
when the supplied registry does not match a bundle’s owner signature.
Sourcepub fn node_detectors<'a>(
&'a self,
node: &'a QuantumNode,
) -> Result<NodeDetectors<'a>, DetectorBundleError>
pub fn node_detectors<'a>( &'a self, node: &'a QuantumNode, ) -> Result<NodeDetectors<'a>, DetectorBundleError>
Borrow node detectors in inline, bundle-use, and bundle-row order.
§Errors
Returns the same structural errors as Self::node_detector_count.
Source§impl Bloq
impl Bloq
Sourcepub fn set_logical_inputs(&mut self, inputs: Vec<LogicalInput>)
pub fn set_logical_inputs(&mut self, inputs: Vec<LogicalInput>)
Replace the logical-input metadata.
Sourcepub fn logical_inputs(&self) -> &[LogicalInput]
pub fn logical_inputs(&self) -> &[LogicalInput]
Logical input patches in deterministic source-port order.
Sourcepub fn output_frames(&self) -> Vec<FramePair>
pub fn output_frames(&self) -> Vec<FramePair>
The per-output terminal Pauli-frame signs: one FramePair per
source output port, in (x, y, z) order. Derived from the
NodeProvenance::OutputFrame stamps on frame-sign Compute nodes —
the stamps are the single source of truth, so this table cannot drift
from the graph. Validation guarantees every stamped output carries
exactly one X and one Z stamp; on an unvalidated program an incomplete
pair is skipped.
Sourcepub fn set_logical_outputs(&mut self, outputs: Vec<LogicalOutput>)
pub fn set_logical_outputs(&mut self, outputs: Vec<LogicalOutput>)
Replace the terminal logical-output metadata.
Sourcepub fn logical_outputs(&self) -> &[LogicalOutput]
pub fn logical_outputs(&self) -> &[LogicalOutput]
Terminal logical operators in deterministic output order.
Source§impl Bloq
impl Bloq
Sourcepub fn top(&self) -> &SubGraph
pub fn top(&self) -> &SubGraph
The top graph level. Region bodies are further SubGraph levels,
reached through crate::RegionNode::bodies or Bloq::levels.
Sourcepub fn top_mut(&mut self) -> &mut SubGraph
pub fn top_mut(&mut self) -> &mut SubGraph
Mutable top graph level.
This invalidates derived layout data because arbitrary graph edits may change the program’s qubit footprint.
Sourcepub fn metadata(&self) -> &BTreeMap<String, MetadataValue>
pub fn metadata(&self) -> &BTreeMap<String, MetadataValue>
Producer-specific provenance, keyed by a namespaced stable name.
Sourcepub fn insert_metadata(
&mut self,
key: impl Into<String>,
value: impl Into<MetadataValue>,
) -> Option<MetadataValue>
pub fn insert_metadata( &mut self, key: impl Into<String>, value: impl Into<MetadataValue>, ) -> Option<MetadataValue>
Insert producer metadata, returning the previous value for key.
Sourcepub fn pipe_padding(&self) -> impl Iterator<Item = &PipePadding>
pub fn pipe_padding(&self) -> impl Iterator<Item = &PipePadding>
Every edge-owned memory-padding record in the program.
Sourcepub fn add_template(&mut self, template: BloqTemplate) -> TemplateId
pub fn add_template(&mut self, template: BloqTemplate) -> TemplateId
Add an owned template and return its id.
§Panics
Panics before insertion if the next template id exceeds u32.
Add a shared template and return its id.
§Panics
Panics before insertion if the next template id exceeds u32.
Sourcepub fn templates(&self) -> &BloqTemplatePool
pub fn templates(&self) -> &BloqTemplatePool
Program template pool.
Sourcepub fn detector_bundles(&self) -> &DetectorBundlePool
pub fn detector_bundles(&self) -> &DetectorBundlePool
Reusable detector bundle pool.
Sourcepub fn add_detector_bundle(
&mut self,
bundle: DetectorBundle,
) -> DetectorBundleId
pub fn add_detector_bundle( &mut self, bundle: DetectorBundle, ) -> DetectorBundleId
Add owned detector rows to the shared bundle pool.
§Panics
Panics before insertion if the next bundle id exceeds u32.
Import an immutable shared detector bundle.
§Panics
Panics before insertion if the next bundle id exceeds u32.
Sourcepub fn add_node(&mut self, node: BloqNode) -> BloqNodeId
pub fn add_node(&mut self, node: BloqNode) -> BloqNodeId
Add a top-level node and return its id.
Sourcepub fn add_edge(&mut self, from: BloqNodeId, to: BloqNodeId, edge: BloqEdge)
pub fn add_edge(&mut self, from: BloqNodeId, to: BloqNodeId, edge: BloqEdge)
Adds a top-level edge; panics on a stale endpoint id, like
SubGraph::add_edge.
Sourcepub fn node_mut(&mut self, id: BloqNodeId) -> Option<&mut BloqNode>
pub fn node_mut(&mut self, id: BloqNodeId) -> Option<&mut BloqNode>
Mutable top-level node lookup.
Sourcepub fn remove_node(&mut self, id: BloqNodeId) -> Option<BloqNode>
pub fn remove_node(&mut self, id: BloqNodeId) -> Option<BloqNode>
Remove a top-level node and its incident edges.
Sourcepub fn quantum_node_count(&self) -> usize
pub fn quantum_node_count(&self) -> usize
The number of top-level quantum nodes. Unlike Self::node_count this
excludes the classical Observable nodes, so it
stays a stable measure of lowered blocks for perf tracking.
Sourcepub fn qubit_count(&self) -> Result<usize, CoordinateOverflowError>
pub fn qubit_count(&self) -> Result<usize, CoordinateOverflowError>
The number of distinct physical qubit coordinates in the layout.
§Errors
Returns CoordinateOverflowError if translating an instance qubit
exceeds the coordinate lattice.
Sourcepub fn sorted_layout_coords(&self) -> Result<&[IVec2], CoordinateOverflowError>
pub fn sorted_layout_coords(&self) -> Result<&[IVec2], CoordinateOverflowError>
The program’s distinct layout qubit coordinates, sorted by (x, y).
Computed once and cached; the cache is cleared on any mutation.
§Errors
Returns CoordinateOverflowError if an instance offset would move a
template qubit outside the i32 coordinate lattice.
Sourcepub fn node_qubits(
&self,
node: &BloqNode,
) -> Result<FxHashSet<IVec2>, CoordinateOverflowError>
pub fn node_qubits( &self, node: &BloqNode, ) -> Result<FxHashSet<IVec2>, CoordinateOverflowError>
The layout qubits a node occupies: each instance’s template qubits translated by the instance offset. Instances pointing at a missing template are skipped.
§Errors
Returns CoordinateOverflowError if an instance offset would move a
template qubit outside the i32 coordinate lattice.
Sourcepub fn node_measurement_count(&self, node: &BloqNode) -> usize
pub fn node_measurement_count(&self, node: &BloqNode) -> usize
The number of static measurement sites in a node and its nested bodies. RUS bodies contribute; this is not a runtime execution count.
Sourcepub fn measurement_count(&self) -> usize
pub fn measurement_count(&self) -> usize
The number of static measurement sites in the program.
Source§impl Bloq
impl Bloq
Sourcepub fn node(&self, id: BloqNodeId) -> Option<&BloqNode>
pub fn node(&self, id: BloqNodeId) -> Option<&BloqNode>
The top level’s SubGraph::node. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn node_ids(&self) -> impl DoubleEndedIterator<Item = BloqNodeId> + '_
pub fn node_ids(&self) -> impl DoubleEndedIterator<Item = BloqNodeId> + '_
The top level’s SubGraph::node_ids. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn nodes(
&self,
) -> impl DoubleEndedIterator<Item = (BloqNodeId, &BloqNode)> + '_
pub fn nodes( &self, ) -> impl DoubleEndedIterator<Item = (BloqNodeId, &BloqNode)> + '_
The top level’s SubGraph::nodes. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn quantum_nodes(
&self,
) -> impl Iterator<Item = (BloqNodeId, &QuantumNode)> + '_
pub fn quantum_nodes( &self, ) -> impl Iterator<Item = (BloqNodeId, &QuantumNode)> + '_
The top level’s SubGraph::quantum_nodes. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
The top level’s SubGraph::node_count. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn edge_count(&self) -> usize
pub fn edge_count(&self) -> usize
The top level’s SubGraph::edge_count. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn edges(&self) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
pub fn edges(&self) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
The top level’s SubGraph::edges. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn incoming(
&self,
id: BloqNodeId,
) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
pub fn incoming( &self, id: BloqNodeId, ) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
The top level’s SubGraph::incoming. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn outgoing(
&self,
id: BloqNodeId,
) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
pub fn outgoing( &self, id: BloqNodeId, ) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
The top level’s SubGraph::outgoing. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn edges_between(
&self,
from: BloqNodeId,
to: BloqNodeId,
) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
pub fn edges_between( &self, from: BloqNodeId, to: BloqNodeId, ) -> impl Iterator<Item = BloqEdgeRef<'_>> + '_
The top level’s SubGraph::edges_between. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn has_path(&self, from: BloqNodeId, to: BloqNodeId) -> bool
pub fn has_path(&self, from: BloqNodeId, to: BloqNodeId) -> bool
The top level’s SubGraph::has_path. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn path_scratch(&self) -> PathScratch
pub fn path_scratch(&self) -> PathScratch
The top level’s SubGraph::path_scratch. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn has_path_with_scratch(
&self,
from: BloqNodeId,
to: BloqNodeId,
scratch: &mut PathScratch,
) -> bool
pub fn has_path_with_scratch( &self, from: BloqNodeId, to: BloqNodeId, scratch: &mut PathScratch, ) -> bool
The top level’s SubGraph::has_path_with_scratch. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn value_inputs(
&self,
id: BloqNodeId,
) -> impl Iterator<Item = ValueInput<'_>> + '_
pub fn value_inputs( &self, id: BloqNodeId, ) -> impl Iterator<Item = ValueInput<'_>> + '_
The top level’s SubGraph::value_inputs. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn data_inputs(
&self,
id: BloqNodeId,
) -> impl Iterator<Item = ValueInput<'_>> + '_
pub fn data_inputs( &self, id: BloqNodeId, ) -> impl Iterator<Item = ValueInput<'_>> + '_
The top level’s SubGraph::data_inputs. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn data_consumers(
&self,
id: BloqNodeId,
) -> impl Iterator<Item = (BloqNodeId, u32)> + '_
pub fn data_consumers( &self, id: BloqNodeId, ) -> impl Iterator<Item = (BloqNodeId, u32)> + '_
The top level’s SubGraph::data_consumers. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn compose_consumers(
&self,
id: BloqNodeId,
) -> impl Iterator<Item = (BloqNodeId, u32)> + '_
pub fn compose_consumers( &self, id: BloqNodeId, ) -> impl Iterator<Item = (BloqNodeId, u32)> + '_
The top level’s SubGraph::compose_consumers. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn value_consumers(
&self,
id: BloqNodeId,
) -> impl Iterator<Item = (BloqNodeId, u32)> + '_
pub fn value_consumers( &self, id: BloqNodeId, ) -> impl Iterator<Item = (BloqNodeId, u32)> + '_
The top level’s SubGraph::value_consumers. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn open_value_producers(&self) -> impl Iterator<Item = BloqNodeId> + '_
pub fn open_value_producers(&self) -> impl Iterator<Item = BloqNodeId> + '_
The top level’s SubGraph::open_value_producers. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn open_bit_producers(&self) -> impl Iterator<Item = BloqNodeId> + '_
pub fn open_bit_producers(&self) -> impl Iterator<Item = BloqNodeId> + '_
The top level’s SubGraph::open_bit_producers. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn value_output(&self) -> Option<ValueRef>
pub fn value_output(&self) -> Option<ValueRef>
The top level’s SubGraph::value_output. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn boundary_outputs(&self) -> &[BloqNodeId]
pub fn boundary_outputs(&self) -> &[BloqNodeId]
The top level’s SubGraph::boundary_outputs. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn is_acyclic(&self) -> bool
pub fn is_acyclic(&self) -> bool
The top level’s SubGraph::is_acyclic. Region body levels are reached through Bloq::levels / Bloq::level_at.
Sourcepub fn is_acyclic_with_edges(&self, extra: &[(BloqNodeId, BloqNodeId)]) -> bool
pub fn is_acyclic_with_edges(&self, extra: &[(BloqNodeId, BloqNodeId)]) -> bool
The top level’s SubGraph::is_acyclic_with_edges. Region body levels are reached through Bloq::levels / Bloq::level_at.
Source§impl Bloq
impl Bloq
Sourcepub fn deterministic_emit_order(&self) -> Result<Vec<BloqNodeId>, CycleDetected>
pub fn deterministic_emit_order(&self) -> Result<Vec<BloqNodeId>, CycleDetected>
The top level’s deterministic topological emission order.
§Errors
Returns CycleDetected if the top-level graph contains a cycle.
Source§impl Bloq
impl Bloq
Sourcepub fn stable_key_map(
&self,
) -> Result<BTreeMap<NodeKey, BloqNodeId>, CycleDetected>
pub fn stable_key_map( &self, ) -> Result<BTreeMap<NodeKey, BloqNodeId>, CycleDetected>
The top level’s stable keys as a lookup
table, for resolving a key obtained from another program into a node id
in this one.
§Errors
Returns CycleDetected when the program has no emit order.
Source§impl Bloq
impl Bloq
Sourcepub fn optimize(&mut self) -> Result<(), CycleDetected>
pub fn optimize(&mut self) -> Result<(), CycleDetected>
Fuse computations and compatible observable recipes, then keep only the contributor frontier of observable ordering dependencies per level. Acyclicity is checked before any rewrite.
§Errors
Returns CycleDetected without rewriting anything if any level has
a cycle.
Source§impl Bloq
impl Bloq
Sourcepub fn pin_membership(
&self,
choices: &BTreeMap<String, bool>,
) -> Result<Self, MembershipPinError>
pub fn pin_membership( &self, choices: &BTreeMap<String, bool>, ) -> Result<Self, MembershipPinError>
Pin named structural branches and selective-measurement outcomes. The returned program retains selected instance ids, record aliases, and signed flow recipes. Guards implied by the joint choices are removed; unresolved predicates and RUS retries retain their runtime semantics.
Every source selector must be pinned, and the joint tuple must be
consistent with its Boolean dataflow. self remains unchanged.
§Errors
Returns MembershipPinError for cyclic dataflow, missing or ambiguous
choices, contradictory assignments, or malformed membership data.
Call Self::validate explicitly to audit all IR well-formedness rules.
Sourcepub fn has_conditional_membership(&self) -> bool
pub fn has_conditional_membership(&self) -> bool
Whether quantum stages, seams, or quantum-containing region activations have conditional membership. Static emission and slicing require selection; timing and memory edits also support exhaustive terminal choices. Classical activation only gates a recipe; it does not change membership.
Source§impl Bloq
impl Bloq
Sourcepub fn regions_of(&self, kind: RegionKind) -> Vec<RegionRef>
pub fn regions_of(&self, kind: RegionKind) -> Vec<RegionRef>
Every region node of kind, at every nesting level.
Ordered by Bloq::levels: levels pre-order top-down, ascending node
id within a level. Filter on RegionRef::path being
top-level when only the outermost regions
matter.
Sourcepub fn selection_seams(
&self,
) -> Result<Vec<(BloqNodeId, BloqNodeId)>, StructureError>
pub fn selection_seams( &self, ) -> Result<Vec<(BloqNodeId, BloqNodeId)>, StructureError>
The quantum seams each top-level guarded component waits on, as
(source, selection) pairs in ascending selection-node-id order.
Subdividing those edges (Bloq::insert_memory_rounds_batch) delays the
component until its guard inputs are ready. Within one component, seams
are ordered by source node id. This query does not certify that an
unresolved selection supports scheduling or memory edits.
§Errors
Returns StructureError::SelectionInputMissing if a guarded component has no
incoming quantum edge.
Sourcepub fn node_by_block(&self, pos: IVec3) -> Option<BloqNodeId>
pub fn node_by_block(&self, pos: IVec3) -> Option<BloqNodeId>
The top-level node realizing source block pos, or None when no node
carries it.
Lowering partitions the source blocks across
NodeProvenance::BlockComponent
nodes, so at most one node can match — this is a lookup, not a search
with a preferred answer.
Source§impl Bloq
impl Bloq
Sourcepub fn resolve_classical(
&self,
node: BloqNodeId,
assignment: ClassicalAssignment<'_>,
) -> Result<ClassicalResolution, ResolveError>
pub fn resolve_classical( &self, node: BloqNodeId, assignment: ClassicalAssignment<'_>, ) -> Result<ClassicalResolution, ResolveError>
The physical-measurement and decoder-flip recipe behind a top-level classical node’s value, folded under a fixed path.
Follows the node’s Value inputs recursively, descending into a region
under assignment and out through that body’s declared
bit result (SEM-RVAL). Observable fragments and complete observables
contribute measurements; Const leaves contribute sign. An observable
also contributes its named decoder flip on its Corrected output;
composition includes only its recipe.
§Errors
Returns ResolveError when the path does not determine a region or
nonlinear cofactor, or when the fold reaches a node with no static value
(a quantum node or a Discard).
Sourcepub fn resolve_value(
&self,
value: ValueRef,
assignment: ClassicalAssignment<'_>,
) -> Result<ClassicalResolution, ResolveError>
pub fn resolve_value( &self, value: ValueRef, assignment: ClassicalAssignment<'_>, ) -> Result<ClassicalResolution, ResolveError>
Resolve a selected runtime output under a fixed path.
§Errors
Returns the same errors as Self::resolve_classical.
Sourcepub fn measurement_dependencies(
&self,
node: BloqNodeId,
assignment: ClassicalAssignment<'_>,
) -> Result<BTreeSet<InstanceMeasurement>, ResolveError>
pub fn measurement_dependencies( &self, node: BloqNodeId, assignment: ClassicalAssignment<'_>, ) -> Result<BTreeSet<InstanceMeasurement>, ResolveError>
Which measurement records node’s value waits on, rather than what
parity it is.
Unlike the parity fold, this conservatively unions all record dependencies, including records needed for Flip outputs and nonlinear expressions.
§Errors
Returns the same errors as Self::resolve_classical.
Sourcepub fn measurement_value_dependencies(
&self,
value: ValueRef,
assignment: ClassicalAssignment<'_>,
) -> Result<BTreeSet<InstanceMeasurement>, ResolveError>
pub fn measurement_value_dependencies( &self, value: ValueRef, assignment: ClassicalAssignment<'_>, ) -> Result<BTreeSet<InstanceMeasurement>, ResolveError>
Measurement dependencies of a selected runtime output, including Flip.
§Errors
Returns the same errors as Self::measurement_dependencies.
Sourcepub fn classical_value(
&self,
node: BloqNodeId,
assignment: ClassicalAssignment<'_>,
) -> Result<bool, ResolveError>
pub fn classical_value( &self, node: BloqNodeId, assignment: ClassicalAssignment<'_>, ) -> Result<bool, ResolveError>
The bit a top-level node already takes on a fixed path.
Where Self::resolve_classical answers which measurements a value
is assembled from, this answers what that value is — for the nodes a
path determines offline, with no per-shot record involved. A
Observable reads its corrected bit from the path’s
forced_observables, and a Compute folds its own expression over
those leaves.
Under ClassicalAssignment::Uniform every predicate leaf folds to
the uniform bit, matching how a uniform path fixes predicate inputs.
§Errors
Returns ResolveError when the node is quantum, when it is a
RepeatUntilSuccess region (whose restart predicate is per-attempt
decoder state, not a path constant), or when the fold reaches a node
the path does not fix — a fragment’s per-shot record, or an
observable with no forced value.
Sourcepub fn classical_ref_value(
&self,
value: ValueRef,
assignment: ClassicalAssignment<'_>,
) -> Result<bool, ResolveError>
pub fn classical_ref_value( &self, value: ValueRef, assignment: ClassicalAssignment<'_>, ) -> Result<bool, ResolveError>
A selected output’s bit when fixed by the supplied path.
§Errors
Returns the same errors as Self::classical_value.
Source§impl Bloq
impl Bloq
Sourcepub fn stats(&self) -> Result<BloqStats, BloqStatsError>
pub fn stats(&self) -> Result<BloqStats, BloqStatsError>
Inventory stored IR structure without inspecting physical circuit payloads.
Unlike Self::node_count and Self::edge_count, counts include all
nested graph levels and concrete node/edge kinds. Every stored region
body contributes once, independently of guards and retry attempts.
Static means fixed execution structure: no regions, node activation,
conditional quantum membership/seams, or shot discard. Classical
computation/readout/decoding and fixed circuit repeats alone remain static.
This is neither the explicit Self::validate audit nor a guarantee
that a particular backend can emit the program.
§Errors
Returns BloqStatsError::CountOverflow if a structural total overflows.
Source§impl Bloq
impl Bloq
Sourcepub fn to_text(&self) -> String
pub fn to_text(&self) -> String
Render this program in the text exchange format (also Display).
Sourcepub fn from_text(text: &str) -> Result<Self, TextParseError>
pub fn from_text(text: &str) -> Result<Self, TextParseError>
Parse a program from the text exchange format.
§Errors
Returns TextParseError for malformed syntax, unsupported versions,
invalid references, or structurally invalid serialized data.
Source§impl Bloq
impl Bloq
Sourcepub fn walk(&self, f: impl FnMut(NodeCx<'_>) -> WalkControl) -> WalkControl
pub fn walk(&self, f: impl FnMut(NodeCx<'_>) -> WalkControl) -> WalkControl
Pre-order depth-first walk over every node at every nesting level, in
ascending node-id order within a level (the validation/scan order —
use SubGraph::deterministic_emit_order per level when you need the
schedule). Returns WalkControl::Stop if the callback stopped the
walk, else WalkControl::Continue.
The callback receives a NodeCx for each visited node and returns a
WalkControl: Continue to descend into the
node’s region bodies (if any), SkipBodies
to visit the node but prune its bodies, or Stop
to abort the whole walk.
§Examples
In real code a Bloq comes from the compiler (bloq_compile), but
that crate depends on this one, so — to keep this doctest free of a
dependency cycle — we parse an equivalent program from the .bloqir
text format instead. It is a single quantum node feeding a
RepeatUntilSuccess region (whose body holds another quantum node and
an observable fragment), then a terminal observable — the shape a magic-state
(T) block lowers to.
use bloq_ir::{Bloq, BloqNodeKind, WalkControl};
let program = Bloq::from_text(
"\
BLOQIR 1
template t0 {
circuit {
MPP X(0,0):m0
}
}
graph {
n0 quantum {
instance i0 t0 @ (0,0)
}
n1 rus in0 source n0 {
body {
n0 quantum {
instance i1 t0 @ (2,0)
}
n1 observable fragment measurements i1:m0 from generator 0
n0 -> n1 order
}
}
n2 observable 0
n0 -> n1 order
n1 -> n2 order
}
",
)
.expect("valid .bloqir text");
// A full walk visits every node at every level, matching on kind.
let (mut quantum, mut classical, mut region) = (0, 0, 0);
program.walk(|cx| {
match cx.node.kind {
BloqNodeKind::Quantum(_) => quantum += 1,
BloqNodeKind::Classical(_) => classical += 1,
BloqNodeKind::Region(_) => region += 1,
}
WalkControl::Continue
});
// Two quantum (top-level + in-body), two classical (in-body fragment +
// terminal observable), one region.
assert_eq!((quantum, classical, region), (2, 2, 1));
// `SkipBodies` prunes region bodies: the two in-body nodes are skipped,
// leaving only the three top-level nodes.
let mut top_level = 0;
program.walk(|cx| {
top_level += 1;
match cx.node.kind {
BloqNodeKind::Region(_) => WalkControl::SkipBodies,
_ => WalkControl::Continue,
}
});
assert_eq!(top_level, 3);
// `Stop` aborts early. Here we halt at the first region and report it.
let mut region_path = None;
let control = program.walk(|cx| {
if matches!(cx.node.kind, BloqNodeKind::Region(_)) {
region_path = Some(cx.path.clone());
WalkControl::Stop
} else {
WalkControl::Continue
}
});
assert_eq!(control, WalkControl::Stop);
// The region is at the top level, so its owner path is empty.
assert!(region_path.expect("stopped at the region").segments().is_empty());Sourcepub fn levels(&self) -> impl Iterator<Item = (LevelPath, &SubGraph)>
pub fn levels(&self) -> impl Iterator<Item = (LevelPath, &SubGraph)>
Every graph level, pre-order top-down: the top level, then each region body. For whole-program table passes (instance collection, id allocation) that read levels rather than individual nodes.
Each item is (LevelPath, &SubGraph): the path identifies the level
(empty for the top level), and the SubGraph exposes the level’s full
read surface — nodes, edges,
deterministic_emit_order, etc.
§Examples
A per-level table pass that sums quantum nodes across the whole program
(see Bloq::walk for the .bloqir program used here):
use bloq_ir::{Bloq, BloqNodeKind};
let mut level_count = 0;
let mut quantum_total = 0;
for (path, level) in program.levels() {
level_count += 1;
let quantum = level
.nodes()
.filter(|(_, node)| matches!(node.kind, BloqNodeKind::Quantum(_)))
.count();
quantum_total += quantum;
// `path` is the level's identity: empty at the top, one hop inside
// the region body.
assert!(path.segments().len() <= 1);
}
// Two levels (top + the region body), one quantum node in each.
assert_eq!(level_count, 2);
assert_eq!(quantum_total, 2);Source§impl Bloq
impl Bloq
Sourcepub fn validate(&self) -> Result<(), BloqValidationError>
pub fn validate(&self) -> Result<(), BloqValidationError>
Validates IR well-formedness, including nested region bodies.
Same-layer qubit overlap depends on source BlockGraph soft corridors
and is checked by bloq_compile lowering.
WF-9 checks every reachable selected merge. Self::validate_with_plans
additionally returns static plans and certified conditional stages.
This entry point releases each merged circuit after checking its node,
bounding temporary circuit storage by the largest quantum stage. Within
one noiseless validation, successful unguarded merges are reused at the
same relative placements; absolute coordinates are still checked.
§Errors
Returns BloqValidationError for any violated IR well-formedness or
bounded-resource rule.
Sourcepub fn validate_with_options(
&self,
options: &InstantiationOptions<'_>,
) -> Result<(), BloqValidationError>
pub fn validate_with_options( &self, options: &InstantiationOptions<'_>, ) -> Result<(), BloqValidationError>
Validate with explicit noise and resource limits, releasing emission plans after each node instead of retaining them.
§Errors
Returns BloqValidationError for invalid IR, merge, noise, or
exhausted resources.
Sourcepub fn validate_with_plans(
&self,
options: &InstantiationOptions<'_>,
) -> Result<ValidatedPlans, BloqValidationError>
pub fn validate_with_plans( &self, options: &InstantiationOptions<'_>, ) -> Result<ValidatedPlans, BloqValidationError>
Self::validate, additionally returning static NodeEmissionPlans
and certified conditional stages, keyed by scoped address (see
ValidatedPlans). Plans are instantiated with options.
Applies the same well-formedness rules as Self::validate, charging
work for every materialized plan. SEM-MERGE applies noise once to the
post-merge circuit, and the returned plans carry the caller’s options.
Conditional membership uses pairwise Boolean overlap checks.
A malformed NoiseModel also changes the outcome: its
probabilities are only checked while materializing noise, so a bad model
surfaces here (and only under noisy options) as
InvalidInstanceMergeStructure
at the first quantum node.
§Errors
Returns BloqValidationError under the same conditions as
Self::validate_with_options.
§Panics
Panics only if the internal plan collector is unexpectedly absent.
Sourcepub fn emission_plans(
&self,
options: &InstantiationOptions<'_>,
) -> Result<ValidatedPlans, BloqValidationError>
pub fn emission_plans( &self, options: &InstantiationOptions<'_>, ) -> Result<ValidatedPlans, BloqValidationError>
Materialize static quantum stages without a full well-formedness audit. Guarded stages are marked for the consumer to select and materialize; no Boolean proof of their entire choice domain is performed here.
Required static merges and their noise application still fail here.
A consumer must report failures while materializing selected guarded
stages. Call Self::validate_with_plans explicitly for the complete
all-choice IR audit as well as plans.
§Errors
InvalidInstanceMergeStructure
if a static quantum node’s instances cannot merge (SEM-MERGE).
§Caution
This is not a substitute for Self::validate. Malformed IR outside
the materialized stages may not be reported by this method.
Source§impl Bloq
impl Bloq
Sourcepub fn to_svg(&self, include_classical: bool) -> String
pub fn to_svg(&self, include_classical: bool) -> String
Render the program dependency graph as a self-contained SVG.
include_classical includes classical nodes and their incident edges.
When false, quantum nodes, regions and their direct dependencies remain.
Nested region bodies are drawn inside their owning container. Quantum, composition,
value and order edges retain distinct colors; this is a structural view
of all alternatives, not one selected runtime execution.
let program = bloq_ir::Bloq::new();
let svg = program.to_svg(true);
assert!(svg.starts_with("<svg"));Trait Implementations§
Source§impl<'de> Deserialize<'de> for Bloq
impl<'de> Deserialize<'de> for Bloq
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Index<BloqNodeId> for Bloq
The panicking twin of Bloq::node (see SubGraph’s Index impl).
impl Index<BloqNodeId> for Bloq
The panicking twin of Bloq::node (see SubGraph’s Index impl).