
    z	ie                        S r SSKJr  SSKrSSKJrJrJr  SSKJ	r	   " S S\	R                  \	R                     5      rg)	zYShared helper utility for mapping classical resources from one circuit or DAG to another.    )annotationsN   )BitClbitClassicalRegister)exprc                      \ rS rSrSrSr SSS.       SS jjjrSS jrSS	.S
 jrS r	SS jr
S rS rS rS rS rS rS rSrg)VariableMapper   a  Stateful helper class that manages the mapping of variables in conditions and expressions.

This is designed to be used by both :class:`.QuantumCircuit` and :class:`.DAGCircuit` when
managing operations that need to map classical resources from one circuit to another.

The general usage is to initialise this at the start of a many-block mapping operation, then
call its :meth:`map_condition`, :meth:`map_target` or :meth:`map_expr` methods as appropriate,
which will return the new object that should be used.

If an ``add_register`` callable is given to the initializer, the mapper will use it to attempt
to add new aliasing registers to the outer circuit object, if there is not already a suitable
register for the mapping available in the circuit.  If this parameter is not given, a
``ValueError`` will be raised instead.  The given ``add_register`` callable may choose to raise
its own exception.)target_cregsregister_mapbit_mapvar_mapadd_registerN)r   c               j    [        U5      U l        0 U l        X l        U=(       d    0 U l        X@l        g N)tupler   r   r   r   r   )selfr   r   r   r   s        `/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/_classical_resource_map.py__init__VariableMapper.__init__-   s/     ",/}"(    c                   U R                   R                  UR                  5      =nb  U$ U Vs/ s H  o0R                  U   PM     nnU R                   H  nU[        U5      :X  d  M  Un  OB   U R                  c  [        SUR                   S35      e[        US9nU R                  U5        X R                   UR                  '   U$ s  snf )zuMap the target's registers to suitable equivalents in the destination, adding an
extra one if there's no exact match.
Register '(' has no counterpart in the destination.bits)	r   getnamer   r   listr   
ValueErrorr   )r   theirsmapped_theirsbitmapped_bitsourss         r   _map_registerVariableMapper._map_register;   s     "..226;;??ML  4:;FS||C(F;%%Dd4j( $ &
   ( :fkk]:b!cdd-;?Mm,)6&++& <s   C	F)allow_reorderc                ^^ Uc  g[        U[        R                  5      (       a  U R                  U5      $ Uu  p4[        U[        5      (       a  U R
                  U   U4$ U(       d  U R                  U5      U4$ U Vs/ s H  oPR
                  U   PM     nn[        U5      nU R                   H  nU[        U5      :X  d  M  Un	  OH   U R                  c  U R                  SUR                   S35      e[        US9n	U R                  U	5        [        U5       V
Vs0 s H  u  pXZ_M	     snn
mUS[        U5       S3 SSS2   m[        SR!                  UU4S	 jU	 5       5      SSS2   S
5      nX4$ s  snf s  snn
f )a  Map the given ``condition`` so that it only references variables in the destination
circuit (as given to this class on initialization).

If ``allow_reorder`` is ``True``, then when a legacy condition (the two-tuple form) is made
on a register that has a counterpart in the destination with all the same (mapped) bits but
in a different order, then that register will be used and the value suitably modified to
make the equality condition work.  This is maintaining legacy (tested) behavior of
:meth:`.DAGCircuit.compose`; nowhere else does this, and in general this would require *far*
more complex classical rewriting than Terra needs to worry about in the full expression era.
Nr   r   r   0b c              3  4   >#    U  H  nTTU      v   M     g 7fr    ).0r$   	new_order
value_bitss     r   	<genexpr>/VariableMapper.map_condition.<locals>.<genexpr>s   s     "W#:in#=s      )
isinstancer   Exprmap_exprr   r   r'   setr   r   exc_typer   r   	enumeratelenintjoin)r   	conditionr)   targetvaluer$   mapped_bits_ordermapped_bits_setregisterr#   imapped_valuer2   r3   s               @@r   map_conditionVariableMapper.map_conditionM   s    i++==++!fe$$LL(%00&&v.66 ;AA&3\\#.&A/0))H#h-/ ( *
   (mm -UV  .3DEMm,*34E*FG*FSV*FG	aF}A-."5
277"W"WWX\Z\X\]_`a,,! B Hs   ?E6E;c                   [        U[        5      (       a  U R                  U   $ [        U[        5      (       a  U R	                  U5      $ U R                  U5      $ )zMap the real-time variables in a ``target`` of a :class:`.SwitchCaseOp` to the new
circuit, as defined in the ``circuit`` argument of the initializer of this class.)r7   r   r   r   r'   r9   )r   rA   s     r   
map_targetVariableMapper.map_targetv   sN     fe$$<<''f/00%%f--}}V$$r   c               $    UR                  U 5      $ )zEMap the variables in an :class:`~.expr.Expr` node to the new circuit.)acceptr   nodes     r   r9   VariableMapper.map_expr   s    {{4  r   c                  [        UR                  [        5      (       a8  [        R                  " U R
                  UR                     UR                  5      $ [        UR                  [        5      (       a:  [        R                  " U R                  UR                  5      UR                  5      $ U R                  R                  X5      $ r   )r7   varr   r   Varr   typer   r'   r   r   rO   s     r   	visit_varVariableMapper.visit_var   s    dhh&&88DLL2DII>>dhh 12288D..txx8$))DD||++r   c               8    U R                   R                  X5      $ r   )r   r   rO   s     r   visit_stretchVariableMapper.visit_stretch   s    ||++r   c               X    [         R                  " UR                  UR                  5      $ r   )r   ValuerB   rU   rO   s     r   visit_valueVariableMapper.visit_value   s    zz$**dii00r   c                   [         R                  " UR                  UR                  R	                  U 5      UR
                  5      $ r   )r   UnaryopoperandrN   rU   rO   s     r   visit_unaryVariableMapper.visit_unary   s,    zz$''4<<#6#6t#<diiHHr   c                   [         R                  " UR                  UR                  R	                  U 5      UR
                  R	                  U 5      UR                  5      $ r   )r   Binaryra   leftrN   rightrU   rO   s     r   visit_binaryVariableMapper.visit_binary   s@    {{477DII$4$4T$:DJJ<M<Md<SUYU^U^__r   c                   [         R                  " UR                  R                  U 5      UR                  UR
                  S9$ )N)implicit)r   Castrb   rN   rU   rl   rO   s     r   
visit_castVariableMapper.visit_cast   s,    yy,,T2DIIVVr   c                   [         R                  " UR                  R                  U 5      UR                  R                  U 5      UR
                  5      $ r   )r   IndexrA   rN   indexrU   rO   s     r   visit_indexVariableMapper.visit_index   s7    zz$++,,T2DJJ4E4Ed4KTYYWWr   )r   r   r   r   r   r   )r   z"typing.Iterable[ClassicalRegister]r   ztyping.Mapping[Bit, Bit]r   zGtyping.Mapping[expr.Var | expr.Stretch, expr.Var | expr.Stretch] | Noner   z1typing.Callable[[ClassicalRegister], None] | None)r"   r   returnr   )rP   	expr.Exprru   rv   )__name__
__module____qualname____firstlineno____doc__	__slots__r   r'   rH   rK   r9   rV   rY   r]   rc   ri   rn   rs   __static_attributes__r0   r   r   r
   r
      s    & WI \`	) KO)8) *) Y	) H)$ <A '-R%!,,1I`WXr   r
   )r{   
__future__r   typingr.   r   r   r   	classicalr   ExprVisitorr8   r
   r0   r   r   <module>r      s9    ` "  + + CXT%%dii0 CXr   