Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
9ec68b2
Adds range expression to classical circuits
arthurostrauss Jun 16, 2025
8962ff5
Fixed bug
arthurostrauss Jun 16, 2025
4828738
Reformat
arthurostrauss Jun 16, 2025
b4af557
Linting + bug in attribute getting in test
arthurostrauss Jun 16, 2025
26485f9
Fixed additional test
arthurostrauss Jun 16, 2025
6ed3917
New linting
arthurostrauss Jun 16, 2025
3d265af
Enables type specification for Range expressions
arthurostrauss Jun 17, 2025
8c4ef28
Added dummy __len__ method to Range + fix Cast logic
arthurostrauss Jun 19, 2025
92285ae
Adds range expression to classical circuits
arthurostrauss Jun 16, 2025
2a2d425
Fixed bug
arthurostrauss Jun 16, 2025
a2a52a6
Reformat
arthurostrauss Jun 16, 2025
e1b46be
Linting + bug in attribute getting in test
arthurostrauss Jun 16, 2025
d7f4afe
New linting
arthurostrauss Jun 16, 2025
5505f00
Enables type specification for Range expressions
arthurostrauss Jun 17, 2025
4c25f5f
Added dummy __len__ method to Range + fix Cast logic
arthurostrauss Jun 19, 2025
60e2afd
Additional expr fix
arthurostrauss Jun 19, 2025
87fcb7e
Added extra check on specified Range type and corrected tests
arthurostrauss Jun 19, 2025
969e864
linting
arthurostrauss Jun 19, 2025
e9f6f42
Added new release note
arthurostrauss Jun 26, 2025
4dd4d01
Adds support for range expressions
arthurostrauss Jul 31, 2025
57a2e36
Linting fix attempt
arthurostrauss Aug 13, 2025
44cbb3d
Added default step value to 1 in promoted type
arthurostrauss Aug 14, 2025
1f2edfb
Reformat and small fix on arg name
arthurostrauss Aug 14, 2025
24c445d
Linting
arthurostrauss Aug 14, 2025
1c44a42
Fixed tests and linting
arthurostrauss Aug 14, 2025
66d6f25
Additional linting
arthurostrauss Aug 14, 2025
f017b0a
Update release note section name
arthurostrauss Aug 14, 2025
4adfad5
Release notes rewriting
arthurostrauss Aug 18, 2025
10d79e5
additional editing of release note
arthurostrauss Aug 18, 2025
5077d2f
Linting fix
arthurostrauss Sep 5, 2025
7e15c65
Refactors range expressions to ensure step is always present
arthurostrauss Sep 9, 2025
55a7bc2
Reformat
arthurostrauss Sep 9, 2025
cb1eee2
Linting
arthurostrauss Sep 9, 2025
a476007
Updates range representation in Python
arthurostrauss Sep 9, 2025
6fa6720
Removes unnecessary formatting in repr
arthurostrauss Sep 9, 2025
6e75c81
Removed unnecessary logic on error message
arthurostrauss Oct 3, 2025
a337b4c
Linting
arthurostrauss Oct 3, 2025
b474bbe
Update range.rs (linting)
arthurostrauss Oct 3, 2025
675c05a
Update qiskit/qasm3/ast.py
arthurostrauss Oct 3, 2025
48c57d3
Update releasenotes
arthurostrauss Oct 3, 2025
8f381cb
Update releasenotes
arthurostrauss Oct 3, 2025
f540df3
Update releasenotes
arthurostrauss Oct 3, 2025
00c1244
Linting
arthurostrauss Oct 3, 2025
22bb3c2
Added copy and pickle method to comply with transpiler constraints
arthurostrauss Oct 5, 2025
eb6622c
Reformat
arthurostrauss Oct 6, 2025
ab49a25
Updated upgrade section of release notes
arthurostrauss Oct 6, 2025
fe5fcc8
Adds range expression to classical circuits
arthurostrauss Jun 16, 2025
1fba76a
Fixed bug
arthurostrauss Jun 16, 2025
9e55386
Reformat
arthurostrauss Jun 16, 2025
15f3ca5
Linting + bug in attribute getting in test
arthurostrauss Jun 16, 2025
fc63ffb
Fixed additional test
arthurostrauss Jun 16, 2025
3dc8b3d
New linting
arthurostrauss Jun 16, 2025
89fc193
Enables type specification for Range expressions
arthurostrauss Jun 17, 2025
74b366f
Added dummy __len__ method to Range + fix Cast logic
arthurostrauss Jun 19, 2025
751cadd
Adds range expression to classical circuits
arthurostrauss Jun 16, 2025
934f37b
Fixed bug
arthurostrauss Jun 16, 2025
93243a1
Reformat
arthurostrauss Jun 16, 2025
0aaf149
Linting + bug in attribute getting in test
arthurostrauss Jun 16, 2025
5084882
New linting
arthurostrauss Jun 16, 2025
49fb7ac
Enables type specification for Range expressions
arthurostrauss Jun 17, 2025
7a5bbaf
Added dummy __len__ method to Range + fix Cast logic
arthurostrauss Jun 19, 2025
07f46a7
Additional expr fix
arthurostrauss Jun 19, 2025
d1ff3f3
Added extra check on specified Range type and corrected tests
arthurostrauss Jun 19, 2025
763cfc6
linting
arthurostrauss Jun 19, 2025
a91937b
Added new release note
arthurostrauss Jun 26, 2025
51e0d78
Adds support for range expressions
arthurostrauss Jul 31, 2025
a926362
Linting fix attempt
arthurostrauss Aug 13, 2025
ee9c4bd
Added default step value to 1 in promoted type
arthurostrauss Aug 14, 2025
ed62fc7
Reformat and small fix on arg name
arthurostrauss Aug 14, 2025
0063acb
Linting
arthurostrauss Aug 14, 2025
133b21e
Fixed tests and linting
arthurostrauss Aug 14, 2025
55dfde9
Additional linting
arthurostrauss Aug 14, 2025
5b2ef05
Update release note section name
arthurostrauss Aug 14, 2025
0cab043
Release notes rewriting
arthurostrauss Aug 18, 2025
070cb2f
additional editing of release note
arthurostrauss Aug 18, 2025
bfb7fd5
Linting fix
arthurostrauss Sep 5, 2025
00491cf
Refactors range expressions to ensure step is always present
arthurostrauss Sep 9, 2025
f57e51f
Reformat
arthurostrauss Sep 9, 2025
a59a6eb
Linting
arthurostrauss Sep 9, 2025
375901d
Updates range representation in Python
arthurostrauss Sep 9, 2025
65c0fc1
Removes unnecessary formatting in repr
arthurostrauss Sep 9, 2025
3dac32b
Removed unnecessary logic on error message
arthurostrauss Oct 3, 2025
7b3ceee
Linting
arthurostrauss Oct 3, 2025
54bfab8
Update range.rs (linting)
arthurostrauss Oct 3, 2025
adf5b9c
Update qiskit/qasm3/ast.py
arthurostrauss Oct 3, 2025
01a80a2
Update releasenotes
arthurostrauss Oct 3, 2025
67d9198
Update releasenotes
arthurostrauss Oct 3, 2025
1419121
Update releasenotes
arthurostrauss Oct 3, 2025
e597905
Linting
arthurostrauss Oct 3, 2025
bc2dc75
Added copy and pickle method to comply with transpiler constraints
arthurostrauss Oct 5, 2025
2ff1523
Reformat
arthurostrauss Oct 6, 2025
ce7e4d9
Updated upgrade section of release notes
arthurostrauss Oct 6, 2025
1506e9d
Merge remote-tracking branch 'origin/dynamic_range_expr' into dynamic…
arthurostrauss Oct 21, 2025
87f009e
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Oct 24, 2025
d1ba761
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Oct 27, 2025
c43e3a2
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Oct 29, 2025
9c3c8ae
Updated Range to comply with latest Rust changes
arthurostrauss Oct 29, 2025
ebc7331
Linting
arthurostrauss Oct 29, 2025
8231ad4
Update range.rs
arthurostrauss Oct 29, 2025
b30c75a
Merge branch 'main' into dynamic_range_expr
1ucian0 Oct 30, 2025
ca6bab5
Merge branch 'main' into dynamic_range_expr
arthurostrauss Oct 31, 2025
7a7241b
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 3, 2025
ea7bd65
Adapted Range to comply with latest Value specification
arthurostrauss Nov 3, 2025
8f82b3d
Upgraded test Range using ddt
arthurostrauss Nov 3, 2025
ff37ae2
Fixed default type in QASM3 AST for ForLoop statement
arthurostrauss Nov 3, 2025
2d48480
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 10, 2025
3fc6983
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 11, 2025
bf82be2
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 16, 2025
f47de54
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 23, 2025
4221598
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 24, 2025
ef65946
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 25, 2025
e107e23
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 26, 2025
effbf32
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 27, 2025
1a7db2f
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Nov 27, 2025
ef2784a
Adds support for range indexsets in for-loops
arthurostrauss Nov 27, 2025
810a89a
Improves ForLoopOp drawing with dynamic range
arthurostrauss Nov 27, 2025
cbf2acd
Simplifies range formatting in circuit visualization
arthurostrauss Nov 27, 2025
19bd045
Added is_empty() method for ForLoopIndexSet
arthurostrauss Nov 27, 2025
30dce33
Improves display of range objects in circuit visualization
arthurostrauss Nov 27, 2025
707d8d0
Merge branch 'main' into dynamic_range_expr
1ucian0 Nov 28, 2025
0f2f1f1
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Dec 3, 2025
b0da9ee
Reduces cloning in range expression creation.
arthurostrauss Dec 3, 2025
f0e680e
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Dec 4, 2025
b245cc4
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Dec 5, 2025
d5fe0e6
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Dec 8, 2025
4666007
Merge remote-tracking branch 'Qiskit/main' into dynamic_range_expr
arthurostrauss Dec 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion crates/circuit/src/classical/expr/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.

