o
    ifc                     @   sx  d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ G dd deZG dd	 d	eZd
d Zdd Zdd Zdd Z G dd de!Z"e#dZ$e#dZ%e#dej&Z'dd Z(d.ddZ)G dd de!Z*G dd dZ+dZ,d.d d!Z-d/d#d$Z.d.d%d&Z/d.d'd(Z0d0d)d*Z1e2d+kre1d,dd- dS dS )1zK
This module provides data structures for representing first-order
models.
    Npformat)	decorator)AbstractVariableExpressionAllExpressionAndExpressionApplicationExpressionEqualityExpressionExistsExpression
ExpressionIffExpressionImpExpressionIndividualVariableExpressionIotaExpressionLambdaExpressionNegatedExpressionOrExpressionVariable	is_indvarc                   @      e Zd ZdS )ErrorN__name__
__module____qualname__ r   r   L/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/nltk/sem/evaluate.pyr   ,       r   c                   @   r   )	UndefinedNr   r   r   r   r   r   0   r   r   c                 O   sV   t | }tt|d |}|dd r$t  | D ]}td|  q| |i |S )Nr   tracez%s => %s)inspectgetfullargspecdictzippopprintitems)fargskwargspecditemr   r   r   r   4   s   
r   c                 C   sJ   t | dkrdS tdd | D rt t| t t| krdS td|  )z
    Check whether a set represents a relation (of any arity).

    :param s: a set containing tuples of str elements
    :type s: set
    :rtype: bool
    r   Tc                 s   s    | ]}t |tV  qd S N)
isinstancetuple).0elr   r   r   	<genexpr>J   s    zis_rel.<locals>.<genexpr>z.Set %r contains sequences of different lengths)lenallmaxmin
ValueError)sr   r   r   is_rel>   s
   	*r9   c                 C   sP   t  }| D ] }t|tr||f qt|tr |t| q|| q|S )aR  
    Convert a set containing individuals (strings or numbers) into a set of
    unary tuples. Any tuples of strings already in the set are passed through
    unchanged.

    For example:
      - set(['a', 'b']) => set([('a',), ('b',)])
      - set([3, 27]) => set([('3',), ('27',)])

    :type s: set
    :rtype: set of tuple of str
    )setr.   straddint)r8   newelemr   r   r   set2relP   s   

r@   c                 C   s    t | dkrdS t t| d S )ze
    Check the arity of a relation.
    :type rel: set of tuples
    :rtype: int of tuple of str
    r   )r3   list)relr   r   r   arityh   s   rC   c                       sT   e Zd ZdZ fddZdd Zdd Zedd	 Zed
d Z	e
dd Z  ZS )	Valuationa  
    A dictionary which represents a model-theoretic Valuation of non-logical constants.
    Keys are strings representing the constants to be interpreted, and values correspond
    to individuals (represented as strings) and n-ary relations (represented as sets of tuples
    of strings).

    An instance of ``Valuation`` will raise a KeyError exception (i.e.,
    just behave like a standard  dictionary) if indexed with an expression that
    is not in its list of symbols.
    c                    sn   t    |D ]-\}}t|tst|tr|| |< qt|tr&t|| |< qtjd||f dd}t	|dS )z=
        :param xs: a list of (symbol, value) pairs.
        zGError in initializing Valuation. Unrecognized value for symbol '%s':
%sB   )widthN)
super__init__r.   r;   boolr:   r@   textwrapfillr7   )selfxssymvalmsg	__class__r   r   rH      s   


zValuation.__init__c                 C       || v r
t | |S td| )NzUnknown expression: '%s'r"   __getitem__r   rL   keyr   r   r   rU         zValuation.__getitem__c                 C   s   t | S r-   r   rL   r   r   r   __str__   s   zValuation.__str__c                 C   sN   g }|   D ]}t|tr|| qt|ts"|dd |D  qt|S )z7Set-theoretic domain of the value-space of a Valuation.c                 S   s"   g | ]}|D ]}|d ur|qqS r-   r   )r0   tuple_r?   r   r   r   
<listcomp>   s   " z$Valuation.domain.<locals>.<listcomp>)valuesr.   r;   appendrI   extendr:   )rL   domrO   r   r   r   domain   s   

