U
    eRC                     @   s   d dl mZ d dlmZmZ e ZG dd dZG dd deZG dd dZG d	d
 d
eZ	G dd de	Z
G dd de	ZG dd deZG dd deZG dd dZG dd deZG dd deZG dd deZdd Zedkre  dS )    )Counter)APPLogicParserc                   @   s*   e Zd ZdZdZdZeegZeeg ZdS )Tokens()z-oN)__name__
__module____qualname__OPENCLOSEIMPZPUNCTTOKENS r   r   U/var/www/html/assets/scripts/venv/lib/python3.8/site-packages/nltk/sem/linearlogic.pyr      s
   r   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )LinearLogicParserz!A linear logic expression parser.c                 C   s4   t |  tdtjdd di| _|  jtjg7  _d S )N         )r   __init__r   r   r   Zoperator_precedenceZright_associated_operationsselfr   r   r   r      s    
zLinearLogicParser.__init__c                 C   s   t jS N)r   r   r   r   r   r   get_all_symbols$   s    z!LinearLogicParser.get_all_symbolsc                 C   s0   |t jkr| ||S |t jkr,| ||S d S r   )r   r   Zhandle_variabler   handle_open)r   tokcontextr   r   r   handle'   s    

zLinearLogicParser.handlec                 C   s   |t jkrtS d S d S r   )r   r   ImpExpression)r   r   r   r   r   get_BooleanExpression_factory-   s    
z/LinearLogicParser.get_BooleanExpression_factoryc                 C   s
   |||S r   r   )r   factoryfirstsecondr   r   r   make_BooleanExpression3   s    z(LinearLogicParser.make_BooleanExpressionc                 C   sT   |  t|rP| drP| dtjkrP|   | t}| tj t	||d}|S )zAttempt to make an application expression.  If the next tokens
        are an argument in parens, then the argument expression is a
        function being applied to the arguments.  Otherwise, return the
        argument expression.r   N)
Zhas_priorityr   ZinRangetokenr   r   Zprocess_next_expressionZassertNextTokenr   ApplicationExpression)r   Z
expressionr   argumentr   r   r   attempt_ApplicationExpression6   s    
z/LinearLogicParser.attempt_ApplicationExpressionc                 C   s    |d   rt|S t|S d S )Nr   )isupperVariableExpressionConstantExpression)r   namer   r   r   make_VariableExpressionC   s    z)LinearLogicParser.make_VariableExpressionN)r   r	   r
   __doc__r   r   r   r   r#   r'   r,   r   r   r   r   r      s   r   c                   @   s8   e Zd Ze Zedd Zd
ddZdd Zdd	 Z	dS )
Expressionc                 C   s   | j |S r   )_linear_logic_parserparse)clssr   r   r   
fromstringN   s    zExpression.fromstringNc                 C   s   t | ||S r   )r%   )r   otherZother_indicesr   r   r   applytoR   s    zExpression.applytoc                 C   s
   |  |S r   )r5   r   r4   r   r   r   __call__U   s    zExpression.__call__c                 C   s   d| j j d|  dS )N< >)	__class__r   r   r   r   r   __repr__X   s    zExpression.__repr__)N)
r   r	   r
   r   r/   classmethodr3   r5   r7   r<   r   r   r   r   r.   J   s   

r.   c                   @   sX   e Zd ZdddZd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S )AtomicExpressionNc                 C   s&   t |tst|| _|sg }|| _dS )z
        :param name: str for the constant name
        :param dependencies: list of int for the indices on which this atom is dependent
        N)
