
    z	iM5              	         S r SSKJr  / SQrSSKrSSKJr  \R                  " SSS	9r " S
 S\R                  \   5      r
 " S S\
\R                  \R                        5      r " S S\
\R                  \R                  \R                  \R                  4         5      r\" 5       r\" 5       rSS jrSS jr " S S\
\   5      r  S         SS jjr " S S\
\   5      r\" 5       rSS jrg)zExpression visitors.    )annotations)ExprVisitor	iter_varsiter_identifiersstructurally_equivalent	is_lvalueN   )expr_T_coT)	covariantc                  l    \ rS rSrSrSrSS jrSS jrSS jrSS jr	SS jr
SS	 jrSS
 jrSS jrSrg)r       zBase class for visitors to the :class:`Expr` tree.  Subclasses should override whichever of
the ``visit_*`` methods that they are able to handle, and should be organized such that
non-existent methods will never be called. c               $    [        SU  SU 35      e)Nzexpression visitor z has no method to handle expr )RuntimeErrorselfnodes     `/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/classical/expr/visitors.pyvisit_genericExprVisitor.visit_generic*   s    06TUYTZ[\\    c               $    U R                  U5      $ Nr   r   s     r   	visit_varExprVisitor.visit_var-       !!$''r   c               $    U R                  U5      $ r   r   r   s     r   visit_stretchExprVisitor.visit_stretch0   r   r   c               $    U R                  U5      $ r   r   r   s     r   visit_valueExprVisitor.visit_value3   r   r   c               $    U R                  U5      $ r   r   r   s     r   visit_unaryExprVisitor.visit_unary6   r   r   c               $    U R                  U5      $ r   r   r   s     r   visit_binaryExprVisitor.visit_binary9   r   r   c               $    U R                  U5      $ r   r   r   s     r   
visit_castExprVisitor.visit_cast<   r   r   c               $    U R                  U5      $ r   r   r   s     r   visit_indexExprVisitor.visit_index?   r   r   N)r   	expr.Exprreturnr   )r   zexpr.Varr2   r   )r   zexpr.Stretchr2   r   )r   z
expr.Valuer2   r   )r   z
expr.Unaryr2   r   )r   zexpr.Binaryr2   r   )r   z	expr.Castr2   r   )r   z
expr.Indexr2   r   )__name__
__module____qualname____firstlineno____doc__	__slots__r   r   r    r#   r&   r)   r,   r/   __static_attributes__r   r   r   r   r       s7    2 I](((((((r   r   c                  B    \ rS rSrSrS rS rS rS rS r	S r
S	 rSrg
)_VarWalkerImplC   r   c             #     #    Uv   g 7fr   r   r   s     r   r   _VarWalkerImpl.visit_varJ   
     
   c             #  $   #    S S h  vN   g  N7fNr   r   r   s     r   r    _VarWalkerImpl.visit_stretchM           c             #  $   #    S S h  vN   g  N7frB   r   r   s     r   r#   _VarWalkerImpl.visit_valueQ   rD   rE   c             #  V   #    UR                   R                  U 5       S h  vN   g  N7fr   operandacceptr   s     r   r&   _VarWalkerImpl.visit_unaryU        <<&&t,,,   )')c             #     #    UR                   R                  U 5       S h  vN   UR                  R                  U 5       S h  vN   g  N( N7fr   leftrK   rightr   s     r   r)   _VarWalkerImpl.visit_binaryX   =     99##D)))::$$T*** 	**!   AA
"AAAAc             #  V   #    UR                   R                  U 5       S h  vN   g  N7fr   rI   r   s     r   r,   _VarWalkerImpl.visit_cast\   rM   rN   c             #     #    UR                   R                  U 5       S h  vN   UR                  R                  U 5       S h  vN   g  N( N7fr   targetrK   indexr   s     r   r/   _VarWalkerImpl.visit_index_   =     ;;%%d+++::$$T*** 	,*rU   Nr3   r4   r5   r6   r8   r   r    r#   r&   r)   r,   r/   r9   r   r   r   r;   r;   C   s,    
 I-+-+r   r;   c                  B    \ rS rSrSrS rS rS rS rS r	S r
S	 rSrg
)_IdentWalkerImpld   r   c             #     #    Uv   g 7fr   r   r   s     r   r   _IdentWalkerImpl.visit_varg   r?   r@   c             #     #    Uv   g 7fr   r   r   s     r   r    _IdentWalkerImpl.visit_stretchj   r?   r@   c             #  $   #    S S h  vN   g  N7frB   r   r   s     r   r#   _IdentWalkerImpl.visit_valuem   s     rE   c             #  V   #    UR                   R                  U 5       S h  vN   g  N7fr   rI   r   s     r   r&   _IdentWalkerImpl.visit_unaryp   rM   rN   c             #     #    UR                   R                  U 5       S h  vN   UR                  R                  U 5       S h  vN   g  N( N7fr   rP   r   s     r   r)   _IdentWalkerImpl.visit_binarys   rT   rU   c             #  V   #    UR                   R                  U 5       S h  vN   g  N7fr   rI   r   s     r   r,   _IdentWalkerImpl.visit_castw   rM   rN   c             #     #    UR                   R                  U 5       S h  vN   UR                  R                  U 5       S h  vN   g  N( N7fr   rY   r   s     r   r/   _IdentWalkerImpl.visit_indexz   r]   rU   Nr^   r   r   r   r`   r`   d   s*    I-+-+r   r`   c              #  J   #    U R                  [        5       Sh  vN   g N7f)a  Get an iterator over the :class:`~.expr.Var` nodes referenced at any level in the given
:class:`~.expr.Expr`.

