B
    `H                 @   s0  d Z ddlmZ ddlmZ ddlmZ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 ddlmZmZ G dd deZ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#dd Z$dd Z%dd Z&dd Z'dd Z(dd  Z)d!d" Z*e+d#kr,e*  d$S )%z
A module to perform nonmonotonic reasoning.  The ideas and demonstrations in
this module are based on "Logical Foundations of Artificial Intelligence" by
Michael R. Genesereth and Nils J. Nilsson.
    )defaultdict)reduce)Prover9Prover9Command)VariableExpressionEqualityExpressionApplicationExpression
ExpressionAbstractVariableExpressionAllExpressionBooleanExpressionNegatedExpressionExistsExpressionVariableImpExpressionAndExpressionunique_variableoperator)ProverProverCommandDecoratorc               @   s   e Zd ZdS )ProverParseErrorN)__name__
__module____qualname__ r   r   J/home/dcms/DCMS/lib/python3.7/site-packages/nltk/inference/nonmonotonic.pyr   '   s   r   c             C   s4   | d kr|}n||  g }t tjdd |D t S )Nc             s   s   | ]}|  V  qd S )N)	constants).0ar   r   r   	<genexpr>0   s    zget_domain.<locals>.<genexpr>)r   r   or_set)goalassumptionsZall_expressionsr   r   r   
get_domain+   s    r$   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ClosedDomainProverz]
    This is a prover decorator that adds domain closure assumptions before
    proving.
    c                s<   dd j  D }j  }t||  fdd|D S )Nc             S   s   g | ]}|qS r   r   )r   r   r   r   r   
<listcomp>:   s    z2ClosedDomainProver.assumptions.<locals>.<listcomp>c                s   g | ]} | qS r   )replace_quants)r   ex)domainselfr   r   r&   =   s    )_commandr#   r"   r$   )r*   r#   r"   r   )r)   r*   r   r#   9   s    

zClosedDomainProver.assumptionsc             C   s&   | j  }t|| j  }| ||S )N)r+   r"   r$   r#   r'   )r*   r"   r)   r   r   r   r"   ?   s    
zClosedDomainProver.goalc                s   t tr>fdd D } fdd|D }tdd |S t trhj j S t trj	  S t t
rfdd D } fdd|D }tdd |S S d	S )
a  
        Apply the closed domain assumption to the expression
         - Domain = union([e.free()|e.constants() for e in all_expressions])
         - translate "exists x.P" to "(z=d1 | z=d2 | ... ) & P.replace(x,z)" OR
                     "P.replace(x, d1) | P.replace(x, d2) | ..."
         - translate "all x.P" to "P.replace(x, d1) & P.replace(x, d2) & ..."
        :param ex: ``Expression``
        :param domain: set of {Variable}s
        :return: ``Expression``
        c                s    g | ]} j  jt|qS r   )termreplacevariabler   )r   d)r(   r   r   r&   Q   s    z5ClosedDomainProver.replace_quants.<locals>.<listcomp>c                s   g | ]} | qS r   )r'   )r   c)r)   r*   r   r   r&   S   s    c             S   s   | |@ S )Nr   )xyr   r   r   <lambda>T       z3ClosedDomainProver.replace_quants.<locals>.<lambda>c                s    g | ]} j  jt|qS r   )r,   r-   r.   r   )r   r/   )r(   r   r   r&   ^   s    c                s   g | ]} | qS r   )r'   )r   r/   )r)   r*   r   r   r&   `   s    c             S   s   | |B S )Nr   )r1   r2   r   r   r   r3   a   r4   N)
isinstancer   r   r   	__class__r'   firstsecondr   r,   r   )r*   r(   r)   Z	conjuncts	disjunctsr   )r)   r(   r*   r   r'   D   s    



z!ClosedDomainProver.replace_quantsN)r   r   r   __doc__r#   r"   r'   r   r   r   r   r%   3   s   r%   c               @   s   e Zd ZdZdd ZdS )UniqueNamesProverz[
    This is a prover decorator that adds unique names assumptions before
    proving.
    c             C   s   | j  }tt| j  |}t }x4|D ],}t|tr*|jj	}|j