isinstancestrAssertionErrorr+   dependencies)r   r+   rB   r   r   r   r   ]   s
    zAtomicExpression.__init__c                 C   s   |r| |kr||  S | S dS )z
        If 'self' is bound by 'bindings', return the atomic to which it is bound.
        Otherwise, return self.

        :param bindings: ``BindingDict`` A dictionary of bindings used to simplify
        :return: ``AtomicExpression``
        Nr   r   bindingsr   r   r   simplifyi   s    zAtomicExpression.simplifyc                 C   s   g | _ | g fS a3  
        From Iddo Lev's PhD Dissertation p108-109

        :param index_counter: ``Counter`` for unique indices
        :param glueFormulaFactory: ``GlueFormula`` for creating new glue formulas
        :return: (``Expression``,set) for the compiled linear logic and any newly created glue formulas
        rB   r   index_counterglueFormulaFactoryr   r   r   compile_posv   s    zAtomicExpression.compile_posc                 C   s   g | _ | g fS rF   rG   rH   r   r   r   compile_neg   s    zAtomicExpression.compile_negc                 C   s   | | j | _d S r   )Zinitialize_labelr+   lowerr   Zfstructr   r   r   initialize_labels   s    z"AtomicExpression.initialize_labelsc                 C   s   | j |j ko| j|jkS r   )r;   r+   r6   r   r   r   __eq__   s    zAtomicExpression.__eq__c                 C   s
   | |k S r   r   r6   r   r   r   __ne__   s    zAtomicExpression.__ne__c                 C   s   | j }| jr|d| j 7 }|S Nz%s)r+   rB   )r   accumr   r   r   __str__   s    zAtomicExpression.__str__c                 C   s
   t | jS r   )hashr+   r   r   r   r   __hash__   s    zAtomicExpression.__hash__)N)N)r   r	   r
   r   rE   rK   rL   rO   rP   rQ   rT   rV   r   r   r   r   r>   \   s   

r>   c                   @   s   e Zd Zdd ZdS )r*   c                 C   s`   t |tstt |trDz|t|| fg W S  tk
r@   Y qPX n| |krP|S t| ||dS )a  
        If 'other' is a constant, then it must be equal to 'self'.  If 'other' is a variable,
        then it must not be bound to anything other than 'self'.

        :param other: ``Expression``
        :param bindings: ``BindingDict`` A dictionary of all current bindings
        :return: ``BindingDict`` A new combined dictionary of of 'bindings' and any new binding
        :raise UnificationException: If 'self' and 'other' cannot be unified in the context of 'bindings'
        N)r?   r.   rA   r)   BindingDictVariableBindingExceptionUnificationException)r   r4   rD   r   r   r   unify   s    

zConstantExpression.unifyNr   r	   r
   rZ   r   r   r   r   r*      s   r*   c                   @   s   e Zd Zdd ZdS )r)   c              
   C   sj   t |tstz&| |kr|W S |t| |fg W S W n0 tk
rd } zt| |||W 5 d}~X Y nX dS )a  
        'self' must not be bound to anything other than 'other'.

        :param other: ``Expression``
        :param bindings: ``BindingDict`` A dictionary of all current bindings
        :return: ``BindingDict`` A new combined dictionary of of 'bindings' and the new binding
        :raise UnificationException: If 'self' and 'other' cannot be unified in the context of 'bindings'
        N)r?   r.   rA   rW   rX   rY   r   r4   rD   er   r   r   rZ      s    	zVariableExpression.unifyNr[   r   r   r   r   r)      s   r)   c                   @   s^   e Zd Zdd Zd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S )r   c                 C   s,   t |tstt |tst|| _|| _dS )z
        :param antecedent: ``Expression`` for the antecedent
        :param consequent: ``Expression`` for the consequent
        N)r?   r.   rA   
antecedent
consequent)r   r^   r_   r   r   r   r      s    zImpExpression.__init__Nc                 C   s   |  | j|| j|S r   )r;   r^   rE   r_   rC   r   r   r   rE      s    
 
zImpExpression.simplifyc              
   C   sj   t |tstz&|| j|j| | j|j| W S  tk
rd } zt| |||W 5 d}~X Y nX dS )a  
        Both the antecedent and consequent of 'self' and 'other' must unify.

        :param other: ``ImpExpression``
        :param bindings: ``BindingDict`` A dictionary of all current bindings
        :return: ``BindingDict`` A new combined dictionary of of 'bindings' and any new bindings
        :raise UnificationException: If 'self' and 'other' cannot be unified in the context of 'bindings'
        N)r?   r   rA   r^   rZ   r_   rX   rY   r\   r   r   r   rZ      s    	zImpExpression.unifyc                 C   s6   | j ||\}}| j||\}}t|||| fS rF   )r^   rL   r_   rK   r   )r   rI   rJ   aa_newcc_newr   r   r   rK      s    zImpExpression.compile_posc           	      C   s\   | j ||\}}| j||\}}| }|j| |d| ||h}||| |g fS )aG  
        From Iddo Lev's PhD Dissertation p108-109

        :param index_counter: ``Counter`` for unique indices
        :param glueFormulaFactory: ``GlueFormula`` for creating new glue formulas
        :return: (``Expression``,list of ``GlueFormula``) for the compiled linear logic and any newly created glue formulas
        zv%s)r^   rK   r_   rL   getrB   append)	r   rI   rJ   r`   ra   rb   rc   Zfresh_indexnew_vr   r   r   rL      s    zImpExpression.compile_negc                 C   s   | j | | j| d S r   )r^   rO   r_   rN   r   r   r   rO     s    zImpExpression.initialize_labelsc                 C   s$   | j |j ko"| j|jko"| j|jkS r   )r;   r^   r_   r6   r   r   r   rP     s
    

