U
    ZÊ¹j�  ã                   @   s´   d Z dgZddlmZ ddlmZmZmZmZm	Z	m
Z
mZmZmZmZ ddlmZ dd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZG dd„ dƒZdS )a  

qasm.py - Functions to parse a set of qasm commands into a SymPy Circuit.

Examples taken from Chuang's page: https://web.archive.org/web/20220120121541/https://www.media.mit.edu/quanta/qasm2circ/

The code returns a circuit and an associated list of labels.

>>> from sympy.physics.quantum.qasm import Qasm
>>> q = Qasm('qubit q0', 'qubit q1', 'h q0', 'cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*H(1)

>>> q = Qasm('qubit q0', 'qubit q1', 'cnot q0,q1', 'cnot q1,q0', 'cnot q0,q1')
>>> q.get_circuit()
CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
ÚQasmé    )Úprod)
ÚHÚCNOTÚXÚZÚCGateÚCGateSÚSWAPÚSÚTÚCPHASE)ÚMzc                 C   s   t |  ¡ Ž S ©N)r   Ú
splitlines)Úlines© r   úY/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/physics/quantum/qasm.pyÚ	read_qasm   s    r   c                 C   s   t t| ƒ ¡ Ž S r   )r   ÚopenÚ	readlines)Úfilenamer   r   r   Úread_qasm_file   s    r   c                 C   s   ||  d S )z­Reorder qubit indices from largest to smallest.

    >>> from sympy.physics.quantum.qasm import flip_index
    >>> flip_index(0, 2)
    1
    >>> flip_index(1, 2)
    0
    é   r   )ÚiÚnr   r   r   Ú
flip_index"   s    	r   c                 C   s   d| kr| S |   d¡d S )zìRemove everything following comment # characters in line.

    >>> from sympy.physics.quantum.qasm import trim
    >>> trim('nothing happens here')
    'nothing happens here'
    >>> trim('something #happens here')
    'something '
    ú#r   )Úsplit)Úliner   r   r   Útrim-   s    	r    c                 C   s   t |ƒ}t| | ¡|ƒS )zÔGet qubit labels from the rest of the line,and return indices

    >>> from sympy.physics.quantum.qasm import get_index
    >>> get_index('q0', ['q0', 'q1'])
    1
    >>> get_index('q1', ['q0', 'q1'])
    0
    )Úlenr   Úindex)ÚtargetÚlabelsZnqr   r   r   Ú	get_index:   s    	r%   c                    s   ‡ fdd„| D ƒS )Nc                    s   g | ]}t |ˆ ƒ‘qS r   )r%   )Ú.0Út©r$   r   r   Ú
<listcomp>G   s     zget_indices.<locals>.<listcomp>r   )Útargetsr$   r   r(   r   Úget_indicesF   s    r+   c                 c   s&   | D ]}t |ƒ}| ¡ rq|V  qd S r   )r    Úisspace)Úargsr   r   r   r   ÚnonblankI   s    r.   c                 C   s:   |   ¡ }d |dd … ¡}t|d ƒdd„ |  d¡D ƒfS )Nú r   r   c                 S   s   g | ]}|  ¡ ‘qS r   )Ústrip)r&   Úsr   r   r   r)   T   s     zfullsplit.<locals>.<listcomp>ú,)r   ÚjoinÚ
fixcommand)r   ÚwordsÚrestr   r   r   Ú	fullsplitQ   s    r7   c                 C   s4   dg}|   ¡ } |D ]}|  |d¡} q| dkr0dS | S )zwFix Qasm command names.

    Remove all of forbidden characters from command c, and
    replace 'def' with 'qdef'.
    ú-Ú ÚdefÚqdef)ÚlowerÚreplace)ÚcZforbidden_charactersÚcharr   r   r   r4   V   s    r4   c                 C   s   |   dd¡} |   dd¡} | S )zäReplace explicit quotes in a string.

    >>> from sympy.physics.quantum.qasm import stripquotes
    >>> stripquotes("'S'") == 'S'
    True
    >>> stripquotes('"S"') == 'S'
    True
    >>> stripquotes('S') == 'S'
    True
    ú"r9   ú')r=   )r1   r   r   r   Ústripquotesd   s    rB   c                   @   sÊ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zd1dd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ ZdS )2r   aV  Class to form objects from Qasm lines

    >>> from sympy.physics.quantum.qasm import Qasm
    >>> q = Qasm('qubit q0', 'qubit q1', 'h q0', 'cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*H(1)
    >>> q = Qasm('qubit q0', 'qubit q1', 'cnot q0,q1', 'cnot q1,q0', 'cnot q0,q1')
    >>> q.get_circuit()
    CNOT(1,0)*CNOT(0,1)*CNOT(1,0)
    c                 O   s,   i | _ g | _g | _i | _| j|Ž  || _d S r   )ÚdefsÚcircuitr$   ÚinitsÚaddÚkwargs)Úselfr-   rG   r   r   r   Ú__init__~   s    