j	}|| | q*W g }xvt|D ]j\}}x`||d d D ]L}	|	|| krtt|t|	}
t |
|r|| |	 q||
  qW qhW || S )z
         - Domain = union([e.free()|e.constants() for e in all_expressions])
         - if "d1 = d2" cannot be proven from the premises, then add "d1 != d2"
           N)r+   r#   listr$   r"   	SetHolderr5   r   r7   r.   r8   add	enumerater   r   proveappend)r*   r#   r)   Zeq_setsr   avZbvnew_assumptionsibZnewEqExr   r   r   r#   l   s$    


zUniqueNamesProver.assumptionsN)r   r   r   r:   r#   r   r   r   r   r;   f   s   r;   c               @   s   e Zd ZdZdd ZdS )r>   z&
    A list of sets of Variables.
    c             C   s@   t |tstx| D ]}||kr|S qW t|g}| | |S )zV
        :param item: ``Variable``
        :return: the set containing 'item'
        )r5   r   AssertionErrorr!   rB   )r*   itemsnewr   r   r   __getitem__   s    


zSetHolder.__getitem__N)r   r   r   r:   rK   r   r   r   r   r>      s   r>   c               @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )ClosedWorldProvera  
    This is a prover decorator that completes predicates before proving.

    If the assumptions contain "P(A)", then "all x.(P(x) -> (x=A))" is the completion of "P".
    If the assumptions contain "all x.(ostrich(x) -> bird(x))", then "all x.(bird(x) -> ostrich(x))" is the completion of "bird".
    If the assumptions don't contain anything that are "P", then "all x.-P(x)" is the completion of "P".

    walk(Socrates)
    Socrates != Bill
    + all x.(walk(x) -> (x=Socrates))
    ----------------
    -walk(Bill)

    see(Socrates, John)
    see(John, Mary)
    Socrates != John
    John != Mary
    + all x.all y.(see(x,y) -> ((x=Socrates & y=John) | (x=John & y=Mary)))
    ----------------
    -see(Socrates, Mary)

    all x.(ostrich(x) -> bird(x))
    bird(Tweety)
    -ostrich(Sam)
    Sam != Tweety
    + all x.(bird(x) -> (ostrich(x) | x=Tweety))
    + all x.-ostrich(x)
    -------------------
    -bird(Sam)
    c             C   s\  | j  }| |}g }x8|D ].}|| }| |}dd |D }g }xN|jD ]D}	g }
x&t||	D ]\}}|
t|| qfW |tdd |
 qRW xJ|j	D ]@}i }x"t||d D ]\}}|||< qW ||d 
| qW |r| ||}tdd |}t||}nt| ||}x"|d d d D ]}t||}q2W || q W || S )	Nc             S   s   g | ]}t |qS r   )r   )r   vr   r   r   r&      s    z1ClosedWorldProver.assumptions.<locals>.<listcomp>c             S   s   | |@ S )Nr   )r1   r2   r   r   r   r3      r4   z/ClosedWorldProver.assumptions.<locals>.<lambda>r   r<   c             S   s   | |B S )Nr   )r1   r2   r   r   r   r3      r4   )r+   r#   _make_predicate_dict_make_unique_signature
signaturesziprB   r   r   
propertiesZsubstitute_bindings_make_antecedentr   r   r   )r*   r#   
predicatesrD   p
predHoldernew_sigZnew_sig_exsr9   sigZequality_exsZv1Zv2propZbindings
antecedentZ
consequentaccumZnew_sig_varr   r   r   r#      s6    


zClosedWorldProver.assumptionsc             C   s   t dd t|jD S )z
        This method figures out how many arguments the predicate takes and
        returns a tuple containing that number of unique variables.
        c             s   s   | ]}t  V  qd S )N)r   )r   rE   r   r   r   r      s    z;ClosedWorldProver._make_unique_signature.<locals>.<genexpr>)tuplerangesignature_len)r*   rW   r   r   r   rP      s    z(ClosedWorldProver._make_unique_signaturec             C   s"   |}x|D ]}|t |}q
W |S )z
        Return an application expression with 'predicate' as the predicate
        and 'signature' as the list of arguments.
        )r   )r*   	predicate	signaturer[   rM   r   r   r   rT      s    
z"ClosedWorldProver._make_antecedentc             C   s&   t t}x|D ]}| || qW |S )z
        Create a dictionary of predicates from the assumptions.

        :param assumptions: a list of ``Expression``s
        :return: dict mapping ``AbstractVariableExpression`` to ``PredHolder``
        )r   
PredHolder_map_predicates)r*   r#   rU   r   r   r   r   rO     s    
z&ClosedWorldProver._make_predicate_dictc             C   sH  t |tr6| \}}t |tr2|| t| nt |tr^| |j| | |j	| nt |t
rD|jg}|j}x t |t
r||j |j}qzW t |trDt |jtrDt |j	trD|j \}}|j	 \}	}
t |trDt |	trD|dd |D krD|dd |
D krD||	 t||jf || | d S )Nc             S   s   g | ]
}|j qS r   )r.   )r   rM   r   r   r   r&   '  s    z5ClosedWorldProver._map_predicates.<locals>.<listcomp>c             S   s   g | ]
}|j qS r   )r.   )r   rM   r   r   r   r&   (  s    )r5   r   Zuncurryr
   
append_sigr]   r   rc   r7   r8   r   r.   r,   rB   r   append_propvalidate_sig_len)r*   Z
expressionZpredDictfuncargsrY   r,   Zfunc1Zargs1Zfunc2Zargs2r   r   r   rc     s0    



z!ClosedWorldProver._map_predicatesN)	r   r   r   r:   r#   rP   rT   rO   rc   r   r   r   r   rL      s   -
rL   c               @   s@   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S )rb   a  
    This class will be used by a dictionary that will store information
    about predicates to be used by the ``ClosedWorldProver``.

    The 'signatures' property is a list of tuples defining signatures for
    which the predicate is true.  For instance, 'see(john, mary)' would be
    result in the signature '(john,mary)' for 'see'.

    The second element of the pair is a list of pairs such that the first
    element of the pair is a tuple of variables and the second element is an
    expression of those variables that makes the predicate true.  For instance,
    'all x.all y.(see(x,y) -> know(x,y))' would result in "((x,y),('see(x,y)'))"
    for 'know'.
    c             C   s   g | _ g | _d | _d S )N)rQ   rS   r_   )r*   r   r   r   __init__>  s    zPredHolder.__init__c             C   s   |  | | j| d S )N)rf   rQ   rB   )r*   rX   r   r   r   rd   C  s    
zPredHolder.append_sigc             C   s   |  |d  | j| d S )Nr   )rf   rS   rB   )r*   Znew_propr   r   r   re   G  s    zPredHolder.append_propc             C   s0   | j d krt|| _ n| j t|kr,tdd S )NzSignature lengths do not match)r_   len	Exception)r*   rX   r   r   r   rf   K  s    
zPredHolder.validate_sig_lenc             C   s   d| j | j| jf S )Nz
(%s,%s,%s))rQ   rS   r_   )r*   r   r   r   __str__Q  s    zPredHolder.__str__c             C   s   d|  S )Nz%sr   )r*   r   r   r   __repr__T  s    zPredHolder.__repr__N)
r   r   r   r:   ri   rd   re   rf   rl   rm   r   r   r   r   rb   .  s   rb   c        
      C   s  t j} | d}| d}| d}t|||g}t|  t|}td x| D ]}td| qRW td|  t|  | d}| d}| d}| d}t||||g}t|  t|}td x| D ]}td| qW td|  t|  | d}| d}| d}| d}t||||g}t|  t|}td x| D ]}td| qVW td|  t|  | d}| d}| d	}t|||g}t|  t|}td x| D ]}td| qW td|  t|  | d
}| d}| d}| d}| d}	| d}t||||||	g}t|  t|}td x| D ]}td| qhW td|  t|  d S )Nzexists x.walk(x)zman(Socrates)zwalk(Socrates)zassumptions:z   zgoal:z-walk(Bill)z
walk(Bill)zall x.walk(x)z
girl(mary)z
dog(rover)zall x.(girl(x) -> -dog(x))zall x.(dog(x) -> -girl(x))zchase(mary, rover)z1exists y.(dog(y) & all x.(girl(x) -> chase(x,y))))r	   
fromstringr   printrA   r%   r#   r"   )
lexprp1p2r0   proverZcdpr   p3p4Zp5r   r   r   closed_domain_demoX  sz    rv   c              C   s  t j} | d}| d}| d}t|||g}t|  t|}td x| D ]}td| qRW td|  t|  | d}| d}| d	}| d
}t||||g}t|  t|}td x| D ]}td| qW td|  t|  d S )Nzman(Socrates)z	man(Bill)zexists x.exists y.(x != y)zassumptions:z   zgoal:z!all x.(walk(x) -> (x = Socrates))zBill = WilliamzBill = Billyz-walk(William))r	   rn   r   ro   rA   r;   r#   r"   )rp   rq   rr   r0   rs   Zunpr   rt   r   r   r   unique_names_demo  s0    rw   c        	      C   s  t j} | d}| d}| d}t|||g}t|  t|}td x| D ]}td| qRW td|  t|  | d}| d}| d	}| d
}| d}t|||||g}t|  t|}td x| D ]}td| qW td|  t|  | d}| d}| d}| d}| d}t|||||g}t|  t|}td x| D ]}td| qjW td|  t|  d S )Nzwalk(Socrates)z(Socrates != Bill)z-walk(Bill)zassumptions:z   zgoal:zsee(Socrates, John)zsee(John, Mary)z(Socrates != John)z(John != Mary)z-see(Socrates, Mary)zall x.(ostrich(x) -> bird(x))zbird(Tweety)z-ostrich(Sam)zSam != Tweetyz
-bird(Sam))r	   rn   r   ro   rA   rL   r#   r"   )	rp   rq   rr   r0   rs   Zcwpr   rt   ru   r   r   r   closed_world_demo  sL    rx   c              C   sr   t j} | d}| d}| d}t|||g}t|  ttt|}x| D ]}t| qRW t|  d S )Nzsee(Socrates, John)zsee(John, Mary)z-see(Socrates, Mary))	r	   rn   r   ro   rA   r%   r;   rL   r#   )rp   rq   rr   r0   rs   commandr   r   r   r   combination_prover_demo  s    rz   c              C   s   t j} g }|| d || d || d || d || d || d || d || d || d	 || d
 || d || d || d || d td |}tt|}x| D ]}t| qW td| td| td| d S )Nz'all x.(elephant(x)        -> animal(x))z'all x.(bird(x)            -> animal(x))z%all x.(dove(x)            -> bird(x))z%all x.(ostrich(x)         -> bird(x))z(all x.(flying_ostrich(x)  -> ostrich(x))z)all x.((animal(x)  & -Ab1(x)) -> -fly(x))z(all x.((bird(x)    & -Ab2(x)) -> fly(x))z)all x.((ostrich(x) & -Ab3(x)) -> -fly(x))z#all x.(bird(x)           -> Ab1(x))z#all x.(ostrich(x)        -> Ab2(x))z#all x.(flying_ostrich(x) -> Ab3(x))zelephant(E)zdove(D)z
ostrich(O)z-fly(E)zfly(D)z-fly(O))	r	   rn   rB   r   r;   rL   r#   ro   print_proof)rp   premisesrs   ry   r   r   r   r   default_reasoning_demo  s4    





r}   c             C   s8   t j}t|| |}tt|}t| | |  d S )N)r	   rn   r   r;   rL   ro   rA   )r"   r|   rp   rs   ry   r   r   r   r{      s    r{   c               C   s"   t   t  t  t  t  d S )N)rv   rw   rx   rz   r}   r   r   r   r   demo'  s
    r~   __main__N),r:   collectionsr   	functoolsr   Znltk.inference.prover9r   r   Znltk.sem.logicr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   Znltk.inference.apir   r   rk   r   r$   r%   r;   r=   r>   rL   objectrb   rv   rw   rx   rz   r}   r{   r~   r   r   r   r   r   <module>   s,   @3+ 
*E,,