zImpExpression.__eq__c                 C   s
   | |k S r   r   r6   r   r   r   rQ     s    zImpExpression.__ne__c                 C   s   d tj| jtj| jtjS )Nz{}{} {} {}{})formatr   r   r^   r   r_   r   r   r   r   r   rT     s    zImpExpression.__str__c                 C   s"   t t | j tj t | j S r   )rU   r^   r   r   r_   r   r   r   r   rV     s    zImpExpression.__hash__)N)r   r	   r
   r   rE   rZ   rK   rL   rO   rP   rQ   rT   rV   r   r   r   r   r      s   

	r   c                   @   s@   e Zd ZdddZdddZdd Zdd	 Zd
d Zdd ZdS )r%   Nc              
   C   s
  |  }|  }t|tstt|ts,tt }z>t|trH||j7 }t|tr\||j7 }||j	||7 }W n> t
k
r } z td| d| d| |W 5 d}~X Y nX |rt|jj|k std||f t|jj|krtd||f || _|| _|| _dS )aY  
        :param function: ``Expression`` for the function
        :param argument: ``Expression`` for the argument
        :param argument_indices: set for the indices of the glue formula from which the argument came
        :raise LinearLogicApplicationException: If 'function' cannot be applied to 'argument' given 'argument_indices'.
        zCannot apply z to z. NzODependencies unfulfilled when attempting to apply Linear Logic formula %s to %szbDependencies not a proper subset of indices when attempting to apply Linear Logic formula %s to %s)rE   r?   r   rA   r.   rW   r%   rD   r^   rZ   rY   LinearLogicApplicationExceptionsetrB   functionr&   )r   rj   r&   Zargument_indicesZfunction_simpZargument_simprD   r]   r   r   r   r   #  sB    



zApplicationExpression.__init__c                 C   s   |s
| j }| j|jS )a=  
        Since function is an implication, return its consequent.  There should be
        no need to check that the application is valid since the checking is done
        by the constructor.

        :param bindings: ``BindingDict`` A dictionary of bindings used to simplify
        :return: ``Expression``
        )rD   rj   rE   r_   rC   r   r   r   rE   O  s    	zApplicationExpression.simplifyc                 C   s$   | j |j ko"| j|jko"| j|jkS r   )r;   rj   r&   r6   r   r   r   rP   ]  s
    

zApplicationExpression.__eq__c                 C   s
   | |k S r   r   r6   r   r   r   rQ   d  s    zApplicationExpression.__ne__c                 C   s    d| j  tj d| j  tj S rR   )rj   r   r   r&   r   r   r   r   r   rT   g  s    zApplicationExpression.__str__c                 C   s"   t t | j tj t | j S r   )rU   r^   r   r   r_   r   r   r   r   rV   j  s    zApplicationExpression.__hash__)N)N)	r   r	   r
   r   rE   rP   rQ   rT   rV   r   r   r   r   r%   "  s   