zValuation.domainc                 C   s   t |  S )z9The non-logical constants which the Valuation recognizes.)sortedkeysrY   r   r   r   symbols   s   zValuation.symbolsc                 C   s   t |S r-   )read_valuation)clsr8   r   r   r   
fromstring   s   zValuation.fromstring)r   r   r   __doc__rH   rU   rZ   propertyra   rd   classmethodrg   __classcell__r   r   rQ   r   rD   s   s    

rD   z	\s*=+>\s*z\s*,\s*zg\s*
                                (\([^)]+\))  # tuple-expression
                                \s*c                 C   s   t | }|d }|d }|drB|dd }t|}|r9g }|D ]}|dd }tt|}|| q#nt|}t|}||fS )a  
    Read a line in a valuation file.

    Lines are expected to be of the form::

      noosa => n
      girl => {g1, g2}
      chase => {(b1, g1), (b2, g1), (g1, d1), (g2, d2)}

    :param s: input line
    :type s: str
    :return: a pair (symbol, value)
    :rtype: tuple
    r      {)	_VAL_SPLIT_REsplit
startswith
_TUPLES_REfindallr/   _ELEMENT_SPLIT_REr^   r:   )r8   piecessymbolvaluetuple_stringsset_elementstselementr   r   r   _read_valuation_line   s    



r|   c                 C   s   |dur	|  |} g }t|  D ]2\}}| }|ds"|dkr#qz	|t| W q tyC } ztd| d| |d}~ww t|S )a  
    Convert a valuation string into a valuation.

    :param s: a valuation string
    :type s: str
    :param encoding: the encoding of the input string, if it is binary
    :type encoding: str
    :return: a ``nltk.sem`` valuation
    :rtype: Valuation
    N# zUnable to parse line z: )	decode	enumerate
splitlinesstriprq   r^   r|   r7   rD   )r8   encoding
statementslinenumlineer   r   r   re      s   
re   c                       sT   e Zd ZdZd fdd	Zdd Zdd Zdd	d
Zdd Zdd Z	dd Z
  ZS )
Assignmentae  
    A dictionary which represents an assignment of values to variables.

    An assignment can only assign values from its domain.

    If an unknown expression *a* is passed to a model *M*\ 's
    interpretation function *i*, *i* will first check whether *M*\ 's
    valuation assigns an interpretation to *a* as a constant, and if
    this fails, *i* will delegate the interpretation of *a* to
    *g*. *g* only assigns values to individual variables (i.e.,
    members of the class ``IndividualVariableExpression`` in the ``logic``
    module. If a variable is not assigned a value by *g*, it will raise
    an ``Undefined`` exception.

    A variable *Assignment* is a mapping from individual variables to
    entities in the domain. Individual variables are usually indicated
    with the letters ``'x'``, ``'y'``, ``'w'`` and ``'z'``, optionally
    followed by an integer (e.g., ``'x0'``, ``'y332'``).  Assignments are
    created using the ``Assignment`` constructor, which also takes the
    domain as a parameter.

        >>> from nltk.sem.evaluate import Assignment
        >>> dom = set(['u1', 'u2', 'u3', 'u4'])
        >>> g3 = Assignment(dom, [('x', 'u1'), ('y', 'u2')])
        >>> g3 == {'x': 'u1', 'y': 'u2'}
        True

    There is also a ``print`` format for assignments which uses a notation
    closer to that in logic textbooks:

        >>> print(g3)
        g[u1/x][u2/y]

    It is also possible to update an assignment using the ``add`` method:

        >>> dom = set(['u1', 'u2', 'u3', 'u4'])
        >>> g4 = Assignment(dom)
        >>> g4.add('x', 'u1')
        {'x': 'u1'}

    With no arguments, ``purge()`` is equivalent to ``clear()`` on a dictionary:

        >>> g4.purge()
        >>> g4
        {}

    :param domain: the domain of discourse
    :type domain: set
    :param assign: a list of (varname, value) associations
    :type assign: list
    Nc                    sl   t    || _|r-|D ] \}}|| jv sJ d|| jt|s(J d| || |< qd | _|   d S )Nz'{}' is not in the domain: {}-Wrong format for an Individual Variable: '%s')rG   rH   ra   formatr   variant_addvariant)rL   ra   assignvarrO   rQ   r   r   rH   0  s   


