pub struct AtomStateData {
pub locations_to_qubit: HashMap<LocationAddr, u32>,
pub qubit_to_locations: HashMap<u32, LocationAddr>,
pub collision: HashMap<u32, u32>,
pub prev_lanes: HashMap<u32, LaneAddr>,
pub move_count: HashMap<u32, u32>,
}Expand description
Tracks qubit-to-location mappings as atoms move through the architecture.
This is an immutable value type: all mutation methods (add_atoms,
apply_moves) return a new instance rather than modifying in place.
The two primary maps (locations_to_qubit and qubit_to_locations) are
kept in sync as a bidirectional index. When a move causes two atoms to
occupy the same site, both are removed from the location maps and recorded
in collision.
Fields§
§locations_to_qubit: HashMap<LocationAddr, u32>Reverse index: given a physical location, which qubit (if any) is there?
qubit_to_locations: HashMap<u32, LocationAddr>Forward index: given a qubit id, where is it currently located?
collision: HashMap<u32, u32>Cumulative record of qubits that have collided since this state was
created (via constructors or add_atoms). Updated by apply_moves —
new collisions are added to existing entries. Key is the moving qubit,
value is the qubit it displaced. Collided qubits are removed from
both location maps.
prev_lanes: HashMap<u32, LaneAddr>The lane each qubit used in the most recent apply_moves.
Only populated for qubits that moved in the last step.
move_count: HashMap<u32, u32>Cumulative number of moves each qubit has undergone across
all apply_moves calls in the state’s history.
Implementations§
Source§impl AtomStateData
impl AtomStateData
Sourcepub fn from_locations(locations: &[(u32, LocationAddr)]) -> Self
pub fn from_locations(locations: &[(u32, LocationAddr)]) -> Self
Create a state from a list of (qubit_id, location) pairs.
Builds both the forward (qubit → location) and reverse (location → qubit) maps. All other fields (collision, prev_lanes, move_count) are empty.
Sourcepub fn add_atoms(
&self,
locations: &[(u32, LocationAddr)],
) -> Result<Self, &'static str>
pub fn add_atoms( &self, locations: &[(u32, LocationAddr)], ) -> Result<Self, &'static str>
Add atoms at new locations, returning a new state.
Each (qubit_id, location) pair is added to the bidirectional maps.
Returns Err if any qubit id already exists in this state or any
location is already occupied by another qubit.
The returned state inherits no collision, prev_lanes, or move_count data — those fields are reset to empty.
Sourcepub fn apply_moves(
&self,
lanes: &[LaneAddr],
arch_spec: &ArchSpec,
) -> Option<Self>
pub fn apply_moves( &self, lanes: &[LaneAddr], arch_spec: &ArchSpec, ) -> Option<Self>
Apply a group of lane moves simultaneously and return the resulting state.
All lanes execute as one AOD transport operation: every endpoint is
resolved against the pre-move state, so for any
check_lanes-valid group the result is
independent of lane order (distinct lanes sharing a source can only
occur in invalid groups, and resolve first-in-slice-wins). A
destination counts as free when its occupant moves in the same group —
conveyor chains (x→y, y→z) are legal. Lanes whose source has no
qubit are skipped.
A qubit that lands on an atom which does not move in this group
collides: both qubits are removed from the location maps and recorded
in collision. This method never fails on collisions — use
Self::validate_moves + Self::apply_validated to reject such
groups up front instead.
Returns None if any lane cannot be resolved to endpoints (invalid
bus, word, or site). The prev_lanes field is reset to contain only
the lanes used in this call; move_count is accumulated.
Sourcepub fn validate_moves(
&self,
lanes: &[LaneAddr],
arch_spec: &ArchSpec,
) -> Result<ValidatedMoves, Vec<MoveValidationError>>
pub fn validate_moves( &self, lanes: &[LaneAddr], arch_spec: &ArchSpec, ) -> Result<ValidatedMoves, Vec<MoveValidationError>>
Validate that a lane group can execute against this state.
This is the canonical executability check for a move group. It runs
the static lane-group checks (ArchSpec::check_lanes) and the
occupancy rules, all resolved against the pre-move state:
- every occupied destination must be vacated by a lane in the same group (the occupant sits at another lane’s source) — this applies uniformly to mover lanes and empty-source filler lanes, because the AOD trap site arrives at every destination either way;
- no two lanes may share a destination;
- empty-source lanes whose destination is also free are legal no-ops (AOD rectangle filler).
Assumes arch_spec itself is valid (see ArchSpec::validate);
with well-formed (acyclic, endpoint-unique) buses, a valid group can
only be a set of independent transports or conveyor chains, never a
rotation.
All errors are collected in one pass. On success the returned
ValidatedMoves token feeds Self::apply_validated; it is tied
to this state and must not be applied to any other.
Sourcepub fn apply_validated(
&self,
moves: &ValidatedMoves,
) -> Result<Self, Vec<MoveValidationError>>
pub fn apply_validated( &self, moves: &ValidatedMoves, ) -> Result<Self, Vec<MoveValidationError>>
Apply a validated lane group and return the resulting state.
Total on a token produced by Self::validate_moves on this state:
validation has already ruled out every collision, so no atom is
destroyed or silently skipped. The prev_lanes field is reset to the
movers of this call; move_count is accumulated; collision is
carried over unchanged.
Returns Err when the token is stale — produced against a different
state, or against this state before it moved on. The token records
assignments resolved at validation time, so applying it blindly would
silently desynchronize the two location maps rather than fail. This
check runs in every build (not just debug) because apply_validated
is public API, including through the Python bindings, where holding a
token across a state change is easy to do by accident. It costs
O(movers) lookups — far less than Self::validate_moves itself.
Sourcepub fn get_qubit(&self, location: &LocationAddr) -> Option<u32>
pub fn get_qubit(&self, location: &LocationAddr) -> Option<u32>
Look up which qubit (if any) occupies the given location.
Sourcepub fn get_qubit_pairing(
&self,
zone: &ZoneAddr,
arch_spec: &ArchSpec,
) -> Option<(Vec<u32>, Vec<u32>, Vec<u32>)>
pub fn get_qubit_pairing( &self, zone: &ZoneAddr, arch_spec: &ArchSpec, ) -> Option<(Vec<u32>, Vec<u32>, Vec<u32>)>
Find CZ gate control/target qubit pairings within a zone.
Iterates over all qubits whose current location is in the given zone
and checks whether the CZ pair site (via [ArchSpec::get_blockaded_location])
is also occupied. If both sites are occupied, the qubits form a
control/target pair. If the pair site is empty or doesn’t exist, the
qubit is unpaired.
Returns (controls, targets, unpaired) where controls[i] and
targets[i] are paired for CZ. Results are sorted by qubit id for
deterministic ordering. Returns None if the zone id is invalid.
Trait Implementations§
Source§impl Clone for AtomStateData
impl Clone for AtomStateData
Source§fn clone(&self) -> AtomStateData
fn clone(&self) -> AtomStateData
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AtomStateData
impl Debug for AtomStateData
Source§impl Default for AtomStateData
impl Default for AtomStateData
impl Eq for AtomStateData
Source§impl Hash for AtomStateData
impl Hash for AtomStateData
Source§impl PartialEq for AtomStateData
impl PartialEq for AtomStateData
Source§fn eq(&self, other: &AtomStateData) -> bool
fn eq(&self, other: &AtomStateData) -> bool
self and other values to be equal, and is used by ==.impl StructuralPartialEq for AtomStateData
Auto Trait Implementations§
impl Freeze for AtomStateData
impl RefUnwindSafe for AtomStateData
impl Send for AtomStateData
impl Sync for AtomStateData
impl Unpin for AtomStateData
impl UnsafeUnpin for AtomStateData
impl UnwindSafe for AtomStateData
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<'src, T> IntoMaybe<'src, T> for Twhere
T: 'src,
impl<'src, T> IntoMaybe<'src, T> for Twhere
T: 'src,
impl<T> OrderedSeq<'_, T> for Twhere
T: Clone,
§impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
§type Iter<'a> = Once<&'a T>
where
T: 'a
type Iter<'a> = Once<&'a T> where T: 'a
§fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
§fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>where
'p: 'b,
fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>where
'p: 'b,
MaybeRef].