§
    OŠtjZL  ã                   óæ   — d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 d„ Z
d„ Zd„ Zd	„ Zd
„ Zd„ Z G d„ de¦  «        Z G d„ d¦  «        Z G d„ d¦  «        Z G d„ de¦  «        Z G d„ de¦  «        ZdS )a>  This is rule-based deduction system for SymPy

The whole thing is split into two parts

 - rules compilation and preparation of tables
 - runtime inference

For rule-based inference engines, the classical work is RETE algorithm [1],
[2] Although we are not implementing it in full (or even significantly)
it's still worth a read to understand the underlying ideas.

In short, every rule in a system of rules is one of two forms:

 - atom                     -> ...      (alpha rule)
 - And(atom1, atom2, ...)   -> ...      (beta rule)


The major complexity is in efficient beta-rules processing and usually for an
expert system a lot of effort goes into code that operates on beta-rules.


Here we take minimalistic approach to get something usable first.

 - (preparation)    of alpha- and beta- networks, everything except
 - (runtime)        FactRules.deduce_all_facts

             _____________________________________
            ( Kirr: I've never thought that doing )
            ( logic stuff is that difficult...    )
             -------------------------------------
                    o   ^__^
                     o  (oo)\_______
                        (__)\       )\/\
                            ||----w |
                            ||     ||


Some references on the topic
----------------------------

[1] https://en.wikipedia.org/wiki/Rete_algorithm
[2] http://reports-archive.adm.cs.cmu.edu/anon/1995/CMU-CS-95-113.pdf

https://en.wikipedia.org/wiki/Propositional_formula
https://en.wikipedia.org/wiki/Inference_rule
https://en.wikipedia.org/wiki/List_of_rules_of_inference
é    )Údefaultdict)ÚIteratoré   )ÚLogicÚAndÚOrÚNotc                 ó>   — t          | t          ¦  «        r| j        S | S )zdReturn the literal fact of an atom.

    Effectively, this merely strips the Not around a fact.
    ©Ú
isinstancer	   Úarg©Úatoms    úN/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sympy/core/facts.pyÚ
_base_factr   7   s"   € õ
 �$�ÑÔð ØŒxˆàˆó    c                 óF   — t          | t          ¦  «        r	| j        dfS | dfS )NFTr   r   s    r   Ú_as_pairr   B   s+   € Ý�$�ÑÔð Ø”˜%Ð Ð à�dˆ|Ðr   c                 óÚ   — t          | ¦  «        } t          ¦   «         j        t          t           |¦  «        Ž }|D ]/}|D ]*}||f|v r"|D ]}||f|v r|                     ||f¦  «         Œ Œ+Œ0|S )z½
    Computes the transitive closure of a list of implications

    Uses Warshall's algorithm, as described at
    http://www.cs.hope.edu/~cusack/Notes/Notes/DiscreteMath/Warshall.pdf.
    )ÚsetÚunionÚmapÚadd)ÚimplicationsÚfull_implicationsÚliteralsÚkÚiÚjs         r   Útransitive_closurer    K   s£   € õ ˜LÑ)Ô)ÐØ�s‰uŒuŒ{�C¥Ð%6Ñ7Ô7Ð8€Hàð 6ð 6ˆØð 	6ð 	6ˆAØ�1ˆvÐ*Ð*Ð*Ø!ð 6ð 6�AØ˜1�vÐ!2Ð2Ð2Ø)×-Ò-¨q°!¨fÑ5Ô5Ð5øøð		6ð Ðr   c           	      ór  — | d„ | D ¦   «         z   } t          t          ¦  «        }t          | ¦  «        }|D ]'\  }}||k    rŒ||                              |¦  «         Œ(|                     ¦   «         D ]E\  }}|                     |¦  «         t          |¦  «        }||v rt          d|›d|›d|›�¦  «        ‚ŒF|S )a:  deduce all implications

       Description by example
       ----------------------

       given set of logic rules:

         a -> b
         b -> c

       we deduce all possible rules:

         a -> b, c
         b -> c


       implications: [] of (a,b)
       return:       {} of a -> set([b, c, ...])
    c                 óP   — g | ]#\  }}t          |¦  «        t          |¦  «        f‘Œ$S © ©r	   )Ú.0r   r   s      r   ú