zAssignment.__init__c                 C   rS   )Nz"Not recognized as a variable: '%s'rT   rV   r   r   r   rU   @  rX   zAssignment.__getitem__c                 C   s   t | j}||  |S r-   )r   ra   update)rL   r>   r   r   r   copyF  s   

zAssignment.copyc                 C   s    |r| |= n|    |   dS )z
        Remove one or all keys (i.e. logic variables) from an
        assignment, and update ``self.variant``.

        :param var: a Variable acting as a key for the assignment.
        N)clearr   )rL   r   r   r   r   purgeK  s
   zAssignment.purgec                 C   s6   d}t | j}|D ]\}}|d| d| d7 }q	|S )zQ
        Pretty printing for assignments. {'x', 'u'} appears as 'g[u/x]'
        g[/])rb   r   )rL   gstringr   rO   r   r   r   r   rZ   Y  s
   
zAssignment.__str__c                 C   s6   g }|   D ]}|d |d f}|| q|| _dS )zK
        Create a more pretty-printable version of the assignment.
        rl   r   N)r&   r^   r   )rL   list_r,   pairr   r   r   r   d  s   zAssignment._addvariantc                 C   sF   || j v sJ | d| j  t|sJ d| || |< |   | S )zh
        Add a new variable-value pair to the assignment, and update
        ``self.variant``.

        z is not in the domain r   )ra   r   r   )rL   r   rO   r   r   r   r<   o  s
   zAssignment.addr-   )r   r   r   rh   rH   rU   r   r   rZ   r   r<   rk   r   r   rQ   r   r      s    4
r   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	d
ZdddZdddZ	dddZ
dS )Modela[  
    A first order model is a domain *D* of discourse and a valuation *V*.

    A domain *D* is a set, and a valuation *V* is a map that associates
    expressions with values in the model.
    The domain of *V* should be a subset of *D*.

    Construct a new ``Model``.

    :type domain: set
    :param domain: A set of entities representing the domain of discourse of the model.
    :type valuation: Valuation
    :param valuation: the valuation of the model.
    :param prop: If this is set, then we are building a propositional    model and don't require the domain of *V* to be subset of *D*.
    c                 C   s<   t |tsJ || _|| _||jstd|j|f d S )NzDThe valuation domain, %s, must be a subset of the model's domain, %s)r.   r:   ra   	valuation
issupersetr   )rL   ra   r   r   r   r   rH     s   zModel.__init__c                 C   s   d| j d| jdS )N(z, )ra   r   rY   r   r   r   __repr__  s   zModel.__repr__c                 C   s   d| j  d| j S )Nz	Domain = z,
Valuation = 
r   rY   r   r   r   rZ     s   zModel.__str__Nc                 C   sx   z"t |}| j|||d}|r t  td| d| d|  |W S  ty;   |r8t  td| d|  Y dS w )aA  
        Read input expressions, and provide a handler for ``satisfy``
        that blocks further propagation of the ``Undefined`` error.
        :param expr: An ``Expression`` of ``logic``.
        :type g: Assignment
        :param g: an assignment to individual variables.
        :rtype: bool or 'Undefined'
        r   'z' evaluates to z
 under M, z' is undefined under M, r   )r   rg   satisfyr%   r   )rL   exprr   r   parsedrw   r   r   r   evaluate  s   	
zModel.evaluatec                    sv  t |tr8| \}}t |tr&| }t fdd|D }||v S |j }|j }|| S t |trE|j	  S t |t
rX|j oW|j S t |trk|j pj|j S t |tr|j  p~|j S t |tr|j |j kS t |tr|j |j kS t |trȈ  }	jD ]}
|	|jj|
 |j	|	s dS qdS t |tr  }	jD ]}
|	|jj|
 |j	|	r dS qdS t |tr  }	jD ]}
|	|jj|
 |j	|	r dS qdS t |tr4i }|jj}jD ]}