zQasm.__init__c                 G   s¬   t |ƒD ]ž}t|ƒ\}}| j |¡r|| j |¡}|  |¡}t|ƒdkr\| j ||d ƒ¡ q¦| j ||d d… |d ƒ¡ qt| |ƒršt	| |ƒ}||Ž  qt
d| ƒ qd S )Nr   r   éÿÿÿÿz!Function %s not defined. Skipping)r.   r7   rC   ÚgetÚindicesr!   rD   ÚappendÚhasattrÚgetattrÚprint)rH   r   r   Úcommandr6   ÚfunctionrL   r   r   r   rF   †   s    
 


zQasm.addc                 C   s   t t| jƒƒS r   )r   ÚreversedrD   ©rH   r   r   r   Úget_circuit–   s    zQasm.get_circuitc                 C   s   t t| jƒƒS r   )ÚlistrS   r$   rT   r   r   r   Ú
get_labels™   s    zQasm.get_labelsc                 C   s8   ddl m} |  ¡ |  ¡  }}||t|ƒ|| jd� d S )Nr   )ÚCircuitPlot)r$   rE   )Ú!sympy.physics.quantum.circuitplotrX   rU   rW   r!   rE   )rH   rX   rD   r$   r   r   r   Úplotœ   s    z	Qasm.plotNc                 C   s   | j  |¡ |r|| j|< d S r   )r$   rM   rE   )rH   ÚargÚinitr   r   r   Úqubit¡   s     z
Qasm.qubitc                 C   s   t || jƒS r   )r+   r$   ©rH   r-   r   r   r   rL   ¥   s    zQasm.indicesc                 C   s   t || jƒS r   )r%   r$   ©rH   r[   r   r   r   r"   ¨   s    z
Qasm.indexc                 G   s   d S r   r   r^   r   r   r   Únop«   s    zQasm.nopc                 C   s   | j  t|  |¡ƒ¡ d S r   )rD   rM   r   r"   r_   r   r   r   Úx®   s    zQasm.xc                 C   s   | j  t|  |¡ƒ¡ d S r   )rD   rM   r   r"   r_   r   r   r   Úz±   s    zQasm.zc                 C   s   | j  t|  |¡ƒ¡ d S r   )rD   rM   r   r"   r_   r   r   r   Úh´   s    zQasm.hc                 C   s   | j  t|  |¡ƒ¡ d S r   )rD   rM   r   r"   r_   r   r   r   r1   ·   s    zQasm.sc                 C   s   | j  t|  |¡ƒ¡ d S r   )rD   rM   r   r"   r_   r   r   r   r'   º   s    zQasm.tc                 C   s   | j  t|  |¡ƒ¡ d S r   )rD   rM   r   r"   r_   r   r   r   Úmeasure½   s    zQasm.measurec                 C   s   | j  t|  ||g¡Ž ¡ d S r   )rD   rM   r   rL   ©rH   Úa1Úa2r   r   r   ÚcnotÀ   s    z	Qasm.cnotc                 C   s   | j  t|  ||g¡Ž ¡ d S r   )rD   rM   r
   rL   re   r   r   r   ÚswapÃ   s    z	Qasm.swapc                 C   s   | j  t|  ||g¡Ž ¡ d S r   )rD   rM   r   rL   re   r   r   r   ÚcphaseÆ   s    zQasm.cphasec                 C   s4   |   |||g¡\}}}| j t||ft|ƒƒ¡ d S r   )rL   rD   rM   r	   r   )rH   rf   rg   Úa3Úi1Úi2Zi3r   r   r   ÚtoffoliÉ   s    zQasm.toffolic                 C   s,   |   ||g¡\}}| j t|t|ƒƒ¡ d S r   )rL   rD   rM   r   r   ©rH   rf   rg   ÚfiÚfjr   r   r   ÚcxÍ   s    zQasm.cxc                 C   s,   |   ||g¡\}}| j t|t|ƒƒ¡ d S r   )rL   rD   rM   r   r   ro   r   r   r   ÚczÑ   s    zQasm.czc                 G   s   t d|ƒ d S )Nz$defbox not supported yet. Skipping: )rP   r^   r   r   r   ÚdefboxÕ   s    zQasm.defboxc                 C   sR   ddl m}m} t|ƒ}t|ƒ}t|ƒ}|dkr@||ƒ| j|< n||ƒ| j|< d S )Nr   )ÚCreateOneQubitGateÚCreateCGate)rY   ru   rv   Úintr4   rB   rC   )rH   ÚnameZ	ncontrolsÚsymbolru   rv   rQ   r   r   r   r;   Ø   s    z	Qasm.qdef)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rI   rF   rU   rW   rZ   r]   rL   r"   r`   ra   rb   rc   r1   r'   rd   rh   ri   rj   rn   rr   rs   rt   r;   r   r   r   r   r   s   s0   

N)r}   Ú__all__Úmathr   Zsympy.physics.quantum.gater   r   r   r   r   r	   r
   r   r   r   rY   r   r   r   r   r    r%   r+   r.   r7   r4   rB   r   r   r   r   r   Ú<module>   s    ÿ0