<listcomp>z-deduce_alpha_implications.<locals>.<listcomp>s   s-   € Ð"OÐ"OÐ"O¹¸¸A¥C¨¡F¤F­C°©F¬FÐ#3Ð"OÐ"OÐ"Or   zimplications are inconsistent: z -> ú )r   r   r    r   ÚitemsÚdiscardr	   Ú
ValueError)r   Úresr   ÚaÚbÚimplÚnas          r   Údeduce_alpha_implicationsr0   _   så   € ð(  Ð"OÐ"OÀ,Ð"OÑ"OÔ"OÑO€LÝ
•cÑ
Ô
€CÝ*¨<Ñ8Ô8ÐØ!ð ð ‰ˆˆ1Ø�Š6ˆ6ØàˆAŒ�
Š
�1‰Œˆˆð —9’9‘;”;ð Nð N‰ˆˆ4Ø�Š�Q‰ŒˆÝ�‰VŒVˆØ�ˆ:ˆ:Ý�*Ø@AÀÀÀ2À2À2ÀtÀtÐLñNô Nð Nð ð €Jr   c                 óT  ‡‡— i }|                       ¦   «         D ]}t          | |         ¦  «        g f||<   Œ|D ]'\  }Š|j        D ]}||v rŒt          ¦   «         g f||<   ŒŒ(d}|r¹d}|D ]²\  }Št          |t          ¦  «        st          d¦  «        ‚t          |j        ¦  «        Š|                     ¦   «         D ]`\  }\  }}||hz  }	‰|	vrN‰                     |	¦  «        r9|                     ‰¦  «         | 	                    ‰¦  «        }
|
�||
d         z  }d}ŒaŒ³|°¹t          |¦  «        D ]{\  }\  }Št          |j        ¦  «        Š|                     ¦   «         D ]J\  }\  }}||hz  }	‰|	v rŒt          ˆˆfd„|	D ¦   «         ¦  «        rŒ0‰|	z  r|                     |¦  «         ŒKŒ||S )a¶  apply additional beta-rules (And conditions) to already-built
    alpha implication tables

       TODO: write about

       - static extension of alpha-chains
       - attaching refs to beta-nodes to alpha chains


       e.g.

       alpha_implications:

       a  ->  [b, !c, d]
       b  ->  [d]
       ...


       beta_rules:

       &(b,d) -> e


       then we'll extend a's rule to the following

       a  ->  [b, !c, d, e]
    TFzCond is not AndNr   c              3   ó`   •K  — | ](}t          |¦  «        ‰v pt          |¦  «        ‰k    V — Œ)d S ©Nr$   )r%   ÚxiÚbargsÚbimpls     €€r   ú	<genexpr>z,apply_beta_to_alpha_route.<locals>.<genexpr>Í   s>   øè è € ÐHÐH¸B•3�r‘7”7˜eÐ#Ð7¥s¨2¡w¤w°%Ò'7ÐHÐHÐHÐHÐHÐHr   )Úkeysr   Úargsr   r   Ú	TypeErrorr(   Úissubsetr   ÚgetÚ	enumerateÚanyÚappend)Úalpha_implicationsÚ
beta_rulesÚx_implÚxÚbcondÚbkÚseen_static_extensionÚximplsÚbbÚx_allÚ
bimpl_implÚbidxr5   r6   s               @@r   Úapply_beta_to_alpha_routerL   ‡   s2  øø€ ð8 €FØ×$Ò$Ñ&Ô&ð 5ð 5ˆÝÐ+¨AÔ.Ñ/Ô/°Ð4ˆˆq‰	ˆ	Ø"ð %ð %‰ˆˆuØ”*ð 	%ð 	%ˆBØ�Vˆ|ˆ|ØÝ™%œ% ˜ˆF�2‰JˆJð	%ð !ÐØ
ð 1Ø %Ðà&ð 	1ð 	1‰LˆE�5Ý˜e¥SÑ)Ô)ð 3ÝÐ 1Ñ2Ô2Ð2Ý˜œ
‘O”OˆEØ#)§<¢<¡>¤>ð 1ð 1‘�‘<�F˜BØ ! ™�à Ð%Ð%¨%¯.ª.¸Ñ*?Ô*?Ð%Ø—J’J˜uÑ%Ô%Ð%ð "(§¢¨EÑ!2Ô!2�JØ!Ð-Ø *¨Q¤-Ñ/˜Ø,0Ð)øð1ð  ð 1õ* !*¨*Ñ 5Ô 5ð  ð  Ñˆ‰nˆu�eÝ�E”J‘”ˆØ%Ÿ|š|™~œ~ð 	 ð 	 ‰OˆA‰|�˜Ø˜a˜S‘LˆEà˜ˆ~ˆ~Øõ ÐHÐHÐHÐHÐHÀ%ÐHÑHÔHÑHÔHð Øà�u‰}ð  Ø—	’	˜$‘”�øð	 ð €Mr   c                 ó6  — t          t          ¦  «        }|                      ¦   «         D ]o\  \  }}}t          |t          ¦  «        r|j        d         }|D ]B\  }}t          |t          ¦  «        r|j        d         }||                              |¦  «         ŒCŒp|S )aM  build prerequisites table from rules

       Description by example
       ----------------------

       given set of logic rules:

         a -> b, c
         b -> c

       we build prerequisites (from what points something can be deduced):

         b <- a
         c <- a, b

       rules:   {} of a -> [b, c, ...]
       return:  {} of c <- [a, b, ...]

       Note however, that this prerequisites may be *not* enough to prove a
       fact. An example is 'a -> b' rule, where prereq(a) is b, and prereq(b)
       is a. That's because a=T -> b=T, and b=F -> a=F, but a=F -> b=?
    r   )r   r   r(   r   r	   r9   r   )ÚrulesÚprereqr,   Ú_r.   r   s         r   Úrules_2prereqrQ   Ö   s¢   € õ. �ÑÔ€FØŸš™œð ð ‰‰ˆˆA�Ý�a�ÑÔð 	Ø”�q”	ˆAØð 	ð 	‰FˆQ�Ý˜!�SÑ!Ô!ð Ø”F˜1”I�Ø�1ŒI�MŠM˜!ÑÔÐÐð	ð €Mr   c                   ó   — e Zd ZdZdS )ÚTautologyDetectedz:(internal) Prover uses it for reporting detected tautologyN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   r   r   rS   rS   ü   s   € € € € € ØDÐDØ€Dr   rS   c                   óV   — e Zd ZdZd„ Zd„ Zed„ ¦   «         Zed„ ¦   «         Zd„ Z	d„ Z
dS )	ÚProveraS  ai - prover of logic rules

       given a set of initial rules, Prover tries to prove all possible rules
       which follow from given premises.

       As a result proved_rules are always either in one of two forms: alpha or
       beta:

       Alpha rules
       -----------

       This are rules of the form::

         a -> b & c & d & ...


       Beta rules
       ----------

       This are rules of the form::

         &(a,b,...) -> c & d & ...


       i.e. beta rules are join conditions that say that something follows when
       *several* facts are true at the same time.
    c                 ó:   — g | _         t          ¦   «         | _        d S r3   )Úproved_rulesr   Ú_rules_seen©Úselfs    r   Ú__init__zProver.__init__  s   € ØˆÔÝ™5œ5ˆÔÐÐr   c                 ó´   — g }g }| j         D ]I\  }}t          |t          ¦  «        r|                     ||f¦  «         Œ2|                     ||f¦  «         ŒJ||fS )z-split proved rules into alpha and beta chains)r[   r   r   r?   )r^   Úrules_alphaÚ
rules_betar,   r-   s        r   Úsplit_alpha_betazProver.split_alpha_beta"  su   € àˆØˆ
ØÔ%ð 	+ð 	+‰DˆAˆqÝ˜!�SÑ!Ô!ð +Ø×!Ò! 1 a &Ñ)Ô)Ð)Ð)à×"Ò" A q 6Ñ*Ô*Ð*Ð*Ø˜JÐ&Ð&r   c                 ó6   — |                       ¦   «         d         S )Nr   ©rc   r]   s    r   ra   zProver.rules_alpha-  ó   € à×$Ò$Ñ&Ô& qÔ)Ð)r   c                 ó6   — |                       ¦   «         d         S )Nr   re   r]   s    r   rb   zProver.rules_beta1  rf   r   c                 ó  — |rt          |t          ¦  «        rdS t          |t          ¦  «        rdS ||f| j        v rdS | j                             ||f¦  «         	 |                      ||¦  «         dS # t
          $ r Y dS w xY w)zprocess a -> b ruleN)r   Úboolr\   r   Ú_process_rulerS   )r^   r,   r-   s      r   Úprocess_rulezProver.process_rule5  s¬   € àð 	•j ¥DÑ)Ô)ð 	ØˆFÝ�a�ÑÔð 	ØˆFØˆqˆ6�TÔ%Ð%Ð%ØˆFàÔ× Ò  ! Q Ñ(Ô(Ð(ð	Ø×Ò˜q !Ñ$Ô$Ð$Ð$Ð$øÝ ð 	ð 	ð 	ØˆDˆDð	øøøs   ÁA3 Á3
BÂ Bc           	      óæ  — t          |t          ¦  «        r8t          |j        t          ¬¦  «        }|D ]}|                      ||¦  «         Œd S t          |t          ¦  «        r÷t          |j        t          ¬¦  «        }t          |t          ¦  «        s||v rt          ||d¦  «        ‚|                      t          d„ |j        D ¦   «         Ž t          |¦  «        ¦  «         t          t          |¦  «        ¦  «        D ]Z}||         }|d |…         ||dz   d …         z   }|                      t          |t          |¦  «        ¦  «        t          |Ž ¦  «         Œ[d S t          |t          ¦  «        rNt          |j        t          ¬¦  «        }||v rt          ||d¦  «        ‚| j                             ||f¦  «         d S t          |t          ¦  «        rMt          |j        t          ¬¦  «        }||v rt          ||d¦  «        ‚|D ]}|                      ||¦  «         Œd S | j                             ||f¦  «         | j                             t          |¦  «        t          |¦  «        f¦  «         d S )N)Úkeyza -> a|c|...c                 ó,   — g | ]}t          |¦  «        ‘ŒS r#   r$   )r%   Úbargs     r   r&   z(Prover._process_rule.<locals>.<listcomp>[  s   € Ð#AÐ#AÐ#A°$¥C¨¡I¤IÐ#AÐ#AÐ#Ar   r   z
a & b -> az
a | b -> a)r   r   Úsortedr9   Ústrrk   r   r   rS   r	   ÚrangeÚlenr[   r?   )	r^   r,   r-   Úsorted_bargsro   rK   ÚbrestÚsorted_aargsÚaargs	            r   rj   zProver._process_ruleF  s’  € õ �a�ÑÔð +	7Ý! !¤&­cÐ2Ñ2Ô2ˆLØ$ð +ð +�Ø×!Ò! ! TÑ*Ô*Ð*Ð*ð+ð +õ ˜�2ÑÔð #	7Ý! !¤&­cÐ2Ñ2Ô2ˆLå˜a¥Ñ'Ô'ð Bà˜Ð$Ð$Ý+¨A¨q°.ÑAÔAÐAØ×Ò�cÐ#AÐ#A¸!¼&Ð#AÑ#AÔ#AÐBÅCÈÁFÄFÑKÔKÐKå�c ,Ñ/Ô/Ñ0Ô0ð Að A�Ø# DÔ)�Ø$ U d UÔ+¨l¸4À!¹8¸9¸9Ô.EÑE�Ø×!Ò!¥# a­¨T©¬Ñ"3Ô"3µR¸°ZÑ@Ô@Ð@Ð@ðAð Aõ ˜�3ÑÔð 	7Ý! !¤&­cÐ2Ñ2Ô2ˆLØ�LÐ Ð Ý'¨¨1¨lÑ;Ô;Ð;ØÔ×$Ò$ a¨ VÑ,Ô,Ð,Ð,Ð,õ ˜�2ÑÔð 
	7Ý! !¤&­cÐ2Ñ2Ô2ˆLØ�LÐ Ð Ý'¨¨1¨lÑ;Ô;Ð;Ø$ð +ð +�Ø×!Ò! $¨Ñ*Ô*Ð*Ð*ð+ð +ð
 Ô×$Ò$ a¨ VÑ,Ô,Ð,ØÔ×$Ò$¥c¨!¡f¤f­c°!©f¬fÐ%5Ñ6Ô6Ð6Ð6Ð6r   N)rT   rU   rV   rW   r_   rc   Úpropertyra   rb   rk   rj   r#   r   r   rY   rY     s�   € € € € € ðð ð8!ð !ð !ð	'ð 	'ð 	'ð ð*ð *ñ „Xð*ð ð*ð *ñ „Xð*ðð ð ð"17ð 17ð 17ð 17ð 17r   rY   c                   óp   — e Zd ZdZd„ Zdefd„Zedefd„¦   «         Z	d„ Z
d„ Zd	„ Zd
„ Zdee         fd„ZdS )Ú	FactRulesa•  Rules that describe how to deduce facts in logic space

       When defined, these rules allow implications to quickly be determined
       for a set of facts. For this precomputed deduction tables are used.
       see `deduce_all_facts`   (forward-chaining)

       Also it is possible to gather prerequisites for a fact, which is tried
       to be proven.    (backward-chaining)


       Definition Syntax
       -----------------

       a -> b       -- a=T -> b=T  (and automatically b=F -> a=F)
       a -> !b      -- a=T -> b=F
       a == b       -- a -> b & b -> a
       a -> b & c   -- a=T -> b=T & c=T
       # TODO b | c


       Internals
       ---------

       .full_implications[k, v]: all the implications of fact k=v
       .beta_triggers[k, v]: beta rules that might be triggered when k=v
       .prereq  -- {} k <- [] of k's prerequisites

       .defined_facts -- set of defined fact names
    c                 óž  — t          |t          ¦  «        r|                     ¦   «         }t          ¦   «         }|D ]¥}|                     dd¦  «        \  }}}t          j        |¦  «        }t          j        |¦  «        }|dk    r|                     ||¦  «         Œa|dk    r-|                     ||¦  «         |                     ||¦  «         Œ”t          d|z  ¦  «        ‚g | _	        |j
        D ]=\  }}| j	                             d„ |j        D ¦   «         t          |¦  «        f¦  «         Œ>t          |j        ¦  «        }	t!          |	|j
        ¦  «        }
d„ |
                     ¦   «         D ¦   «         | _        t'          t(          ¦  «        }t'          t(          ¦  «        }|
                     ¦   «         D ]6\  }\  }}d„ |D ¦   «         |t          |¦  «        <   ||t          |¦  «        <   Œ7|| _        || _        t'          t(          ¦  «        }t1          |¦  «        }|                     ¦   «         D ]\  }}||xx         |z  cc<   Œ|| _        dS )	z)Compile rules into internal lookup tablesNé   z->z==zunknown op %rc                 ó,   — h | ]}t          |¦  «        ’ŒS r#   ©r   )r%   r,   s     r   ú	<setcomp>z%FactRules.__init__.<locals>.<setcomp>·  s   € Ð2Ð2Ð2 !•(˜1‘+”+Ð2Ð2Ð2r   c                 ó,   — h | ]}t          |¦  «        ’ŒS r#   )r   )r%   r   s     r   r   z%FactRules.__init__.<locals>.<setcomp>Ã  s   € ÐDÐDÐD°�j¨™mœmÐDÐDÐDr   c                 ó,   — h | ]}t          |¦  «        ’ŒS r#   r~   ©r%   r   s     r   r   z%FactRules.__init__.<locals>.<setcomp>É  s   € Ð-HÐ-HÐ-H¸a­h°q©k¬kÐ-HÐ-HÐ-Hr   )r   rq   Ú
splitlinesrY   Úsplitr   Ú
fromstringrk   r*   rA   rb   r?   r9   r   r0   ra   rL   r8   Údefined_factsr   r   r(   r   Úbeta_triggersrQ   rO   )r^   rN   ÚPÚruler,   Úopr-   rD   r6   Úimpl_aÚimpl_abr   r‡   r   r.   ÚbetaidxsrO   Ú
rel_prereqÚpitemss                      r   r_   zFactRules.__init__›  sf  € õ �e�SÑ!Ô!ð 	'Ø×$Ò$Ñ&Ô&ˆEõ ‰HŒHˆàð 	7ð 	7ˆDà—z’z $¨Ñ*Ô*‰HˆAˆr�1åÔ  Ñ#Ô#ˆAÝÔ  Ñ#Ô#ˆAà�TŠzˆzØ—’˜q !Ñ$Ô$Ð$Ð$Ø�t’�Ø—’˜q !Ñ$Ô$Ð$Ø—’˜q !Ñ$Ô$Ð$Ð$å  °2Ñ!5Ñ6Ô6Ð6ð ˆŒØœLð 	Fð 	F‰LˆE�5ØŒO×"Ò"Ø2Ð2 u¤zÐ2Ñ2Ô2µH¸U±O´OÐDñFô Fð Fð Fõ +¨1¬=Ñ9Ô9ˆõ ,¨F°A´LÑAÔAˆð EÐD°W·\²\±^´^ÐDÑDÔDˆÔõ (­Ñ,Ô,ÐÝ#¥CÑ(Ô(ˆØ#*§=¢=¡?¤?ð 	2ð 	2ÑˆAÑ��hØ-HÐ-HÀ4Ð-HÑ-HÔ-HÐ�h q™kœkÑ*Ø)1ˆM�( 1™+œ+Ñ&Ð&à!2ˆÔØ*ˆÔõ �SÑ!Ô!ˆÝ"Ð#4Ñ5Ô5ˆ
Ø#×)Ò)Ñ+Ô+ð 	 ð 	 ‰IˆAˆvØ�1ˆIˆIŒI˜ÑˆIˆI‰IˆIØˆŒˆˆr   Úreturnc                 óP   — d                      |                      ¦   «         ¦  «        S )zD Generate a string with plain python representation of the instance ú
)ÚjoinÚprint_rulesr]   s    r   Ú
_to_pythonzFactRules._to_pythonÖ  s    € à�yŠy˜×)Ò)Ñ+Ô+Ñ,Ô,Ð,r   Údatac                 óô   —  | d¦  «        }dD ]B}t          t          ¦  «        }|                     ||         ¦  «         t          |||¦  «         ŒC|d         |_        t          |d         ¦  «        |_        |S )z; Generate an instance from the plain python representation Ú )r   r‡   rO   rA   r†   )r   r   ÚupdateÚsetattrrA   r†   )Úclsr–   r^   rm   Úds        r   Ú_from_pythonzFactRules._from_pythonÚ  s~   € ð ˆs�2‰wŒwˆØCð 	"ð 	"ˆCÝ�#ÑÔˆAØ�HŠH�T˜#”YÑÔÐÝ�D˜#˜qÑ!Ô!Ð!Ð!Ø˜|Ô,ˆŒÝ   oÔ!6Ñ7Ô7ˆÔàˆr   c              #   óX   K  — dV — t          | j        ¦  «        D ]
}d|›d�V — ŒdV — d S )Nzdefined_facts = [ú    ú,z] # defined_facts)rp   r†   )r^   Úfacts     r   Ú_defined_facts_lineszFactRules._defined_facts_linesç  sX   è è € Ø!Ð!Ð!Ð!Ý˜4Ô-Ñ.Ô.ð 	#ð 	#ˆDØ"˜Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ø!Ð!Ð!Ð!Ð!Ð!r   c              #   óà   K  — dV — t          | j        ¦  «        D ]N}dD ]I}d|› d|› d�V — d|›d|›d�V — | j        ||f         }t          |¦  «        D ]
}d	|›d
�V — ŒdV — dV — ŒJŒOdV — d S )Nzfull_implications = dict( [)TFz    # Implications of ú = ú:z    ((ú, z	), set( (ú        r    z       ) ),z     ),z ] ) # full_implications)rp   r†   r   )r^   r¡   Úvaluer   Úimplieds        r   Ú_full_implications_linesz"FactRules._full_implications_linesí  së   è è € Ø+Ð+Ð+Ð+Ý˜4Ô-Ñ.Ô.ð 	 ð 	 ˆDØ&ð  ð  �Ø@¨tÐ@Ð@¸Ð@Ð@Ð@Ð@Ð@Ð@Ø;˜tÐ;Ð;¨Ð;Ð;Ð;Ð;Ð;Ð;Ø#Ô5°t¸U°mÔD�Ý% lÑ3Ô3ð 2ð 2�GØ1 WÐ1Ð1Ð1Ð1Ð1Ð1Ð1Ø#Ð#Ð#Ð#Ø����ð ð )Ð(Ð(Ð(Ð(Ð(r   c              #   óÈ   K  — dV — dV — t          | j        ¦  «        D ]>}d|› �V — d|›d�V — t          | j        |         ¦  «        D ]
}d|›d�V — ŒdV — dV — Œ?d	V — d S )
Nz
prereq = {r˜   z.    # facts that could determine the value of rŸ   z: {r§   r    z    },z
} # prereq)rp   rO   )r^   r¡   Úpfacts      r   Ú_prereq_lineszFactRules._prereq_linesú  s½   è è € ØÐÐÐØˆˆˆÝ˜4œ;Ñ'Ô'ð 	ð 	ˆDØIÀ4ÐIÐIÐIÐIÐIØ%˜Ð%Ð%Ð%Ð%Ð%Ð%Ý ¤¨DÔ 1Ñ2Ô2ð ,ð ,�Ø+ Ð+Ð+Ð+Ð+Ð+Ð+Ð+ØˆNˆNˆNØˆHˆHˆHˆHØÐÐÐÐÐr   c           
   #   ód  ‡K  — t          t          ¦  «        }t          | j        ¦  «        D ]%\  }\  }}||                              ||f¦  «         Œ&dV — dV — dV — d}i Št          |¦  «        D ]r}|\  }}d|› d|› �V — ||         D ]T\  }}|‰|<   |dz  }d                     t          t          t          |¦  «        ¦  «        ¦  «        }d	|› d
�V — d|›d�V — ŒUdV — ŒsdV — dV — t          | j	        ¦  «        D ]+}	|	\  }}ˆfd„| j	        |	         D ¦   «         }
d|	›d|
›d�V — Œ,dV — d S )Nz@# Note: the order of the beta rules is used in the beta_triggerszbeta_rules = [r˜   r   z    # Rules implying r¤   r   r¦   z    ({z},r§   z),z] # beta_ruleszbeta_triggers = {c                 ó    •— g | ]
}‰|         ‘ŒS r#   r#   )r%   ÚnÚindicess     €r   r&   z/FactRules._beta_rules_lines.<locals>.<listcomp>  s   ø€ ÐFÐFÐF q˜ œ
ÐFÐFÐFr   rŸ   z: r    z} # beta_triggers)
r   Úlistr=   rA   r?   rp   r“   r   rq   r‡   )r^   Úreverse_implicationsr°   Úprer©   Úmr¡   r¨   ÚsetstrÚqueryÚtriggersr±   s              @r   Ú_beta_rules_lineszFactRules._beta_rules_lines  sÖ  øè è € Ý*­4Ñ0Ô0ÐÝ!*¨4¬?Ñ!;Ô!;ð 	;ð 	;ÑˆA‰~��WØ  Ô)×0Ò0°#°q°Ñ:Ô:Ð:Ð:àPÐPÐPÐPØÐÐÐØˆˆˆØˆØˆÝÐ2Ñ3Ô3ð 		ð 		ˆGØ!‰KˆD�%Ø:¨$Ð:Ð:°5Ð:Ð:Ð:Ð:Ð:Ø.¨wÔ7ð /ð /‘��QØ�˜‘
Ø�Q‘�ØŸš¥3¥s­F°3©K¬KÑ#8Ô#8Ñ9Ô9�Ø+ Ð+Ð+Ð+Ð+Ð+Ð+Ø. Ð.Ð.Ð.Ð.Ð.Ð.Ð.ØˆHˆHˆHˆHØÐÐÐà!Ð!Ð!Ð!Ý˜DÔ.Ñ/Ô/ð 	2ð 	2ˆEØ‰KˆD�%ØFÐFÐFÐF¨DÔ,>¸uÔ,EÐFÑFÔFˆHØ1˜Ð1Ð1 HÐ1Ð1Ð1Ð1Ð1Ð1Ð1Ø!Ð!Ð!Ð!Ð!Ð!r   c              #   ó*  K  — |                       ¦   «         E d{V —† dV — dV — |                      ¦   «         E d{V —† dV — dV — |                      ¦   «         E d{V —† dV — dV — |                      ¦   «         E d{V —† dV — dV — dV — dV — dS )zA Returns a generator with lines to represent the facts and rules Nr˜   z`generated_assumptions = {'defined_facts': defined_facts, 'full_implications': full_implications,zZ               'prereq': prereq, 'beta_rules': beta_rules, 'beta_triggers': beta_triggers})r¢   rª   r­   r¹   r]   s    r   r”   zFactRules.print_rules#  sü   è è € à×,Ò,Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.ØˆˆˆØˆˆˆØ×0Ò0Ñ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2Ð2ØˆˆˆØˆˆˆØ×%Ò%Ñ'Ô'Ð'Ð'Ð'Ð'Ð'Ð'Ð'ØˆˆˆØˆˆˆØ×)Ò)Ñ+Ô+Ð+Ð+Ð+Ð+Ð+Ð+Ð+ØˆˆˆØˆˆˆØpÐpÐpÐpØjÐjÐjÐjÐjÐjr   N)rT   rU   rV   rW   r_   rq   r•   ÚclassmethodÚdictr�   r¢   rª   r­   r¹   r   r”   r#   r   r   rz   rz   |  sÒ   € € € € € ðð ð<9ð 9ð 9ðv-˜Cð -ð -ð -ð -ð ð
 ð 
