o
    rZhmA                     @   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r{e  dS 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   C/var/www/auris/lib/python3.10/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   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v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 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      
z(LinearLogicParser.make_BooleanExpressionc                 C   sT   |  t|r(| dr(| dtjkr(|   | 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 )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   
fromstringM   s   zExpression.fromstringNc                 C   s   t | ||S r   )r'   )r   otherZother_indicesr   r   r   applytoQ   s   zExpression.applytoc                 C   s
   |  |S r   )r7   r   r6   r   r   r   __call__T   r%   zExpression.__call__c                 C   s   d| j j d|  dS )N< >)	__class__r   r   r   r   r   __repr__W      zExpression.__repr__r   )
r   r	   r
   r   r1   classmethodr5   r7   r9   r>   r   r   r   r   r0   J   s    

r0   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J || _|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strr-   dependencies)r   r-   rD   r   r   r   r   \   s
   
zAtomicExpression.__init__c                 C   s   |r
| |v r
||  S | 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``
        r   r   bindingsr   r   r   simplifyh   s   zAtomicExpression.simplifyc                 C      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
        rD   r   index_counterglueFormulaFactoryr   r   r   compile_posu      zAtomicExpression.compile_posc                 C   rH   rI   rJ   rK   r   r   r   compile_neg   rO   zAtomicExpression.compile_negc                 C   s   | | j | _d S r   )Zinitialize_labelr-   lowerr   Zfstructr   r   r   initialize_labels   r?   z"AtomicExpression.initialize_labelsc                 C   s   | j |j ko| j|jkS r   )r=   r-   r8   r   r   r   __eq__   s   zAtomicExpression.__eq__c                 C   
   | |k S r   r   r8   r   r   r   __ne__   r%   zAtomicExpression.__ne__c                 C   s   | j }| jr|d| j 7 }|S Nz%s)r-   rD   )r   accumr   r   r   __str__   s   zAtomicExpression.__str__c                 C   s
   t | jS r   )hashr-   r   r   r   r   __hash__   r%   zAtomicExpression.__hash__r   )r   r	   r
   r   rG   rN   rP   rS   rT   rV   rY   r[   r   r   r   r   rA   [   s    

rA   c                   @      e Zd Zdd ZdS )r,   c                 C   sX   t |tsJ t |tr z
|t|| fg W S  ty   Y nw | |kr&|S t| ||)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'
        )rB   r0   r+   BindingDictVariableBindingExceptionUnificationException)r   r6   rF   r   r   r   unify   s   

zConstantExpression.unifyNr   r	   r
   r`   r   r   r   r   r,          r,   c                   @   r\   )r+   c              
   C   sX   t |tsJ z| |kr|W S |t| |fg W S  ty+ } zt| |||d}~ww )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)rB   r0   r]   r^   r_   r   r6   rF   er   r   r   r`      s   	zVariableExpression.unifyNra   r   r   r   r   r+      rb   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J t |tsJ || _|| _dS )z
        :param antecedent: ``Expression`` for the antecedent
        :param consequent: ``Expression`` for the consequent
        N)rB   r0   
antecedent
consequent)r   re   rf   r   r   r   r      s   
zImpExpression.__init__Nc                 C   s   |  | j|| j|S r   )r=   re   rG   rf   rE   r   r   r   rG      s   zImpExpression.simplifyc              
   C   s\   t |tsJ z|| j|j| | j|j| W S  ty- } zt| |||d}~ww )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)rB   r   re   r`   rf   r^   r_   rc   r   r   r   r`      s   	zImpExpression.unifyc                 C   s6   | j ||\}}| j||\}}t|||| fS rI   )re   rP   rf   rN   r   )r   rL   rM   aa_newcc_newr   r   r   rN      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)re   rN   rf   rP   getrD   append)	r   rL   rM   rg   rh   ri   rj   Zfresh_indexnew_vr   r   r   rP      s   zImpExpression.compile_negc                 C   s   | j | | j| d S r   )re   rS   rf   rR   r   r   r   rS     s   zImpExpression.initialize_labelsc                 C   $   | j |j ko| j|jko| j|jkS r   )r=   re   rf   r8   r   r   r   rT   
  
   

