Skip to main content

AtomStateData

Struct AtomStateData 

Source
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

Source

pub fn new() -> Self

Create an empty state with no qubits or locations.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn get_qubit(&self, location: &LocationAddr) -> Option<u32>

Look up which qubit (if any) occupies the given location.

Source

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

Source§

fn clone(&self) -> AtomStateData

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AtomStateData

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for AtomStateData

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for AtomStateData

Source§

impl Hash for AtomStateData

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for AtomStateData

Source§

fn eq(&self, other: &AtomStateData) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for AtomStateData

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<'src, T> IntoMaybe<'src, T> for T
where T: 'src,

§

type Proj<U: 'src> = U

§

fn map_maybe<R>( self, _f: impl FnOnce(&'src T) -> &'src R, g: impl FnOnce(T) -> R, ) -> <T as IntoMaybe<'src, T>>::Proj<R>
where R: 'src,

§

impl<T> OrderedSeq<'_, T> for T
where T: Clone,

§

impl<'p, T> Seq<'p, T> for T
where T: Clone,

§

type Item<'a> = &'a T where T: 'a

The item yielded by the iterator.
§

type Iter<'a> = Once<&'a T> where T: 'a

An iterator over the items within this container, by reference.
§

fn seq_iter(&self) -> <T as Seq<'p, T>>::Iter<'_>

Iterate over the elements of the container.
§

fn contains(&self, val: &T) -> bool
where T: PartialEq,

Check whether an item is contained within this sequence.
§

fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>
where 'p: 'b,

Convert an item of the sequence into a [MaybeRef].
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.