|j	 ||
}|||
< q|S | |S )a  
        Recursive interpretation function for a formula of first-order logic.

        Raises an ``Undefined`` error when ``parsed`` is an atomic string
        but is not a symbol or an individual variable.

        :return: Returns a truth value or ``Undefined`` if ``parsed`` is        complex, and calls the interpretation function ``i`` if ``parsed``        is atomic.

        :param parsed: An expression of ``logic``.
        :type g: Assignment
        :param g: an assignment to individual variables.
        c                 3   s    | ]	} | V  qd S r-   )r   r0   argr   rL   r   r   r2     s    z Model.satisfy.<locals>.<genexpr>FT)r.   r   uncurryr   r   r/   functionargumentr   termr   firstsecondr   r   r   r	   r   r   ra   r<   variablenamer
   r   r   i)rL   r   r   r   r   	argumentsfunvalargvalsargvalnew_gucfr   rO   r   r   r   r     sj   













zModel.satisfyFc                 C   s@   |j j| jjv r| j|j j S t|tr||j j S td| )a  
        An interpretation function.

        Assuming that ``parsed`` is atomic:

        - if ``parsed`` is a non-logical constant, calls the valuation *V*
        - else if ``parsed`` is an individual variable, calls assignment *g*
        - else returns ``Undefined``.

        :param parsed: an ``Expression`` of ``logic``.
        :type g: Assignment
        :param g: an assignment to individual variables.
        :return: a semantic value
        zCan't find a value for %s)r   r   r   rd   r.   r   r   )rL   r   r   r   r   r   r   r      s
   
zModel.ir   c              	   C   s6  d}|||  }g }t |trt|}	n|}	|	| v r|r/t  t|| d| d|   | jD ]U}
| }||	j|
 |rJ|dkrJ|d }nd}| 	|||}|r]t|d|   |dkrq|rpt|d| d	| d
  q2|
|
 |rt|d| d	| d|   q2dd |D }|S t|	j d| )a  
        Generate the entities from the model's domain that satisfy an open formula.

        :param parsed: an open formula
        :type parsed: Expression
        :param varex: the relevant free individual variable in ``parsed``.
        :type varex: VariableExpression or str
        :param g: a variable assignment
        :type g:  Assignment
        :return: a set of the entities that satisfy ``parsed``.
        z   zOpen formula is 'z' with assignment rl   r   z(trying assignment %s)Fz
value of 'z' under z	 is Falsez is c                 S   s   h | ]}|qS r   r   )r0   cr   r   r   	<setcomp>N  s    z#Model.satisfiers.<locals>.<setcomp>z is not free in )r.   r;   r   freer%   ra   r   r<   r   r   r^   r   )rL   r   varexr   r   nestingspacerindent
candidatesr   r   r   lowtracerw   resultr   r   r   
satisfiers  sD   




zModel.satisfiersr-   )F)Nr   )r   r   r   rh   rH   r   rZ   r   r   r   r   r   r   r   r   r   |  s    



Lr      c              	   C   s   t g dat atttattat  tdt	  td tdt	  td t  tdt tdt	  g d}|D ]}| rLt  t
|t|  q=td| dt
|t  q=d	S )
z!Example of a propositional model.))PT)QT)RF*zPropositional Formulas Demoz7(Propositional constants treated as nullary predicates)z
Model m1:
)z(P & Q)z(P & R)z- Pz- Rz- - Pz	- (P & R)z(P | R)z(R | P)z(R | R)z	(- P | R)z	(P | - P)z(P -> Q)z(P -> R)z(R -> P)z	(P <-> P)z	(R <-> R)z	(P <-> R)The value of '' is: N)rD   val1r:   dom1r   m1r   g1r%   multr   )r   	sentencessentr   r   r   propdemo_  s&   

r   Fc           
   	   C   s  ddddddhfddd	hfd
dhfdh dfga tt atjatttattddga| st	  t	dt
  t	d t	dt
  t	dddt t	dt g d}dd |D }t	  |D ]}zt	d|t|tf  W q\ ty{   t	d|  Y q\w g d}|D ];\}}z"tt|t}tdd |D }	t	| d| d|	|v   W q ty   t	| d| d  Y qw d!S d!S )"zExample of a first-order model.)adamb1)bettyr   )fidod1girlr   g2boyr   b2dogr   love>   r   r   r   r   r   r   r   r   )xr   )yr   r   zModels Demoz