use crate::classical::expr::{Binary, Cast, Index, Stretch, Unary, Value, Var};
use crate::classical::expr::{Binary, Cast, Index, Range, Stretch, Unary, Value, Var};
use crate::classical::types::Type;
use pyo3::prelude::*;
use pyo3::{IntoPyObjectExt, intern};
Expand All @@ -30,6 +30,7 @@ pub enum Expr {
Var(Var),
Stretch(Stretch),
Index(Box<Index>),
Range(Box<Range>),
}

#[derive(Debug, PartialEq)]
Expand All @@ -41,6 +42,7 @@ pub enum ExprRef<'a> {
Var(&'a Var),
Stretch(&'a Stretch),
Index(&'a Index),
Range(&'a Range),
}

#[derive(Debug, PartialEq)]
Expand All @@ -52,6 +54,7 @@ pub enum ExprRefMut<'a> {
Var(&'a mut Var),
Stretch(&'a mut Stretch),
Index(&'a mut Index),
Range(&'a mut Range),
}

#[derive(Clone, Debug, PartialEq)]
Expand All @@ -71,6 +74,7 @@ impl Expr {
Expr::Var(v) => ExprRef::Var(v),
Expr::Stretch(s) => ExprRef::Stretch(s),
Expr::Index(i) => ExprRef::Index(i.as_ref()),
Expr::Range(r) => ExprRef::Range(r.as_ref()),
}
}

Expand All @@ -84,6 +88,7 @@ impl Expr {
Expr::Var(v) => ExprRefMut::Var(v),
Expr::Stretch(s) => ExprRefMut::Stretch(s),
Expr::Index(i) => ExprRefMut::Index(i.as_mut()),
Expr::Range(r) => ExprRefMut::Range(r.as_mut()),
}
}

Expand All @@ -97,6 +102,7 @@ impl Expr {
Expr::Var(_) => false,
Expr::Stretch(_) => true,
Expr::Index(i) => i.constant,
Expr::Range(r) => r.constant,
}
}

Expand All @@ -118,6 +124,7 @@ impl Expr {
},
Expr::Stretch(_) => Type::Duration,
Expr::Index(i) => i.ty,
Expr::Range(r) => r.ty,
}
}

Expand Down Expand Up @@ -165,6 +172,11 @@ impl Expr {
i.target.visit_mut_impl(visitor)?;
i.index.visit_mut_impl(visitor)?;
}
Expr::Range(r) => {
r.start.visit_mut_impl(visitor)?;
r.stop.visit_mut_impl(visitor)?;
r.step.visit_mut_impl(visitor)?;
}
}
visitor(self.as_mut())
}
Expand Down Expand Up @@ -237,6 +249,18 @@ impl Expr {
return false;
}
}
(ExprRef::Range(a), ExprRef::Range(b)) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't fully understand what this function does - and so, whether we should also compare the values of start and stop (and step).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It recursively goes into the equivalence checks of the components of the Range, which are defined in other modules. I did not pay too much attention of what it was checking under the hood

