B
    [                 @   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e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   9lib/python3.7/site-packages/sympy/physics/quantum/qasm.py	read_qasm   s    r   c             C   s   t t|   S )N)r   open	readlines)filenamer   r   r   read_qasm_file   s    r   c             C   s   d}x| D ]}||9 }q
W |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| k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   )Ztargetsr%   r   )r%   r   get_indicesJ   s    r*   c             c   s*   x$| D ]}t |}| rq|V  qW d S )N)r!   isspace)argsr    r   r   r   nonblankM   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)   X   s    zfullsplit.<locals>.<listcomp>,)r   join
fixcommand)r    Zwordsrestr   r   r   	fullsplitU   s    r5   c             C   s8   dg}|   } x|D ]}| |d} qW | dkr4d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   r3   Z   s    
r3   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
    "r7   ')r;   )r0   r   r   r   stripquotesh   s    r?   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 )N)defscircuitr%   initsaddkwargs)selfr,   rD   r   r   r   __init__   s    
zQasm.__init__c             G   s   xt |D ]}t|\}}| j|r~| j|}| |}t|dkr^| j||d  q| j||d d |d  q
t| |rt	| |}||  q
t
d|  q
W d S )Nr   r   z!Function %s not defined. Skipping)r-   r5   r@   getindicesr"   rA   appendhasattrgetattrprint)rE   r   r    commandr4   ZfunctionrI   r   r   r   rC      s    
 


zQasm.addc             C   s   t t| jS )N)r   reversedrA   )rE   r   r   r   get_circuit   s    zQasm.get_circuitc             C   s   t t| jS )N)listrO   r%   )rE   r   r   r   
get_labels   s    zQasm.get_labelsc             C   s8   ddl m} |  |   }}||t||| jd d S )Nr   )CircuitPlot)r%   rB   )!sympy.physics.quantum.circuitplotrS   rP   rR   r"   rB   )rE   rS   rA   r%   r   r   r   plot   s    z	Qasm.plotNc             C   s   | j | |r|| j|< d S )N)r%   rJ   rB   )rE   argZinitr   r   r   qubit   s     z
Qasm.qubitc             C   s   t || jS )N)r*   r%   )rE   r,   r   r   r   rI      s    zQasm.indicesc             C   s   t || jS )N)r&   r%   )rE   rV   r   r   r   r#      s    z
Qasm.indexc             G   s   d S )Nr   )rE   r,   r   r   r   nop   s    zQasm.nopc             C   s   | j t| | d S )N)rA   rJ   r   r#   )rE   rV   r   r   r   x   s    zQasm.xc             C   s   | j t| | d S )N)rA   rJ   r   r#   )rE   rV   r   r   r   z   s    zQasm.zc             C   s   | j t| | d S )N)rA   rJ   r   r#   )rE   rV   r   r   r   h   s    zQasm.hc             C   s   | j t| | d S )N)rA   rJ   r
   r#   )rE   rV   r   r   r   r0      s    zQasm.sc             C   s   | j t| | d S )N)rA   rJ   r   r#   )rE   rV   r   r   r   r(      s    zQasm.tc             C   s   | j t| | d S )N)rA   rJ   r   r#   )rE   rV   r   r   r   measure   s    zQasm.measurec             C   s   | j t| ||g  d S )N)rA   rJ   r   rI   )rE   a1a2r   r   r   cnot   s    z	Qasm.cnotc             C   s   | j t| ||g  d S )N)rA   rJ   r	   rI   )rE   r]   r^   r   r   r   swap   s    z	Qasm.swapc             C   s   | j t| ||g  d S )N)rA   rJ   r   rI   )rE   r]   r^   r   r   r   cphase   s    zQasm.cphasec             C   s4   |  |||g\}}}| jt||ft| d S )N)rI   rA   rJ   r   r   )rE   r]   r^   Za3Zi1Zi2Zi3r   r   r   toffoli   s    zQasm.toffolic             C   s,   |  ||g\}}| jt|t| d S )N)rI   rA   rJ   r   r   )rE   r]   r^   fifjr   r   r   cx   s    zQasm.cxc             C   s,   |  ||g\}}| jt|t| d S )N)rI   rA   rJ   r   r   )rE   r]   r^   rc   rd   r   r   r   cz   s    zQasm.czc             G   s   t d| d S )Nz$defbox not supported yet. Skipping: )rM   )rE   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)rT   rh   ri   intr3   r?   r@   )rE   nameZ	ncontrolsZsymbolrh   ri   rN   r   r   r   r9      s    z	Qasm.qdef)N)__name__
__module____qualname____doc__rF   rC   rP   rR   rU   rW   rI   r#   rX   rY   rZ   r[   r0   r(   r\   r_   r`   ra   rb   re   rf   rg   r9   r   r   r   r   r   w   s0   

N)ro   __all__Zsympy.physics.quantum.gater   r   r   r   r   r   r	   r
   r   r   rT   r   r   r   r   r   r!   r&   r*   r-   r5   r3   r?   objectr   r   r   r   r   <module>   s   0