Model m2:
z--------------
zVariable assignment = )r   r   r   walksr   r   zc                 S      g | ]}t |qS r   r   rg   )r0   r   r   r   r   r\         zfolmodel.<locals>.<listcomp>z&The interpretation of '%s' in m2 is %sz-The interpretation of '%s' in m2 is Undefined))r   r   )r   )r   )r   )r   r   )r   )r   r   c                 s   s"    | ]}t t|tV  qd S r-   )m2r   r   rg   r   r   r   r   r   r2     s     zfolmodel.<locals>.<genexpr>r   z) evaluates to z) evaluates to UndefinedN)v2rD   val2ra   dom2r   r   r   r   r%   r   r   r   r   rg   r/   )
quietr   exprsparsed_exprsr   applicationsfunr(   r   argsvalr   r   r   folmodel  sV   


	

 r   c              	   C   s~   t dd t  tdt  td tdt  g d}|D ]}t  | r.t|t|  qtd| dt|t  qdS )	zF
    Interpretation of closed expressions in a first-order model.
    Tr   r   zFOL Formulas Demo)zlove (adam, betty)z(adam = mia)z\x. (boy(x) | girl(x))z\x. boy(x)(adam)z\x y. love(x, y)z\x y. love(x, y)(adam)(betty)z\x y. love(x, y)(adam, betty)z\x y. (boy(x) & love(x, y))z#\x. exists y. (boy(x) & love(x, y))zexists z1. boy(z1)z!exists x. (boy(x) &  -(x = adam))z&exists x. (boy(x) & all y. love(y, x))zall x. (boy(x) | girl(x))z1all x. (girl(x) -> exists y. boy(y) & love(x, y))z3exists x. (boy(x) & all y. (girl(y) -> love(y, x)))z3exists x. (boy(x) & all y. (girl(y) -> love(x, y)))zall x. (dog(x) -> - girl(x))z-exists x. exists y. (love(x, y) & love(x, y))r   r   N)r   r%   r   r   r   r   r   )r   formulasfmlar   r   r   foldemo  s   
r   c                 C   s   t   t dt  t d t dt  tdd g d}| r"t t |D ]}t | t| q$dd |D }|D ]}t  t d|t	|d	t|  q9d
S )z5Satisfiers of an open formula in a first order model.r   zSatisfiers DemoTr   )zboy(x)z(x = x)z(boy(x) | girl(x))z(boy(x) & girl(x))zlove(adam, x)zlove(x, adam)z-(x = adam)zexists z22. love(x, z22)exists y. love(y, x)zall y. (girl(y) -> love(x, y))zall y. (girl(y) -> love(y, x))z)all y. (girl(y) -> (boy(x) & love(y, x)))z)(boy(x) & all y. (girl(y) -> love(x, y)))z)(boy(x) & all y. (girl(y) -> love(y, x)))z+(boy(x) & exists y. (girl(y) & love(y, x)))z(girl(x) -> dog(x))zall y. (dog(y) -> (x = y))r   z&exists y. (love(adam, y) & love(y, x))c                 S   r   r   r   )r0   r   r   r   r   r\     r   zsatdemo.<locals>.<listcomp>zThe satisfiers of '{}' are: {}r   N)
r%   r   r   r   r   rg   r   r   r   r   )r   r   r   r   pr   r   r   satdemo  s$   
r   c                 C   sP   t tttd}z
||  |d W dS  ty'   |D ]	} ||  |d qY dS w )aO  
    Run exists demos.

     - num = 1: propositional logic demo
     - num = 2: first order model demo (only if trace is set)
     - num = 3: first order sentences demo
     - num = 4: satisfaction of open formulas demo
     - any other value: run all the demos

    :param trace: trace = 1, or trace = 2 for more verbose tracing
    )rl            r   N)r   r   r   r   KeyError)numr   demosr   r   r   demo(  s   r  __main__r   r   r-   )FN)r   N)3rh   r    resysrJ   pprintr   nltk.decoratorsr   nltk.sem.logicr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   	Exceptionr   r   r   r9   r@   rC   r"   rD   compilero   rt   VERBOSErr   r|   re   r   r   r   r   r   r   r   r  r   r   r   r   r   <module>   sH   H

B

#  _

1
<
,
0