if a.ty != b.ty || a.constant != b.constant {
return false;
}
// Compare the actual values of start, stop, and step expressions
if !a.start.structurally_equivalent(&b.start)
|| !a.stop.structurally_equivalent(&b.stop)
|| !a.step.structurally_equivalent(&b.step)
{
return false;
}
}
_ => return false,
},
(None, None) => return true,
Expand Down Expand Up @@ -275,6 +299,11 @@ impl<'a> Iterator for ExprIterator<'a> {
self.stack.push(&i.index);
self.stack.push(&i.target);
}
Expr::Range(r) => {
self.stack.push(&r.stop);
self.stack.push(&r.start);
self.stack.push(&r.step);
}
}
Some(expr.as_ref())
}
Expand Down Expand Up @@ -381,6 +410,18 @@ impl From<Box<Index>> for Expr {
}
}

impl From<Range> for Expr {
fn from(value: Range) -> Self {
Expr::Range(Box::new(value))
}
}

impl From<Box<Range>> for Expr {
fn from(value: Box<Range>) -> Self {
Expr::Range(value)
}
}

/// Root base class of all nodes in the expression tree. The base case should never be
/// instantiated directly.
///
Expand Down Expand Up @@ -433,6 +474,7 @@ pub enum ExprKind {
Cast,
Stretch,
Index,
Range,
}

