Skip to content

for loops only accept sets and ranges — not bit[n], arrays, aliases or index expressions #393

Description

@TheGupta2012

Limitation

For loops states that the iterated <values> may
be any of:

  • a discrete set, e.g. {1, 2, 3}
  • a range expression, e.g. [0:2:10]
  • a value of type bit[n], or the target of a let statement aliasing classical bits
  • a value of type array[<scalar>, n] (one-dimensional)

and adds: "It is valid to use an indexing expression (e.g. my_array[1:3]) to arrive at one of
the types given above."

pyqasm implements only the first two. Any identifier or index expression as the iterable is
rejected.

Example QASM failure

Iterating a bit register:

OPENQASM 3.0;
bit[4] b = "1010";
for bit x in b { }
// ValidationError: Unexpected type <class 'openqasm3.ast.Identifier'> of set_declaration in loop.

Iterating an array:

OPENQASM 3.0;
array[int[8], 3] a = {1, 2, 3};
for int[8] i in a { }
// ValidationError: Unexpected type <class 'openqasm3.ast.Identifier'> of set_declaration in loop.

Iterating an index expression:

OPENQASM 3.0;
array[int[8], 4] a = {1, 2, 3, 4};
for int[8] i in a[1:2] { }
// ValidationError: Unexpected type <class 'openqasm3.ast.IndexExpression'> of set_declaration in loop.

Iterating a classical alias:

OPENQASM 3.0;
bit[4] b;
let c = b;
for bit x in c { }
// ValidationError: Qubit register b not found for aliasing

Change Requested

Extend the loop's iterable resolution to accept, in addition to the existing set and range
forms:

  1. An Identifier naming a bit[n] — loop variable type bit, iterating index 0..n-1.
  2. An Identifier naming a one-dimensional array[<scalar>, n] — loop variable type
    <scalar>, promoted to the declared loop variable type.
  3. An Identifier naming a classical alias.
  4. An IndexExpression that evaluates to any of the above.

Two spec rules to enforce while doing so:

  • Iteration order is guaranteed sequential by index: iden[0], then iden[1], and so on.
  • Assigning to the loop variable inside the body must not modify the underlying array element.

A multi-dimensional array as the iterable must raise a ValidationError — the spec restricts
this to one-dimensional arrays.

Implementation Details

  • The rejection is in Qasm3Visitor._visit_forin_loop at src/pyqasm/visitor.py:2462. It
    branches on the concrete type of statement.set_declaration and falls through for anything
    that is not a DiscreteSet or RangeDefinition.
  • Factor the branch into a helper that returns a plain Python list of values to iterate. That
    isolates the new cases and keeps the unrolling loop below unchanged.
  • Since the loop body is unrolled per value, the "assignment to the loop variable does not
    write back" rule falls out naturally from binding a copy into the loop scope each
    iteration — but add an explicit test, since it is easy to regress with a by-reference bind.
  • Depends on the bit[n] representation work for case 1 and on the classical-alias work for
    case 3; case 2 (arrays) is independent and could land first.
  • Tests: tests/qasm3/test_loop.py — one case per iterable form, an index-expression iterable,
    a write to the loop variable asserting the source array is unchanged, and a
    multi-dimensional array asserting a clean ValidationError.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestllm-assistedUsed LLMs to fine tune issue description.qasm3Related to openqasm3qasm3-coverageAdding support for qasm3 constructs

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions