§
    ¹³Ùg  ã                   ó–   — d Z ddlZddlmZmZ ddlmZ ddlmZm	Z	 ddl
mZ ddlmZ dd	lmZ dd
lmZ ddlmZ  G d„ de¦  «        ZdS )zClassicalFunction classé    N)ÚCallableÚOptional)Údeprecate_func)ÚQuantumCircuitÚQuantumRegister)ÚQiskitError)ÚHAS_TWEEDLEDUMé   )ÚClassicalElement)ÚClassicalFunctionVisitor)Útweedledum2qiskitc                   óD  ‡ — e Zd ZdZej         eddd¬¦  «        dˆ fd„	¦   «         ¦   «         Zd„ Ze	d	„ ¦   «         Z
e	d
„ ¦   «         Ze	d„ ¦   «         Ze	d„ ¦   «         Zdedefd„Zd„ Ze	d„ ¦   «         Z	 	 ddedeeegef                  defd„Zd„ Ze	d„ ¦   «         Zˆ xZS )ÚClassicalFunctionz5Represent a classical function and its logic network.z1.4zin Qiskit 2.0zÌUse `PhaseOracle` instead, which can be turned into a bit-flip oracle by applying Hadamard gates on the target qubit before and after the instruction, and conditioning.the instruction on the target qubit.)ÚsinceÚremoval_timelineÚadditional_msgNc                 ó>  •— t          |t          ¦  «        st          d¦  «        ‚t          j        |¦  «        | _        d| _        d| _        d| _        d| _	        t          ¦   «                              |pdt          d„ | j        D ¦   «         ¦  «        g ¬¦  «         dS )an  Creates a ``ClassicalFunction`` from Python source code in ``source``.

        The code should be a single function with types.

        Args:
            source (str): Python code with type hints.
            name (str): Optional. Default: "*classicalfunction*". ClassicalFunction name.

        Raises:
            QiskitError: If source is not a string.
        z2ClassicalFunction needs a source code as a string.Nz*classicalfunction*c              3   ó$   K  — | ]}|j         V — Œd S ©N)Úsize)Ú.0Úqregs     úh/granary/edev/quantum/lib/python3.11/site-packages/qiskit/circuit/classicalfunction/classicalfunction.pyú	<genexpr>z-ClassicalFunction.__init__.<locals>.<genexpr><   s$   è è € Ð<Ð<¨˜4œ9Ð<Ð<Ð<Ð<Ð<Ð<ó    )Ú
num_qubitsÚparams)Ú
isinstanceÚstrr   ÚastÚparseÚ_astÚ_networkÚ_scopesÚ_argsÚ_truth_tableÚsuperÚ__init__ÚsumÚqregs)ÚselfÚsourceÚnameÚ	__class__s      €r   r(   zClassicalFunction.__init__   s¨   ø€ õ* ˜&¥#Ñ&Ô&ð 	TÝÐRÑSÔSÐSÝ”I˜fÑ%Ô%ˆŒ	ØˆŒØˆŒØˆŒ
Ø ˆÔÝ‰Œ×ÒØÐ)Ð)ÝÐ<Ð<°´Ð<Ñ<Ô<Ñ<Ô<Øð 	ñ 	
ô 	
ð 	
ð 	
ð 	
r   c                 ó¶   — t          ¦   «         }|                     | j        ¦  «         |j        | _        |j        | _        |j        | _        |j        | _        dS )z&Parses and creates the logical circuitN)	r   Úvisitr"   r#   Úscopesr$   Úargsr%   r-   )r+   Ú_classical_function_visitors     r   ÚcompilezClassicalFunction.compile@   sP   € å&>Ñ&@Ô&@Ð#Ø#×)Ò)¨$¬)Ñ4Ô4Ð4Ø3Ô<ˆŒØ2Ô9ˆŒØ0Ô5ˆŒ
Ø/Ô4ˆŒ	ˆ	ˆ	r   c                 óF   — | j         €|                      ¦   «          | j         S )zReturns the logical network)r#   r4   ©r+   s    r   ÚnetworkzClassicalFunction.networkI   s!   € ð Œ=Ð Ø�LŠL‰NŒNˆNØŒ}Ðr   c                 óF   — | j         €|                      ¦   «          | j         S )zReturns the scope dict)r$   r4   r6   s    r   r1   zClassicalFunction.scopesP   s!   € ð Œ<ÐØ�LŠL‰NŒNˆNØŒ|Ðr   c                 óF   — | j         €|                      ¦   «          | j         S )z'Returns the classicalfunction arguments)r%   r4   r6   s    r   r2   zClassicalFunction.argsW   s!   € ð Œ:ÐØ�LŠL‰NŒNˆNØŒzÐr   c                 ó€   — g }| j         D ]3}|                     d„ |                     ¦   «         D ¦   «         ¦  «         Œ4|S )zÆDumps a list of scopes with their variables and types.

        Returns:
            list(dict): A list of scopes as dicts, where key is the variable name and
            value is its type.
        c                 ó&   — i | ]\  }}||d          “ŒS )r   © )r   ÚkÚvs      r   ú
<dictcomp>z+ClassicalFunction.types.<locals>.<dictcomp>h   s"   € Ð:Ð:Ð:¡D A q˜˜1˜Qœ4Ð:Ð:Ð:r   )r1   ÚappendÚitems)r+   ÚretÚscopes      r   ÚtypeszClassicalFunction.types^   sK   € ð ˆØ”[ð 	<ð 	<ˆEØ�JŠJÐ:Ð:¨E¯KªK©M¬MÐ:Ñ:Ô:Ñ;Ô;Ð;Ð;Øˆ
r   Ú	bitstringÚreturnc                 ó0   — ddl m}  || j        |¦  «        S )zçEvaluate the expression on a bitstring.

        This evaluation is done classically.

        Args:
            bitstring: The bitstring for which to evaluate.

        Returns:
            bool: result of the evaluation.
        r   ©Úsimulate)Útweedledum.classicalrI   r#   )r+   rE   rI   s      r   rI   zClassicalFunction.simulatek   s*   € ð 	2Ð1Ð1Ð1Ð1Ð1àˆx˜œ yÑ1Ô1Ð1r   c                 ó  ‡— g }t          d| j                             ¦   «         z  ¦  «        D ]=Šd                     ˆfd„| j        D ¦   «         ¦  «        }|                     |¦  «         Œ>d                     t          |¦  «        ¦  «        S )zj
        Returns a truth table.

        Returns:
            str: a bitstring with a truth table
        é   Ú c                 óT   •— g | ]$}t          t          |‰         ¦  «        ¦  «        ‘Œ%S r<   )r   Úint)r   ÚttÚpositions     €r   ú
<listcomp>z2ClassicalFunction.simulate_all.<locals>.<listcomp>ƒ   s-   ø€ Ð!TÐ!TÐ!T¸R¥#¥c¨"¨X¬,Ñ&7Ô&7Ñ"8Ô"8Ð!TÐ!TÐ!Tr   )Úranger#   Únum_pisÚjoinÚtruth_tabler@   Úreversed)r+   ÚresultÚ
sim_resultrQ   s      @r   Úsimulate_allzClassicalFunction.simulate_allz   sŒ   ø€ ð ˆÝ˜a 4¤=×#8Ò#8Ñ#:Ô#:Ñ:Ñ;Ô;ð 	&ð 	&ˆHØŸšÐ!TÐ!TÐ!TÐ!TÀ4ÔCSÐ!TÑ!TÔ!TÑUÔUˆJØ�MŠM˜*Ñ%Ô%Ð%Ð%à�wŠw•x Ñ'Ô'Ñ(Ô(Ð(r   c                 óT   — ddl m} | j        € || j        ¦  «        | _        | j        S )z&Returns (and computes) the truth tabler   rH   )rJ   rI   r&   r#   )r+   rI   s     r   rV   zClassicalFunction.truth_tableˆ   s<   € ð 	2Ð1Ð1Ð1Ð1Ð1àÔÐ$Ø ( ¨¬Ñ 7Ô 7ˆDÔØÔ Ð r   TÚregisterlessÚsynthesizerc                 ó–   — |rd}n| j         }|r || ¦  «        S ddlm} t           || j        d         ¦  «        | j        |¬¦  «        S )aÆ  Synthesis the logic network into a :class:`~qiskit.circuit.QuantumCircuit`.

        Args:
            registerless: Default ``True``. If ``False`` uses the parameter names to create
            registers with those names. Otherwise, creates a circuit with a flat quantum register.
            synthesizer: Optional. If None tweedledum's pkrm_synth is used.

        Returns:
            QuantumCircuit: A circuit implementing the logic network.
        Nr   )Ú
