o
    imA                     @   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IMPPUNCTTOKENS r   r   O/var/www/edux/Edux_v2/venv/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_precedence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   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)
has_priorityr   inRangetokenr   r   process_next_expressionassertNextTokenr   ApplicationExpression)r   
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'   r1   r6   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   otherother_indicesr   r   r   applytoQ   s   zExpression.applytoc                 C   s
   |  |S r   )r@   r   r>   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   r9   classmethodr=   r@   rB   rG   r   r   r   r   r8   J   s    

r8   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strr5   dependencies)r   r5   rM   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
        rM   r   index_counterglueFormulaFactoryr   r   r   compile_posu      zAtomicExpression.compile_posc                 C   rQ   rR   rS   rT   r   r   r   compile_neg   rX   zAtomicExpression.compile_negc                 C   s   | | j | _d S r   )initialize_labelr5   lowerr   fstructr   r   r   initialize_labels   rH   z"AtomicExpression.initialize_labelsc                 C   s   | j |j ko| j|jkS r   )rF   r5   rA   r   r   r   __eq__   s   zAtomicExpression.__eq__c                 C   
   | |k S r   r   rA   r   r   r   __ne__   r(   zAtomicExpression.__ne__c                 C   s   | j }| jr|d| j 7 }|S Nz%s)r5   rM   )r   accumr   r   r   __str__   s   zAtomicExpression.__str__c                 C   s
   t | jS r   )hashr5   r   r   r   r   __hash__   r(   zAtomicExpression.__hash__r   )r   r	   r
   r   rP   rW   rY   r^   r_   ra   rd   rf   r   r   r   r   rJ   [   s    

rJ   c                   @      e Zd Zdd ZdS )r4   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'
        )rK   r8   r3   BindingDictVariableBindingExceptionUnificationException)r   r>   rO   r   r   r   unify   s   

zConstantExpression.unifyNr   r	   r
   rk   r   r   r   r   r4          r4   c                   @   rg   )r3   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)rK   r8   rh   ri   rj   r   r>   rO   er   r   r   rk      s   	zVariableExpression.unifyNrl   r   r   r   r   r3      rm   r3   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)rK   r8   
antecedent
consequent)r   rp   rq   r   r   r   r      s   
zImpExpression.__init__Nc                 C   s   |  | j|| j|S r   )rF   rp   rP   rq   rN   r   r   r   rP      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)rK   r"   rp   rk   rq   ri   rj   rn   r   r   r   rk      s   	zImpExpression.unifyc                 C   s6   | j ||\}}| j||\}}t|||| fS rR   )rp   rY   rq   rW   r"   )r   rU   rV   aa_newcc_newr   r   r   rW      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)rp   rW   rq   rY   getrM   append)	r   rU   rV   rr   rs   rt   ru   fresh_indexnew_vr   r   r   rY      s   zImpExpression.compile_negc                 C   s   | j | | j| d S r   )rp   r^   rq   r\   r   r   r   r^     s   zImpExpression.initialize_labelsc                 C   $   | j |j ko| j|jko| j|jkS r   )rF   rp   rq   rA   r   r   r   r_   
  
   

zImpExpression.__eq__c                 C   r`   r   r   rA   r   r   r   ra     r(   zImpExpression.__ne__c                 C   s   d tj| jtj| jtjS )Nz{}{} {} {}{})formatr   r   rp   r   rq   r   r   r   r   r   rd     s   zImpExpression.__str__c                 C   "   t t | j tj t | j S r   )re   rp   r   r   rq   r   r   r   r   rf        "zImpExpression.__hash__r   )r   r	   r
   r   rP   rk   rW   rY   r^   r_   ra   rd   rf   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)rP   rK   r"   r8   rh   r.   rO   rp   rk   rj   LinearLogicApplicationExceptionsetrM   functionr0   )r   r   r0   argument_indicesfunction_simpargument_simprO   ro   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``
        )rO   r   rP   rq   rN   r   r   r   rP   N  s   	zApplicationExpression.simplifyc                 C   rz   r   )rF   r   r0   rA   r   r   r   r_   \  r{   zApplicationExpression.__eq__c                 C   r`   r   r   rA   r   r   r   ra   c  r(   zApplicationExpression.__ne__c                 C   s    d| j  tj d| j  tj S rb   )r   r   r   r0   r   r   r   r   r   rd   f  s    zApplicationExpression.__str__c                 C   r}   r   )re   rp   r   r   rq   r   r   r   r   rf   i  r~   zApplicationExpression.__hash__r   )	r   r	   r
   r   rP   r_   ra   rd   rf   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 )rh   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)drK   dictitems)r   rO   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)rK   r3   r8   r   rv   ri   )r   variable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)rK   r3   r   KeyError)r   r   intermediater   r   r   __getitem__  s   
zBindingDict.__getitem__c                 C   s
   || j v S r   r   )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)rh   r   ri   )r   r>   combinedr   ro   r   r   r   __add__  s"   

zBindingDict.__add__c                 C   r`   r   r   rA   r   r   r   ra     r(   zBindingDict.__ne__c                 C   s   t |tst| j|jkS r   )rK   rh   	TypeErrorr   rA   r   r   r   r_     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   ).0r   r   r   r   	<genexpr>  s   " z&BindingDict.__str__.<locals>.<genexpr>})joinsortedr   keysr   r   r   r   rd     s   *zBindingDict.__str__c                 C   s   d|  S )NzBindingDict: %sr   r   r   r   r   rG     s   zBindingDict.__repr__r   )r   r	   r
   r   r   r   r   r   ra   r_   rd   rG   r   r   r   r   rh   m  s    
rh   c                   @      e Zd ZdS )ri   Nr   r	   r
   r   r   r   r   ri         ri   c                   @   rg   )rj   c              	   C   s"   t | d| d| d|  d S )NzCannot unify z with z given )	Exceptionr   )r   rr   r   rO   r   r   r   r     r~   zUnificationException.__init__N)r   r	   r
   r   r   r   r   r   rj     rm   rj   c                   @   r   )r   Nr   r   r   r   r   r     r   r   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)))r8   r=   printrP   )lexprr   r   r   demo  s   r   __main__N)nltk.internalsr   nltk.sem.logicr   r   _counterr   r   r8   rJ   r4   r3   r"   r.   rh   r   ri   rj   r   r   r   r   r   r   r   <module>   s&   /CYLY