ð 
ð 
ñ „[ð
ð"ð "ð "ð)ð )ð )ð
ð 
ð 
ð"ð "ð "ð:k˜X cœ]ð kð kð kð kð kð kr   rz   c                   ó   — e Zd Zd„ ZdS )ÚInconsistentAssumptionsc                 ó,   — | j         \  }}}|›d|›d|›�S )Nr¦   ú=)r9   )r^   Úkbr¡   r¨   s       r   Ú__str__zInconsistentAssumptions.__str__6  s&   € Øœ)‰ˆˆD�%Ø ˜b˜b $ $ $¨¨Ð.Ð.r   N)rT   rU   rV   rÂ   r#   r   r   r¾   r¾   5  s#   € € € € € ð/ð /ð /ð /ð /r   r¾   c                   ó*   — e Zd ZdZd„ Zd„ Zd„ Zd„ ZdS )ÚFactKBzT
    A simple propositional knowledge base relying on compiled inference rules.
    c                 ó„   — dd                      d„ t          |                      ¦   «         ¦  «        D ¦   «         ¦  «        z  S )Nz{
%s}z,
c                 ó   — g | ]}d |z  ‘ŒS )z	%s: %sr#   r‚   s     r   r&   z"FactKB.__str__.<locals>.<listcomp>A  s   € Ð:Ð:Ð: ˆZ˜!‰^Ð:Ð:Ð:r   )r“   rp   r(   r]   s    r   rÂ   zFactKB.__str__?  s@   € Ø˜%Ÿ*š*Ø:Ð:¥V¨D¯JªJ©L¬LÑ%9Ô%9Ð:Ñ:Ô:ñ<ô <ñ <ð 	<r   c                 ó   — || _         d S r3   )rN   )r^   rN   s     r   r_   zFactKB.__init__C  s   € ØˆŒ
ˆ
ˆ
r   c                 óf   — || v r'| |         �| |         |k    rdS t          | ||¦  «        ‚|| |<   dS )zxAdd fact k=v to the knowledge base.

        Returns True if the KB has actually been updated, False otherwise.
        NFT)r¾   )r^   r   Úvs      r   Ú_tellzFactKB._tellF  sH   € ð
 �ˆ9ˆ9˜˜aœÐ,Ø�AŒw˜!Š|ˆ|Ø�uå-¨d°A°qÑ9Ô9Ð9àˆD�‰GØ�4r   c                 ó  ‡ — ‰ j         j        }‰ j         j        }‰ j         j        }t	          |t
          ¦  «        r|                     ¦   «         }|r¸t          ¦   «         }|D ]a\  }}‰                      ||¦  «        r|€Œ|||f         D ]\  }}	‰                      ||	¦  «         Œ| 	                    |||f         ¦  «         Œbg }|D ]=}