impl<'py> IntoPyObject<'py> for Expr {
Expand All @@ -449,6 +491,7 @@ impl<'py> IntoPyObject<'py> for Expr {
Expr::Var(v) => v.into_bound_py_any(py),
Expr::Stretch(s) => s.into_bound_py_any(py),
Expr::Index(i) => i.into_bound_py_any(py),
Expr::Range(r) => r.into_bound_py_any(py),
}
}
}
Expand All @@ -466,6 +509,7 @@ impl<'a, 'py> FromPyObject<'a, 'py> for Expr {
ExprKind::Cast => Ok(Expr::Cast(Box::new(ob.extract()?))),
ExprKind::Stretch => Ok(Expr::Stretch(ob.extract()?)),
ExprKind::Index => Ok(Expr::Index(Box::new(ob.extract()?))),
ExprKind::Range => Ok(Expr::Range(Box::new(ob.extract()?))),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/circuit/src/classical/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod cast;
#[allow(clippy::module_inception)]
mod expr;
mod index;
mod range;
mod stretch;
mod unary;
mod value;
Expand All @@ -26,6 +27,7 @@ pub use binary::{Binary, BinaryOp};
pub use cast::Cast;
pub use expr::{Expr, ExprRef, ExprRefMut, IdentifierRef};
pub use index::Index;
pub use range::Range;
pub use stretch::Stretch;
pub use unary::{Unary, UnaryOp};
pub use value::Value;
Expand All @@ -38,6 +40,7 @@ use crate::classical::expr::binary::PyBinary;
use crate::classical::expr::cast::PyCast;
use crate::classical::expr::expr::{ExprKind, PyExpr};
use crate::classical::expr::index::PyIndex;
use crate::classical::expr::range::PyRangeExpr;
use crate::classical::expr::stretch::PyStretch;
use crate::classical::expr::unary::PyUnary;
use crate::classical::expr::value::PyValue;
Expand All @@ -52,5 +55,6 @@ pub(crate) fn register_python(m: &Bound<PyModule>) -> PyResult<()> {
m.add_class::<PyVar>()?;
m.add_class::<PyStretch>()?;
m.add_class::<PyIndex>()?;
m.add_class::<PyRangeExpr>()?;
Ok(())
}
Loading