Examples:
    Print out the name of each :class:`.ClassicalRegister` encountered::

        from qiskit.circuit import ClassicalRegister
        from qiskit.circuit.classical import expr

        cr1 = ClassicalRegister(3, "a")
        cr2 = ClassicalRegister(3, "b")

        for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
            if isinstance(node.var, ClassicalRegister):
                print(node.var.name)

.. seealso::
    :func:`iter_identifiers`
        Get an iterator over all identifier nodes in the expression, including
        both :class:`~.expr.Var` and :class:`~.expr.Stretch` nodes.
N)rK   _VAR_WALKERr   s    r   r   r      s     , {{;'''   #!#c              #  J   #    U R                  [        5       Sh  vN   g N7f)a  Get an iterator over the :class:`~.expr.Var` and :class:`~.expr.Stretch`
nodes referenced at any level in the given :class:`~.expr.Expr`.

Examples:
    Print out the name of each :class:`.ClassicalRegister` encountered::

        from qiskit.circuit import ClassicalRegister
        from qiskit.circuit.classical import expr

        cr1 = ClassicalRegister(3, "a")
        cr2 = ClassicalRegister(3, "b")

        for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
            if isinstance(node.var, ClassicalRegister):
                print(node.var.name)

.. seealso::
    :func:`iter_vars`
        Get an iterator over just the :class:`~.expr.Var` nodes in the expression.
N)rK   _IDENT_WALKERrr   s    r   r   r      s     * {{=)))rs   c                  L    \ rS rSrSrSS jrS rS rS rS r	S r
S	 rS
 rSrg)_StructuralEquivalenceImpl   self_key	other_keyotherc                (    X l         X0l        Xl        g r   ry   )r   r|   rz   r{   s       r   __init__#_StructuralEquivalenceImpl.__init__   s     "
r   c                  U R                   R                  UR                  Ld$  U R                   R                  UR                  :w  a  gU R                  b  U R                  UR                  5      =nc  UR                  nU R
                  b(  U R                  U R                   R                  5      =nc  U R                   R                  nX#:H  $ NF)r|   	__class__typerz   varr{   )r   r   self_var	other_vars       r   r   $_StructuralEquivalenceImpl.visit_var   s    ::t~~5DII9U== txx1H%HX$QxxH>>!4>>$**..3Q&Qi%Z

I$$r   c                   U R                   R                  UR                  La  gUR                  U R                   R                  :H  $ r   )r|   r   r   r   s     r   r    (_StructuralEquivalenceImpl.visit_stretch   s2    ::t~~5xx4::>>))r   c                   UR                   U R                  R                   L =(       aM    UR                  U R                  R                  :H  =(       a#    UR                  U R                  R                  :H  $ r   )r   r|   r   valuer   s     r   r#   &_StructuralEquivalenceImpl.visit_value   sQ    NNdjj222 /		TZZ__,/

djj...	
r   c               D   U R                   R                  UR                  LdG  U R                   R                  UR                  Ld$  U R                   R                  UR                  :w  a  gU R                   R                  U l         UR                  R                  U 5      $ r   )r|   r   opr   rJ   rK   r   s     r   r&   &_StructuralEquivalenceImpl.visit_unary   si    JJ  6zz}}DGG+zz$))+ZZ''
||""4((r   c                  U R                   R                  UR                  LdG  U R                   R                  UR                  Ld$  U R                   R                  UR                  :w  a  gU R                   nUR                  U l         UR                  R                  U 5      (       d  gUR                  U l         UR                  R                  U 5      $ r   )r|   r   r   r   rQ   rK   rR   r   r   r|   s      r   r)   '_StructuralEquivalenceImpl.visit_binary   s    JJ  6zz}}DGG+zz$))+

ZZ
yy%%[[
zz  &&r   c                   U R                   R                  UR                  Ld$  U R                   R                  UR                  :w  a  gU R                   R                  U l         UR                  R	                  U 5      $ r   )r|   r   r   rJ   rK   r   s     r   r,   %_StructuralEquivalenceImpl.visit_cast   sT    ::t~~5DII9UZZ''
||""4((r   c               f   U R                   R                  UR                  Ld$  U R                   R                  UR                  :w  a  gU R                   nUR                  U l         UR                  R	                  U 5      (       d  gUR
                  U l         UR
                  R	                  U 5      $ r   )r|   r   r   rZ   rK   r[   r   s      r   r/   &_StructuralEquivalenceImpl.visit_index   sz    ::t~~5DII9U

\\
{{!!$''[[
zz  &&r   )r|   r{   rz   N)r|   r1   )r3   r4   r5   r6   r8   r~   r   r    r#   r&   r)   r,   r/   r9   r   r   r   rw   rw      s1    I
%*

)')'r   rw   c                8    U R                  [        XU5      5      $ )a  Do these two expressions have exactly the same tree structure, up to some key function for
the :class:`~.expr.Var` objects?

In other words, are these two expressions the exact same trees, except we compare the
:attr:`.Var.var` fields by calling the appropriate ``*_var_key`` function on them, and comparing
that output for equality.  This function does not allow any semantic "equivalences" such as
asserting that ``a == b`` is equivalent to ``b == a``; the evaluation order of the operands
could, in general, cause such a statement to be false (consider hypothetical ``extern``
functions that access global state).

There's no requirements on the key functions, except that their outputs should have general
``__eq__`` methods.  If a key function returns ``None``, the variable will be used verbatim
instead.

Args:
    left: one of the :class:`~.expr.Expr` nodes.
    right: the other :class:`~.expr.Expr` node.
    left_var_key: a callable whose output should be used when comparing :attr:`.Var.var`
        attributes.  If this argument is ``None`` or its output is ``None`` for a given
        variable in ``left``, the variable will be used verbatim.
    right_var_key: same as ``left_var_key``, but used on the variables in ``right`` instead.

Examples:
    Comparing two expressions for structural equivalence, with no remapping of the variables.
    These are different because the different :class:`.Clbit` instances compare differently::

        >>> from qiskit.circuit import Clbit
        >>> from qiskit.circuit.classical import expr
        >>> left_bits = [Clbit(), Clbit()]
        >>> right_bits = [Clbit(), Clbit()]
        >>> left = expr.logic_and(expr.logic_not(left_bits[0]), left_bits[1])
        >>> right = expr.logic_and(expr.logic_not(right_bits[0]), right_bits[1])
        >>> expr.structurally_equivalent(left, right)
        False

    Comparing the same two expressions, but this time using mapping functions that associate
    the bits with simple indices::

        >>> left_key = {var: i for i, var in enumerate(left_bits)}.get
        >>> right_key = {var: i for i, var in enumerate(right_bits)}.get
        >>> expr.structurally_equivalent(left, right, left_key, right_key)
        True
)rK   rw   )rQ   rR   left_var_keyright_var_keys       r   r   r     s    b ;;1%}UVVr   c                  B    \ rS rSrSrS rS rS rS rS r	S r
S	 rSrg
)_IsLValueImpli9  r   c                   g)NTr   r   s     r   r   _IsLValueImpl.visit_var<  s    r   c                   gr   r   r   s     r   r    _IsLValueImpl.visit_stretch?      r   c                   gr   r   r   s     r   r#   _IsLValueImpl.visit_valueB  r   r   c                   gr   r   r   s     r   r&   _IsLValueImpl.visit_unaryE  r   r   c                   gr   r   r   s     r   r)   _IsLValueImpl.visit_binaryH  r   r   c                   gr   r   r   s     r   r,   _IsLValueImpl.visit_castK  r   r   c               8    UR                   R                  U 5      $ r   )rZ   rK   r   s     r   r/   _IsLValueImpl.visit_indexN  s    {{!!$''r   Nr^   r   r   r   r   r   9  s*    I(r   r   c               ,    U R                  [        5      $ )aB  Return whether this expression can be used in l-value positions, that is, whether it has a
well-defined location in memory, such as one that might be writeable.

Being an l-value is a necessary but not sufficient for this location to be writeable; it is
permissible that a larger object containing this memory location may not allow writing from
the scope that attempts to write to it.  This would be an access property of the containing
program, however, and not an inherent property of the expression system.

A constant expression is never an lvalue.

Examples:
    Literal values are never l-values; there's no memory location associated with (for example)
    the constant ``1``::

        >>> from qiskit.circuit.classical import expr
        >>> expr.is_lvalue(expr.lift(2))
        False

    :class:`~.expr.Var` nodes are always l-values, because they always have some associated
    memory location::

        >>> from qiskit.circuit.classical import types
        >>> from qiskit.circuit import Clbit
        >>> expr.is_lvalue(expr.Var.new("a", types.Bool()))
        True
        >>> expr.is_lvalue(expr.lift(Clbit()))
        True

    Currently there are no unary or binary operations on variables that can produce an l-value
    expression, but it is likely in the future that some sort of "indexing" operation will be
    added, which could produce l-values::

        >>> a = expr.Var.new("a", types.Uint(8))
        >>> b = expr.Var.new("b", types.Uint(8))
        >>> expr.is_lvalue(a) and expr.is_lvalue(b)
        True
        >>> expr.is_lvalue(expr.bit_and(a, b))
        False
)rK   
_IS_LVALUErr   s    r   r   r   U  s    P ;;z""r   )r   r1   r2   ztyping.Iterator[expr.Var])r   r1   r2   z5typing.Iterator[typing.Union[expr.Var, expr.Stretch]])NN)
rQ   r1   rR   r1   r   0typing.Callable[[typing.Any], typing.Any] | Noner   r   r2   bool)r   r1   r2   r   )r7   
__future__r   __all__typing r
   TypeVarr   Genericr   IterableVarr;   UnionStretchr`   rq   ru   r   r   r   rw   r   r   r   r   r   r   r   <module>r      s&    "  w$/ (&..'  (F+[!:; +B+{6??6<<$,,@V3W#XY +6  "(2*0N'T!2 N'h FJFJ	1W
1W1W C1W D	1W
 
1Wh(K% (2 _
(#r   