ó
    ‰*£hZL  ã                   óÆ   • S r SSKJr  SSKJr  SSKJrJrJrJ	r	  S r
S rS rS	 rS
 rS r " S S\5      r " S S5      r " S S5      r " S S\5      r " S S\5      rg)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                 óH   • [        U [        5      (       a  U R                  $ U $ )z\Return the literal fact of an atom.

Effectively, this merely strips the Not around a fact.
©Ú
isinstancer	   Úarg©Úatoms    ÚM/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sympy/core/facts.pyÚ
_base_factr   7   s   € ô
 �$œ×ÑØ�x‰xˆàˆó    c                 óP   • [        U [        5      (       a  U R                  S4$ U S4$ )NFTr   r   s    r   Ú_as_pairr   B   s(   € Ü�$œ×ÑØ—‘˜%Ð Ð à�dˆ|Ðr   c                 óä   • [        U 5      n[        5       R                  " [        [         U5      6 nU H9  nU H0  nXC4U;   d  M  U H  nX54U;   d  M  UR                  XE45        M      M2     M;     U$ )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   ss   € ô ˜LÓ)ÐÜ‹u�{Š{œC¤Ð%6Ó7Ð8€HãˆÛˆAØˆvÐ*Õ*Û!�AØ�vÐ!2Õ2Ø)×-Ñ-¨q¨fÖ5ó "ó ñ ð Ðr   c           	      óŒ  • X  VVs/ s H  u  p[        U5      [        U5      4PM     snn-   n [        [        5      n[        U 5      nU H  u  pVXV:X  a  M  X5   R	                  U5        M!     UR                  5        H=  u  pWUR                  U5        [        U5      nX‡;   d  M(  [        SU< SU< SU< 35      e   U$ s  snnf )zð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, ...])
zimplications are inconsistent: z -> Ú )r	   r   r   r    r   ÚitemsÚdiscardÚ
ValueError)	r   r   r   Úresr   ÚaÚbÚimplÚnas	            r   Údeduce_alpha_implicationsr+   _   sµ   € ð(  À,Ô"OÂ,¹¸¤C¨£F¬C°«FÓ#3Á,Ò"OÑO€LÜ
”cÓ
€CÜ*¨<Ó8ÐÛ!‰ˆØ‹6Ùà‰�
‰
�1Žñ	 "ð —9‘9–;‰ˆØ�‰�QŒÜ�‹VˆØ�:ÝÛ@AÃ2ÂtÐLóNð Nñ	 ð €Jùó# #Ps   †"C c                 ón  ^^• 0 nU R                  5        H  n[        X   5      / 4X#'   M     U H.  u  nmUR                   H  nXR;   a  M
  [        5       / 4X%'   M     M0     SnU(       a»  SnU Hª  u  nm[        U[        5      (       d  [        S5      e[        UR                  5      mUR                  5        H[  u  nu  pxXs1-  n	TU	;  d  M  TR                  U	5      (       d  M-  UR                  T5        UR                  T5      n
U
b  XzS   -  nSnM]     M¬     U(       a  M»  [        U5       H�  u  nu  nm[        UR                  5      mUR                  5        HO  u  nu  pxXs1-  n	TU	;   a  M  [        UU4S jU	 5       5      (       a  M2  TU	-  (       d  M>  UR                  U5        MQ     Mƒ     U$ )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 Andr   c              3   ój   >#   • U  H(  n[        U5      T;   =(       d    [        U5      T:H  v •  M*     g 7f©N)r	   )Ú.0ÚxiÚbargsÚbimpls     €€r   Ú	<genexpr>Ú,apply_beta_to_alpha_route.<locals>.<genexpr>Í   s+   øé € ÐHÂ%¸B”3�r“7˜eÑ#×7¤s¨2£w°%Ñ'7Ô7Â%ùs   ƒ03)Ú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Úbidxr1   r2   s               @@r   Úapply_beta_to_alpha_routerI   ‡   sš  ù€ ð8 €FØ×$Ñ$Ö&ˆÜÐ+Ñ.Ó/°Ð4ˆ‹	ñ 'ã"‰ˆˆuØ—*”*ˆBØ‹|ÙÜ›% ˜ˆF‹Jó ñ #ð !ÐÞ
Ø %Ðã&‰LˆE�5Ü˜e¤S×)Ñ)ÜÐ 1Ó2Ð2Ü˜Ÿ
™
“OˆEØ#)§<¡<¦>‘�‘<�FØ ™�à Õ%¨%¯.©.¸×*?Ó*?Ø—J‘J˜uÔ%ð "(§¡¨EÓ!2�JØ!Ñ-Ø¨Q¡-Ñ/˜Ø,0Ò)ó $2ñ	 '÷  Ð
ô* !*¨*Ö 5Ñˆ‰nˆu�eÜ�E—J‘J“ˆØ%Ÿ|™|ž~‰OˆA‰|�Ø˜S‘LˆEà˜‹~Ùô ÕHÁ%ÓH×HÑHÙà�u�}‰}Ø—	‘	˜$–ó  .ñ !6ð €Mr   c                 ó(  • [        [        5      nU R                  5        Hn  u  u  p#n[        U[        5      (       a  UR
                  S   nU H<  u  pS[        U[        5      (       a  UR
                  S   nX   R                  U5        M>     Mp     U$ )aî  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	   r6   r   )ÚrulesÚprereqr'   Ú_r)   r   s         r   Úrules_2prereqrN   Ö   sy   € ô. œÓ€FØŸ™ž‰‰ˆ�Ü�aœ×ÑØ—‘�q‘	ˆAÛ‰FˆQÜ˜!œS×!Ñ!Ø—F‘F˜1‘I�Ø‰I�M‰M˜!Öó ñ &ð €Mr   c                   ó   • \ rS rSrSrSrg)ÚTautologyDetectedéü   z:(internal) Prover uses it for reporting detected tautology© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__rR   r   r   rP   rP   ü   s   † ÙDÚr   rP   c                   óP   • \ rS rSrSrS rS r\S 5       r\S 5       r	S r
S rS	rg
)ÚProveri  aí  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                 ó0   • / U l         [        5       U l        g r.   )Úproved_rulesr   Ú_rules_seen©Úselfs    r   Ú__init__ÚProver.__init__  s   € ØˆÔÜ›5ˆÕr   c                 ó°   • / n/ nU R                    H@  u  p4[        U[        5      (       a  UR                  X445        M.  UR                  X445        MB     X4$ )z-split proved rules into alpha and beta chains)r\   r   r   r<   )r_   Úrules_alphaÚ
rules_betar'   r(   s        r   Úsplit_alpha_betaÚProver.split_alpha_beta"  sV   € àˆØˆ
Ø×%Ô%‰DˆAÜ˜!œS×!Ñ!Ø×!Ñ! 1 &Ö)à×"Ñ" A 6Ö*ñ	 &ð
 Ð&Ð&r   c                 ó(   • U R                  5       S   $ )Nr   ©re   r^   s    r   rc   ÚProver.rules_alpha-  ó   € à×$Ñ$Ó& qÑ)Ð)r   c                 ó(   • U R                  5       S   $ )Nr   rh   r^   s    r   rd   ÚProver.rules_beta1  rj   r   c                 ó
  • U(       a  [        U[        5      (       a  g[        U[        5      (       a  gX4U R                  ;   a  gU R                  R                  X45         U R	                  X5        g! [
         a     gf = f)zprocess a -> b ruleN)r   Úboolr]   r   Ú_process_rulerP   )r_   r'   r(   s      r   Úprocess_ruleÚProver.process_rule5  sr   € æ”j ¤D×)Ñ)ØÜ�aœ×ÑØØˆ6�T×%Ñ%Ó%Øà×Ñ× Ñ  ! Ô(ð	Ø×Ñ˜qÕ$øÜ ó 	Ùð	ús   Á#A5 Á5
BÂBc           
      ó|  • [        U[        5      (       a3  [        UR                  [        S9nU H  nU R                  X5        M     g [        U[        5      (       aÛ  [        UR                  [        S9n[        U[        5      (       d  X;   a  [        XS5      eU R                  [        UR                   Vs/ s H  n[        U5      PM     sn6 [        U5      5        [        [        U5      5       H?  nX5   nUS U X5S-   S  -   nU R                  [        U[        U5      5      [        U6 5        MA     g [        U[        5      (       aF  [        UR                  [        S9nX';   a  [        XS5      eU R                  R                  X45        g [        U[        5      (       aD  [        UR                  [        S9nX';   a  [        XS5      eU H  nU R                  X‚5        M     g U R                  R                  X45        U R                  R                  [        U5      [        U5      45        g s  snf )N)Úkeyza -> a|c|...r   z
a & b -> az
a | b -> a)r   r   Úsortedr6   Ústrrp   r   r   rP   r	   ÚrangeÚlenr\   r<   )	r_   r'   r(   Úsorted_bargsÚbargrH   ÚbrestÚsorted_aargsÚaargs	            r   ro   ÚProver._process_ruleF  sÎ  € ô �aœ×ÑÜ! !§&¡&¬cÑ2ˆLÛ$�Ø×!Ñ! !Ö*ò %ô ˜œ2×ÑÜ! !§&¡&¬cÑ2ˆLä˜a¤×'Ñ'àÓ$Ü+¨A°.ÓAÐAØ×Ñœc¸!¿&º&Ó#Aº&°$¤C¨¦I¹&Ñ#AÐBÄCÈÃFÔKäœc ,Ó/Ö0�Ø#Ñ)�Ø$ U dÐ+¨lÀ!¹8¸9Ð.EÑE�Ø×!Ñ!¤# a¬¨T«Ó"3´R¸°ZÖ@ò 1ô ˜œ3×ÑÜ! !§&¡&¬cÑ2ˆLØÓ Ü'¨¨lÓ;Ð;Ø×Ñ×$Ñ$ a VÕ,ô ˜œ2×ÑÜ! !§&¡&¬cÑ2ˆLØÓ Ü'¨¨lÓ;Ð;Û$�Ø×!Ñ! $Ö*ò %ð
 ×Ñ×$Ñ$ a VÔ,Ø×Ñ×$Ñ$¤c¨!£f¬c°!«fÐ%5Õ6ùò9 $Bs   Â:H9)r]   r\   N)rS   rT   rU   rV   rW   r`   re   Úpropertyrc   rd   rp   ro   rX   rR   r   r   rZ   rZ     sC   † ñò8!ò	'ð ñ*ó ð*ð ñ*ó ð*òõ"17r   rZ   c                   óp   • \ rS rSrSrS rS\4S jr\S\	4S j5       r
S rS	 rS
 rS rS\\   4S jrSrg)Ú	FactRulesi|  a  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           	      ó¶  • [        U[        5      (       a  UR                  5       n[        5       nU H“  nUR	                  SS5      u  pEn[
        R                  " U5      n[
        R                  " U5      nUS:X  a  UR                  XF5        M]  US:X  a$  UR                  XF5        UR                  Xd5        M‡  [        SU-  5      e   / U l	        UR                   HO  u  pxU R                  R                  UR                   Vs1 s H  n[        U5      iM     sn[        U5      45        MQ     [        UR                  5      n	[!        X’R                  5      n
U
R#                  5        Vs1 s H  n[%        U5      iM     snU l        [)        [*        5      n[)        [*        5      nU
R-                  5        H=  u  nu  pïU Vs1 s H  n[        U5      iM     snU[        U5      '   Xý[        U5      '   M?     XÀl        XÐl        [)        [*        5      n[3        U5      nUR-                  5        H  u  nnUU==   U-  ss'   M     UU l        gs  snf s  snf s  snf )z)Compile rules into internal lookup tablesNé   z->z==zunknown op %r)r   ru   Ú
splitlinesrZ   Úsplitr   Ú
fromstringrp   r%   r>   rd   r<   r6   r   r+   rc   rI   r5   r   Údefined_factsr   r   r#   r   Úbeta_triggersrN   rL   )r_   rK   ÚPÚruler'   Úopr(   rA   r2   Úimpl_aÚimpl_abr   r   r‡   r)   Úbetaidxsr   rL   Ú
rel_prereqÚpitemss                       r   r`   ÚFactRules.__init__›  sù  € ô �eœS×!Ñ!Ø×$Ñ$Ó&ˆEô ‹HˆãˆDà—z‘z $¨Ó*‰HˆA�1ä× Ò  Ó#ˆAÜ× Ò  Ó#ˆAà�T‹zØ—‘˜qÖ$Ø�t“Ø—‘˜qÔ$Ø—‘˜qÖ$ä  °2Ñ!5Ó6Ð6ñ ð  ˆŒØŸLœL‰LˆEØ�O‰O×"Ñ"Ø',§z¢zÓ2¢z !”(˜1–+¡zÑ2´H¸U³OÐDöFñ )ô
 +¨1¯=©=Ó9ˆô ,¨F·L±LÓAˆð 6=·\±\´^ÓD²^°œj¨žm±^ÑDˆÔô (¬Ó,ÐÜ#¤CÓ(ˆØ#*§=¡=¦?ÑˆAÑ�ÙCGÓ-HÂ4¸a¬h°q®kÁ4Ñ-HÐœh q›kÑ*Ø)1œ( 1›+Ó&ñ $3ð "3ÔØ*Ôô œSÓ!ˆÜ"Ð#4Ó5ˆ
Ø#×)Ñ)Ö+‰IˆAˆvØ�1‹I˜Ñ�Iñ ,àˆ�ùò; 3ùò Eùò .Is   ÄI
Å+IÇIÚreturnc                 ó@   • SR                  U R                  5       5      $ )zCGenerate a string with plain python representation of the instance Ú
)ÚjoinÚprint_rulesr^   s    r   Ú
_to_pythonÚFactRules._to_pythonÖ  s   € à�y‰y˜×)Ñ)Ó+Ó,Ð,r   Údatac                 ó¾   • U " S5      nS H1  n[        [        5      nUR                  X   5        [        X#U5        M3     US   Ul        [        US   5      Ul        U$ )z:Generate an instance from the plain python representation Ú )r   r‡   rL   r>   r†   )r   r   ÚupdateÚsetattrr>   r†   )Úclsr˜   r_   rs   Úds        r   Ú_from_pythonÚFactRules._from_pythonÚ  s_   € ñ �2‹wˆÛCˆCÜœ#ÓˆAØ�H‰H�T‘YÔÜ�D˜qÖ!ñ Dð ˜|Ñ,ˆŒÜ   oÑ!6Ó7ˆÔàˆr   c              #   óf   #   • Sv •  [        U R                  5       H  nSU< S3v •  M     Sv •  g 7f)Nzdefined_facts = [ú    Ú,z] # defined_facts)rt   r†   )r_   Úfacts     r   Ú_defined_facts_linesÚFactRules._defined_facts_linesç  s5   é € Ø!Ò!Ü˜4×-Ñ-Ö.ˆDØ˜™ Ð"Ô"ñ /à!Ó!ùs   ‚/1c              #   óü   #   • Sv •  [        U R                  5       HW  nS HN  nSU SU S3v •  SU< SU< S3v •  U R                  X4   n[        U5       H  nS	U< S
3v •  M     Sv •  Sv •  MP     MY     Sv •  g 7f)Nzfull_implications = dict( [)TFz    # Implications of ú = Ú:z    ((ú, z	), set( (ú        r£   z       ) ),z     ),z ] ) # full_implications)rt   r†   r   )r_   r¤   Úvaluer   Úimplieds        r   Ú_full_implications_linesÚ"FactRules._full_implications_linesí  s—   é € Ø+Ò+Ü˜4×-Ñ-Ö.ˆDÛ&�Ø.¨t¨f°C¸°w¸aÐ@Ò@Ø˜t™h b¨©	°Ð;Ò;Ø#×5Ñ5°t°mÑD�Ü% lÖ3�GØ$ W¡K¨qÐ1Ô1ñ  4à#Ò#Ø”ó 'ñ /ð )Ó(ùs   ‚A:A<c              #   óÜ   #   • Sv •  Sv •  [        U R                  5       HC  nSU 3v •  SU< S3v •  [        U R                  U   5       H  nSU< S3v •  M     Sv •  Sv •  ME     S	v •  g 7f)
Nz
prereq = {rš   z.    # facts that could determine the value of r¢   z: {r«   r£   z    },z
} # prereq)rt   rL   )r_   r¤   Úpfacts      r   Ú_prereq_linesÚFactRules._prereq_linesú  sx   é € ØÒØŠÜ˜4Ÿ;™;Ö'ˆDØBÀ4À&ÐIÒIØ˜™ Ð%Ò%Ü §¡¨DÑ 1Ö2�Ø  ¡	¨Ð+Ô+ñ 3àŠNØŒHñ (ð Óùs   ‚A*A,c           
   #   óX  #   • [        [        5      n[        U R                  5       H  u  nu  p4X   R	                  X245        M     Sv •  Sv •  Sv •  Sn0 n[        U5       Hd  nUu  pxSU SU 3v •  X    HG  u  p2XVU'   US-  nSR                  [        [        [        U5      5      5      n	S	U	 S
3v •  SU< S3v •  MI     Sv •  Mf     Sv •  Sv •  [        U R                  5       H5  n
U
u  pxU R                  U
    Vs/ s H  o&U   PM	     nnSU
< SU< S3v •  M7     Sv •  g s  snf 7f)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 = {r¢   z: r£   z} # beta_triggers)
r   Úlistr:   r>   r<   rt   r”   r   ru   r‡   )r_   Úreverse_implicationsÚnÚprer­   ÚmÚindicesr¤   r¬   ÚsetstrÚqueryÚtriggerss               r   Ú_beta_rules_linesÚFactRules._beta_rules_lines  sR  é € Ü*¬4Ó0ÐÜ!*¨4¯?©?Ö!;ÑˆA‰~�Ø Ñ)×0Ñ0°#°Ö:ñ "<ð QÒPØÒØŠØˆØˆÜÐ2Ö3ˆGØ!‰KˆDØ)¨$¨¨s°5°'Ð:Ò:Ø.Ô7‘�Ø˜‘
Ø�Q‘�ØŸ™¤3¤s¬F°3«KÓ#8Ó9�Ø ˜x sÐ+Ò+Ø  ¡¨2Ð.Ô.ñ 8ð ŒHñ 4ð Òà!Ò!Ü˜D×.Ñ.Ö/ˆEØ‰KˆDØ,0×,>Ñ,>¸uÒ,EÓFÒ,E q œ
Ñ,EˆHÐFØ˜™	  H¡<¨qÐ1Ô1ñ 0ð "Ó!ùò Gùs   ‚C=D*Ã?D%ÄD*c              #   ó,  #   • U R                  5        Sh  v•N   Sv •  Sv •  U R                  5        Sh  v•N   Sv •  Sv •  U R                  5        Sh  v•N   Sv •  Sv •  U R                  5        Sh  v•N   Sv •  Sv •  Sv •  Sv •  g Nu NW N9 N7f)z@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•   ÚFactRules.print_rules#  s•   é € à×,Ñ,Ó.×.Ð.ØŠØŠØ×0Ñ0Ó2×2Ð2ØŠØŠØ×%Ñ%Ó'×'Ð'ØŠØŠØ×)Ñ)Ó+×+Ð+ØŠØŠØpÒpØjÓjñ 	/ñ 	3ñ 	(ñ 	,ùsC   ‚B–B—B¶B·BÁBÁBÁ6BÁ7BÂBÂBÂB)r>   r‡   r†   r   rL   N)rS   rT   rU   rV   rW   r`   ru   r–   ÚclassmethodÚdictrŸ   r¥   r®   r²   r¾   r   r•   rX   rR   r   r   r€   r€   |  sZ   † ñò<9ðv-˜Cô -ð ð
 ó 
ó ð
ò"ò)ò
ò"ð:k˜X c™]÷ kr   r€   c                   ó   • \ rS rSrS rSrg)ÚInconsistentAssumptionsi5  c                 ó:   • U R                   u  pnU< SU< SU< 3$ )Nrª   Ú=)r6   )r_   Úkbr¤   r¬   s       r   Ú__str__ÚInconsistentAssumptions.__str__6  s   € ØŸ)™)‰ˆ�%Û £$ªÐ.Ð.r   rR   N)rS   rT   rU   rV   rÉ   rX   rR   r   r   rÅ   rÅ   5  s   † õ/r   rÅ   c                   ó0   • \ rS rSrSrS rS rS rS rSr	g)	ÚFactKBi;  zL
A simple propositional knowledge base relying on compiled inference rules.
c                 óŠ   • SSR                  [        U R                  5       5       Vs/ s H  nSU-  PM
     sn5      -  $ s  snf )Nz{
%s}z,
z	%s: %s)r”   rt   r#   )r_   r   s     r   rÉ   ÚFactKB.__str__?  s@   € Ø˜%Ÿ*™*Ü%+¨D¯J©J«LÔ%9Ó:Ò%9 ˆZ˜!Œ^Ñ%9Ñ:ó<ñ <ð 	<ùÚ:s   ¨A 
c                 ó   • Xl         g r.   ©rK   )r_   rK   s     r   r`   ÚFactKB.__init__C  s   € Ø�
r   c                 óJ   • X;   a  X   b  X   U:X  a  g[        XU5      eX U'   g)zhAdd fact k=v to the knowledge base.

Returns True if the KB has actually been updated, False otherwise.
FT)rÅ   )r_   r   Úvs      r   Ú_tellÚFactKB._tellF  s3   € ð
 ‹9˜™Ñ,Ø‰w˜!‹|Øä-¨d°qÓ9Ð9à�‰GØr   c                 ó<  ^ • T R                   R                  nT R                   R                  nT R                   R                  n[	        U[
        5      (       a  UR                  5       nU(       a­  [        5       nU HU  u  pgT R                  Xg5      (       a  Uc  M   X&U4    H  u  p‰T R                  X‰5        M     UR                  X6U4   5        MW     / nU H6  n
XJ   u  p¼[        U 4S jU 5       5      (       d  M%  UR                  U5        M8     U(       a  M¬  gg)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   óN   >#   • U  H  u  pTR                  U5      UL v •  M     g 7fr.   )r9   )r/   r   rÓ   r_   s      €r   r3   Ú*FactKB.deduce_all_facts.<locals>.<genexpr>y  s    øé € Ð:²E©D¨A�t—x‘x “{ aÕ'²Eùs   ƒ"%)rK   r   r‡   r>   r   rÃ   r#   r   rÔ   r›   Úallr<   )r_   Úfactsr   r‡   r>   Úbeta_maytriggerr   rÓ   rs   r¬   rH   rA   r2   s   `            r   Údeduce_all_factsÚFactKB.deduce_all_factsW  sð   ø€ ð !ŸJ™J×8Ñ8ÐØŸ
™
×0Ñ0ˆØ—Z‘Z×*Ñ*ˆ
ä�eœT×"Ñ"Ø—K‘K“MˆEæÜ!›eˆOó ‘�Ø—z‘z !×'Ñ'¨1©9Ùð #4°q°DÔ"9‘J�CØ—J‘J˜sÖ*ñ #:ð  ×&Ñ& }¸°TÑ':Ö;ñ ð ˆEÛ'�Ø)Ñ/‘�ÜÔ:±EÓ:×:Ó:Ø—L‘L Ö'ñ (÷! Šer   rÐ   N)
rS   rT   rU   rV   rW   rÉ   r`   rÔ   rÜ   rX   rR   r   r   rÌ   rÌ   ;  s   † ñò<òòõ"#(r   rÌ   N)rW   Úcollectionsr   Útypingr   Úlogicr   r   r   r	   r   r   r    r+   rI   rN   Ú	ExceptionrP   rZ   r€   r%   rÅ   rÃ   rÌ   rR   r   r   Ú<module>râ      s{   ðñ.õ` $Ý ç &Ó &òòòò(%òPLò^ôL	˜	ô 	÷
v7ñ v7÷vvkñ vkôr/˜jô /ô?(ˆTõ ?(r   