o
    8Va                     @   s   d Z dg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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: http://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    )
HCNOTXZCGateCGateSSWAPSTCPHASE)Mzc                 C   s   t |   S N)r   
splitlines)lines r   </usr/lib/python3/dist-packages/sympy/physics/quantum/qasm.py	read_qasm      r   c                 C   s   t t|   S r   )r   open	readlines)filenamer   r   r   read_qasm_file   s   r   c                 C   s   d}| D ]}||9 }q|S )N   r   )cpZcir   r   r   prod    s   
r   c                 C   s   ||  d S )zReorder 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   r   )inr   r   r   
flip_index&   s   	r   c                 C   s   d| vr| S |  dd S )zRemove 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   trim1   s   	r#   c                 C   s   t |}t|| |S )zGet 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>K   s    zget_indices.<locals>.<listcomp>r   )targetsr'   r   r+   r   get_indicesJ   s   r.   c                 c   s(    | D ]}t |}| rq|V  qd S r   )r#   isspace)argsr"   r   r   r   nonblankM   s   r1   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,   X   s    zfullsplit.<locals>.<listcomp>,)r!   join
fixcommand)r"   Zwordsrestr   r   r   	fullsplitU   s    r9   c                 C   s4   dg}|   } |D ]}| |d} q	| dkrdS | S )zwFix Qasm command names.

    Remove all of forbidden characters from command c, and
    replace 'def' with 'qdef'.
    - defqdef)lowerreplace)r   Zforbidden_characterscharr   r   r   r7   Z   s   r7   c                 C   s   |  dd} |  dd} | S )zReplace explicit quotes in a string.

    >>> from sympy.physics.quantum.qasm import stripquotes
    >>> stripquotes("'S'") == 'S'
    True
    >>> stripquotes('"S"') == 'S'
    True
    >>> stripquotes('S') == 'S'
    True
    "r;   ')r?   )r4   r   r   r   stripquotesh   s   rC   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)selfr0   rH   r   r   r   __init__   s   

zQasm.__init__c                 G   s   t |D ]O}t|\}}| j|r>| j|}| |}t|dkr.| j||d  q| j||d d |d  qt| |rMt	| |}||  qt
d|  qd S )Nr   r   z!Function %s not defined. Skipping)r1   r9   rD   getindicesr$   rE   appendhasattrgetattrprint)rI   r   r"   commandr8   functionrM   r   r   r   rG      s   
 


zQasm.addc                 C      t t| jS r   )r   reversedrE   rI   r   r   r   get_circuit      zQasm.get_circuitc                 C   rT   r   )listrU   r'   rV   r   r   r   
get_labels   rX   zQasm.get_labelsc                 C   s8   ddl m} |  |  }}||t||| jd d S )Nr   )CircuitPlot)r'   rF   )!sympy.physics.quantum.circuitplotr[   rW   rZ   r$   rF   )rI   r[   rE   r'   r   r   r   plot   s   z	Qasm.plotNc                 C   s"   | j | |r|| j|< d S d S r   )r'   rN   rF   )rI   argZinitr   r   r   qubit   s   z
Qasm.qubitc                 C      t || jS r   )r.   r'   rI   r0   r   r   r   rM      r   zQasm.indicesc                 C   r`   r   )r(   r'   rI   r^   r   r   r   r%      r   z
Qasm.indexc                 G   s   d S r   r   ra   r   r   r   nop   s   zQasm.nopc                 C      | j t| | d S r   )rE   rN   r   r%   rb   r   r   r   x      zQasm.xc                 C   rd   r   )rE   rN   r   r%   rb   r   r   r   z   rf   zQasm.zc                 C   rd   r   )rE   rN   r   r%   rb   r   r   r   h   rf   zQasm.hc                 C   rd   r   )rE   rN   r
   r%   rb   r   r   r   r4      rf   zQasm.sc                 C   rd   r   )rE   rN   r   r%   rb   r   r   r   r*      rf   zQasm.tc                 C   rd   r   )rE   rN   r   r%   rb   r   r   r   measure   rf   zQasm.measurec                 C      | j t| ||g  d S r   )rE   rN   r   rM   rI   a1a2r   r   r   cnot      z	Qasm.cnotc                 C   rj   r   )rE   rN   r	   rM   rk   r   r   r   swap   ro   z	Qasm.swapc                 C   rj   r   )rE   rN   r   rM   rk   r   r   r   cphase   ro   zQasm.cphasec                 C   s4   |  |||g\}}}| jt||ft| d S r   )rM   rE   rN   r   r   )rI   rl   rm   a3Zi1Zi2Zi3r   r   r   toffoli   s   zQasm.toffolic                 C   ,   |  ||g\}}| jt|t| d S r   )rM   rE   rN   r   r   rI   rl   rm   fiZfjr   r   r   cx      zQasm.cxc                 C   rt   r   )rM   rE   rN   r   r   ru   r   r   r   cz   rx   zQasm.czc                 G   s   t d| d S )Nz$defbox not supported yet. Skipping: )rQ   ra   r   r   r   defbox   rX   zQasm.defboxc                 C   sT   ddl m}m} t|}t|}t|}|dkr!||| j|< d S ||| j|< d S )Nr   )CreateOneQubitGateCreateCGate)r\   r{   r|   intr7   rC   rD   )rI   nameZ	ncontrolssymbolr{   r|   rR   r   r   r   r=      s   z	Qasm.qdefr   )__name__
__module____qualname____doc__rJ   rG   rW   rZ   r]   r_   rM   r%   rc   re   rg   rh   r4   r*   ri   rn   rp   rq   rs   rw   ry   rz   r=   r   r   r   r   r   w   s2    

N)r   __all__Zsympy.physics.quantum.gater   r   r   r   r   r   r	   r
   r   r   r\   r   r   r   r   r   r#   r(   r.   r1   r9   r7   rC   r   r   r   r   r   <module>   s"    0