,
r%   c                   @   sV   e Zd Zd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S )rW   Nc                 C   s6   i | _ t|tr| }|r2|D ]\}}|| |< q dS )z
        :param bindings:
            list [(``VariableExpression``, ``AtomicExpression``)] to initialize the dictionary
            dict {``VariableExpression``: ``AtomicExpression``} to initialize the dictionary
        N)dr?   dictitems)r   rD   vbr   r   r   r   o  s    
zBindingDict.__init__c                 C   s^   t |tstt |tst||ks(t| j|d}|rB||krN|| j|< ntd| dS )a  
        A binding is consistent with the dict if its variable is not already bound, OR if its
        variable is already bound to its argument.

        :param variable: ``VariableExpression`` The variable bind
        :param binding: ``Expression`` The expression to which 'variable' should be bound
        :raise VariableBindingException: If the variable cannot be bound in this dictionary
        Nz*Variable %s already bound to another value)r?   r)   rA   r.   rk   rd   rX   )r   variableZbindingexistingr   r   r   __setitem__~  s    	zBindingDict.__setitem__c                 C   sJ   t |tst| j| }|rFz| j| }W q tk
rB   | Y S X qdS )zD
        Return the expression to which 'variable' is bound
        N)r?   r)   rA   rk   KeyError)r   rp   Zintermediater   r   r   __getitem__  s    
zBindingDict.__getitem__c                 C   s
   || j kS r   rk   )r   itemr   r   r   __contains__  s    zBindingDict.__contains__c              
   C   sz   z@t  }| jD ]}| j| ||< q|jD ]}|j| ||< q(|W S  tk
rt } ztd| |f |W 5 d}~X Y nX dS )a  
        :param other: ``BindingDict`` The dict with which to combine self
        :return: ``BindingDict`` A new dict containing all the elements of both parameters
        :raise VariableBindingException: If the parameter dictionaries are not consistent with each other
        zAAttempting to add two contradicting VariableBindingsLists: %s, %sN)rW   rk   rX   )r   r4   combinedrn   r]   r   r   r   __add__  s    

zBindingDict.__add__c                 C   s
   | |k S r   r   r6   r   r   r   rQ     s    zBindingDict.__ne__c                 C   s   t |tst| j|jkS r   )r?   rW   	TypeErrorrk   r6   r   r   r   rP     s    
zBindingDict.__eq__c                    s*   dd  fddt j D  d S )N{z, c                 3   s"   | ]}| d  j |  V  qdS )z: Nru   ).0rn   r   r   r   	<genexpr>  s     z&BindingDict.__str__.<locals>.<genexpr>})joinsortedrk   keysr   r   r   r   rT     s    zBindingDict.__str__c                 C   s   d|  S )NzBindingDict: %sr   r   r   r   r   r<     s    zBindingDict.__repr__)N)r   r	   r
   r   rr   rt   rw   ry   rQ   rP   rT   r<   r   r   r   r   rW   n  s   
rW   c                   @   s   e Zd ZdS )rX   Nr   r	   r
   r   r   r   r   rX     s   rX   c                   @   s   e Zd Zdd ZdS )rY   c              	   C   s"   t | d| d| d|  d S )NzCannot unify z with z given )	Exceptionr   )r   r`   ro   rD   r   r   r   r     s    zUnificationException.__init__N)r   r	   r
   r   r   r   r   r   rY     s   rY   c                   @   s   e Zd ZdS )rh   Nr   r   r   r   r   rh     s   rh   c                  C   sz   t j} t| d t| d t| d t| d t| d  t| d  t| d  t| d  d S )	Nfz(g -o f)z((g -o G) -o G)zg -o h -o fz(g -o f)(g)z(H -o f)(g)z((g -o G) -o G)((g -o f))z(H -o H)((g -o f)))r.   r3   printrE   )Zlexprr   r   r   demo  s    r   __main__N)Znltk.internalsr   Znltk.sem.logicr   r   _counterr   r   r.   r>   r*   r)   r   r%   rW   r   rX   rY   rh   r   r   r   r   r   r   <module>	   s"   /CYLY