pkrm_synth)r-   r*   )r*   Útweedledum.synthesisr_   r   rV   r-   )r+   r\   r]   r*   r_   s        r   ÚsynthzClassicalFunction.synth‘   sn   € ð ð 	ØˆEˆEà”JˆEàð 	%Ø�;˜tÑ$Ô$Ð$à3Ð3Ð3Ð3Ð3Ð3å   ¨DÔ,<¸QÔ,?Ñ!@Ô!@ÀtÄyÐX]Ð^Ñ^Ô^Ð^r   c                 ó8   — |                       ¦   «         | _        dS )z9The definition of the classical function is its synthesisN)ra   Ú
definitionr6   s    r   Ú_definezClassicalFunction._define¬   s   € àŸ*š*™,œ,ˆŒˆˆr   c                 ó¤   ‡ — ˆ fd„‰ j         D ¦   «         }‰ j        d         d         dk    r$|                     t          dd¬¦  «        ¦  «         |S )z/The list of qregs used by the classicalfunctionc                 ó`   •— g | ]*}‰j         d          |         dk    ¯t          d|¬¦  «        ‘Œ+S )r   ÚInt1r
   ©r-   )rD   r   )r   Úargr+   s     €r   rR   z+ClassicalFunction.qregs.<locals>.<listcomp>³   s>   ø€ ÐcÐcÐc°#ÀdÄjÐQRÄmÐTWÔFXÐ\bÒFbÐFb• ¨Ð-Ñ-Ô-ÐFbÐFbÐFbr   r   rF   rg   r
   rh   )r2   rD   r@   r   )r+   r*   s   ` r   r*   zClassicalFunction.qregs°   s[   ø€ ð dÐcÐcÐc¸¼ÐcÑcÔcˆØŒ:�aŒ=˜Ô" fÒ,Ð,Ø�LŠL�¨°Ð:Ñ:Ô:Ñ;Ô;Ð;Øˆr   r   )TN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   Úrequire_in_instancer   r(   r4   Úpropertyr7   r1   r2   rD   r   ÚboolrI   rZ   rV   r   r   r   r   ra   rd   r*   Ú__classcell__)r.   s   @r   r   r      sÃ  ø€ € € € € Ø?Ð?àÔ'Ø€^ØØ(ð/ðñ ô ð
ð 
ð 
ð 
ð 
ñô ñ (Ô'ð
ð25ð 5ð 5ð ðð ñ „Xðð ðð ñ „Xðð ðð ñ „Xðð ð
ð 
ñ „Xð
ð2 #ð 2¨$ð 2ð 2ð 2ð 2ð)ð )ð )ð ð!ð !ñ „Xð!ð "ØNRð_ð _àð_ð ˜hÐ(8Ð'9¸>Ð'IÔJÔKð_ð 
ð	_ð _ð _ð _ð6'ð 'ð 'ð ðð ñ „Xðð ð ð ð r   r   )rm   r    Útypingr   r   Úqiskit.utils.deprecationr   Úqiskit.circuitr   r   Úqiskit.exceptionsr   Úqiskit.utils.optionalsr	   Úclassical_elementr   Úclassical_function_visitorr   Úutilsr   r   r<   r   r   ú<module>rz      sñ   ðð Ð à 
€
€
€
Ø %Ð %Ð %Ð %Ð %Ð %Ð %Ð %à 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø :Ð :Ð :Ð :Ð :Ð :Ð :Ð :Ø )Ð )Ð )Ð )Ð )Ð )Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø /Ð /Ð /Ð /Ð /Ð /Ø @Ð @Ð @Ð @Ð @Ð @Ø $Ð $Ð $Ð $Ð $Ð $ð[ð [ð [ð [ð [Ð(ñ [ô [ð [ð [ð [r   