Limitation
Duration and stretch types defines
stretch as a duration that resolves at compile time, and
Operations on durations allows a
stretch to be combined with a duration in arithmetic. This is how the spec expresses
padding that absorbs whatever slack a schedule leaves.
pyqasm declares a stretch with a None value and then applies Python arithmetic to it,
producing an uncaught TypeError.
Example QASM failure
import pyqasm
m = pyqasm.loads('''
OPENQASM 3.0;
stretch s;
duration a = 300ns;
duration b = a + s;
''')
m.validate()
TypeError: unsupported operand type(s) for +: 'float' and 'NoneType'
A bare stretch s; declaration and delay[s] q[0]; both work today, so the gap is confined
to arithmetic involving a stretch operand.
Change Requested
- Duration expressions containing a
stretch operand must not raise a Python TypeError.
- Preferred: represent a duration as an affine value
(constant_ns, {stretch: coefficient})
so that a + s, 2 * s, and a + 2 * s are all representable symbolically and can be
emitted unchanged by dumps().
- Minimum acceptable: raise a
ValidationError stating that stretch arithmetic is not yet
supported, naming the stretch variable and its span. The current internal error is the only
unacceptable outcome.
Implementation Details
- Duration/stretch declarations are handled in
src/pyqasm/visitor.py alongside the other
classical declarations; the numeric evaluation happens in Qasm3ExprEvaluator
(src/pyqasm/expressions.py), which is where the float + None occurs.
- Unit conversion lives in
DURATION_UNITS in src/pyqasm/maps/expressions.py; the affine
representation should normalise the constant part to nanoseconds there, consistent with how
plain durations are already handled.
- The affine form composes with the existing
box[...] duration validation and delay[...]
handling, both of which currently expect a plain number — they will need to accept the new
type or explicitly reject a non-constant duration where a concrete one is required.
- Full stretch resolution (solving for stretch values against a schedule) is a much larger
piece of work and is explicitly out of scope here. This issue only asks that stretch
operands survive expression evaluation.
- Tests:
tests/qasm3/test_timing.py (or the existing delay/box tests) — a + s, 2 * s,
a + 2 * s, a stretch inside box[...], and a dumps() round-trip.
Limitation
Duration and stretch types defines
stretchas a duration that resolves at compile time, andOperations on durations allows a
stretchto be combined with adurationin arithmetic. This is how the spec expressespadding that absorbs whatever slack a schedule leaves.
pyqasmdeclares astretchwith aNonevalue and then applies Python arithmetic to it,producing an uncaught
TypeError.Example QASM failure
A bare
stretch s;declaration anddelay[s] q[0];both work today, so the gap is confinedto arithmetic involving a stretch operand.
Change Requested
stretchoperand must not raise a PythonTypeError.(constant_ns, {stretch: coefficient})so that
a + s,2 * s, anda + 2 * sare all representable symbolically and can beemitted unchanged by
dumps().ValidationErrorstating that stretch arithmetic is not yetsupported, naming the stretch variable and its span. The current internal error is the only
unacceptable outcome.
Implementation Details
src/pyqasm/visitor.pyalongside the otherclassical declarations; the numeric evaluation happens in
Qasm3ExprEvaluator(
src/pyqasm/expressions.py), which is where thefloat + Noneoccurs.DURATION_UNITSinsrc/pyqasm/maps/expressions.py; the affinerepresentation should normalise the constant part to nanoseconds there, consistent with how
plain durations are already handled.
box[...]duration validation anddelay[...]handling, both of which currently expect a plain number — they will need to accept the new
type or explicitly reject a non-constant duration where a concrete one is required.
piece of work and is explicitly out of scope here. This issue only asks that stretch
operands survive expression evaluation.
tests/qasm3/test_timing.py(or the existing delay/box tests) —a + s,2 * s,a + 2 * s, a stretch insidebox[...], and adumps()round-trip.