||
         \  }}t          ˆ fd„|D ¦   «         ¦  «        r|                     |¦  «         Œ>|°¶dS dS )z©
        Update the KB with all the implications of a list of facts.

        Facts can be specified as a dictionary or as a list of (key, value)
        pairs.
        Nc              3   óL   •K  — | ]\  }}‰                      |¦  «        |u V — Œd S r3   )r<   )r%   r   rÉ   r^   s      €r   r7   z*FactKB.deduce_all_facts.<locals>.<genexpr>y  s6   øè è € Ð:Ð:©D¨A¨q�t—x’x ‘{”{ aÐ'Ð:Ð:Ð:Ð:Ð:Ð:r   )rN   r   r‡   rA   r   r¼   r(   r   rÊ   r™   Úallr?   )r^   Úfactsr   r‡   rA   Úbeta_maytriggerr   rÉ   rm   r¨   rK   rD   r6   s   `            r   Údeduce_all_factszFactKB.deduce_all_factsW  sU  ø€ ð !œJÔ8ÐØœ
Ô0ˆØ”ZÔ*ˆ
å�e�TÑ"Ô"ð 	"Ø—K’K‘M”MˆEàð 	(Ý!™eœeˆOð ð <ð <‘��1Ø—z’z ! QÑ'Ô'ð ¨1¨9Øð #4°A°q°DÔ"9ð +ð +‘J�C˜Ø—J’J˜s EÑ*Ô*Ð*Ð*à×&Ò& }°Q¸°TÔ':Ñ;Ô;Ð;Ð;ð ˆEØ'ð (ð (�Ø)¨$Ô/‘��uÝÐ:Ð:Ð:Ð:°EÐ:Ñ:Ô:Ñ:Ô:ð (Ø—L’L Ñ'Ô'Ð'øð' ð 	(ð 	(ð 	(ð 	(ð 	(r   N)rT   rU   rV   rW   rÂ   r_   rÊ   rÐ   r#   r   r   rÄ   rÄ   ;  sZ   € € € € € ðð ð<ð <ð <ðð ð ðð ð ð"#(ð #(ð #(ð #(ð #(r   rÄ   N)rW   Úcollectionsr   Útypingr   Úlogicr   r   r   r	   r   r   r    r0   rL   rQ   Ú	ExceptionrS   rY   rz   r*   r¾   r¼   rÄ   r#   r   r   ú<module>rÕ      s¬  ðð.ð .ð` $Ð #Ð #Ð #Ð #Ð #Ø Ð Ð Ð Ð Ð à &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &ðð ð ðð ð ðð ð ð(%ð %ð %ðPLð Lð Lð^ð ð ðL	ð 	ð 	ð 	ð 	˜	ñ 	ô 	ð 	ð
v7ð v7ð v7ð v7ð v7ñ v7ô v7ð v7ðvvkð vkð vkð vkð vkñ vkô vkð vkðr/ð /ð /ð /ð /˜jñ /ô /ð /ð?(ð ?(ð ?(ð ?(ð ?(ˆTñ ?(ô ?(ð ?(ð ?(ð ?(r   