zImpExpression.__eq__c                 C   rU   r   r   r8   r   r   r   rV     r%   zImpExpression.__ne__c                 C   s   d tj| jtj| jtjS )Nz{}{} {} {}{})formatr   r   re   r   rf   r   r   r   r   r   rY     s   zImpExpression.__str__c                 C   "   t t | j tj t | j S r   )rZ   re   r   r   rf   r   r   r   r   r[        "zImpExpression.__hash__r   )r   r	   r
   r   rG   r`   rN   rP   rS   rT   rV   rY   r[   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J t|tsJ t }zt|tr$||j7 }t|tr.||j7 }||j||7 }W n t	yR } zt
d| d| d| |d}~ww |rut|jj|k set
d||f t|jj|krut
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)rG   rB   r   r0   r]   r'   rF   re   r`   r_   LinearLogicApplicationExceptionsetrD   functionr(   )r   ru   r(   Zargument_indicesZfunction_simpZargument_simprF   rd   r   r   r   r   "  sF   




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``
        )rF   ru   rG   rf   rE   r   r   r   rG   N  s   	zApplicationExpression.simplifyc                 C   rn   r   )r=   ru   r(   r8   r   r   r   rT   \  ro   zApplicationExpression.__eq__c                 C   rU   r   r   r8   r   r   r   rV   c  r%   zApplicationExpression.__ne__c                 C   s    d| j  tj d| j  tj S rW   )ru   r   r   r(   r   r   r   r   r   rY   f  s    zApplicationExpression.__str__c                 C   rq   r   )rZ   re   r   r   rf   r   r   r   r   r[   i  rr   zApplicationExpression.__hash__r   )	r   r	   r
   r   rG   rT   rV   rY   r[   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 )r]   Nc                 C   s:   i | _ t|tr| }|r|D ]
\}}|| |< qdS dS )z
        :param bindings:
            list [(``VariableExpression``, ``AtomicExpression``)] to initialize the dictionary
            dict {``VariableExpression``: ``AtomicExpression``} to initialize the dictionary
        N)drB   dictitems)r   rF   vbr   r   r   r   n  s   

zBindingDict.__init__c                 C   s\   t |tsJ t |tsJ ||ksJ | j|d}|r!||kr(|| j|< dS td| )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)rB   r+   r0   rv   rk   r^   )r   variableZbindingexistingr   r   r   __setitem__}  s   	zBindingDict.__setitem__c                 C   sN   t |tsJ | j| }|r%z| j| }W n ty    | Y S w |sdS dS )zD
        Return the expression to which 'variable' is bound
        N)rB   r+   rv   KeyError)r   r{   Zintermediater   r   r   __getitem__  s   
zBindingDict.__getitem__c                 C   s
   || j v S r   rv   )r   itemr   r   r   __contains__  r%   zBindingDict.__contains__c              
   C   sl   z t  }| jD ]	}| j| ||< q|jD ]	}|j| ||< q|W S  ty5 } z	td| |f |d}~ww )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)r]   rv   r^   )r   r6   combinedry   rd   r   r   r   __add__  s"   

zBindingDict.__add__c                 C   rU   r   r   r8   r   r   r   rV     r%   zBindingDict.__ne__c                 C   s   t |tst| j|jkS r   )rB   r]   	TypeErrorrv   r8   r   r   r   rT     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: Nr   ).0ry   r   r   r   	<genexpr>  s   " z&BindingDict.__str__.<locals>.<genexpr>})joinsortedrv   keysr   r   r   r   rY     s   *zBindingDict.__str__c                 C   s   d|  S )NzBindingDict: %sr   r   r   r   r   r>     s   zBindingDict.__repr__r   )r   r	   r
   r   r}   r   r   r   rV   rT   rY   r>   r   r   r   r   r]   m  s    
r]   c                   @      e Zd ZdS )r^   Nr   r	   r
   r   r   r   r   r^         r^   c                   @   r\   )r_   c              	   C   s"   t | d| d| d|  d S )NzCannot unify z with z given )	Exceptionr   )r   rg   rz   rF   r   r   r   r     rr   zUnificationException.__init__N)r   r	   r
   r   r   r   r   r   r_     rb   r_   c                   @   r   )rs   Nr   r   r   r   r   rs     r   rs   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)))r0   r5   printrG   )Zlexprr   r   r   demo  s   r   __main__N)Znltk.internalsr   Znltk.sem.logicr   r   _counterr   r   r0   rA   r,   r+   r   r'   r]   r   r^   r_   rs   r   r   r   r   r   r   <module>   s&   /CYLY
