Ë
    7^(hZL  ã                   óÆ   — 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y)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/skyplay_api_hub/venv/lib/python3.12/site-packages/sympy/core/facts.pyÚ
_base_factr   7   s   € ô
 �$œÔØ�x‰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 ]1  }|D ]*  }||f|v sŒ
|D ]  }||f|v sŒ
|j                  ||f«       Œ Œ, Œ3 |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�{‰{œC¤Ð%6Ó7Ð8€Hàò 6ˆØò 	6ˆAØ�1ˆvÐ*Ò*Ø!ò 6�AØ˜1�vÐ!2Ò2Ø)×-Ñ-¨q°!¨fÕ5ñ6ñ	6ð6ð Ðr   c           	      ó~  — | | D ��cg c]  \  }}t        |«      t        |«      f‘Œ c}}z   } t        t        «      }t        | «      }|D ]  \  }}||k(  rŒ||   j	                  |«       Œ! |j                  «       D ]9  \  }}|j                  |«       t        |«      }||v sŒ't        d|›d|›d|›�«      ‚ |S c c}}w )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, ...])
    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¹¸¸A¤C¨£F¬C°«FÒ#3Ó"OÑO€LÜ
”cÓ
€CÜ*¨<Ó8ÐØ!ò ‰ˆˆ1Ø�Š6ØàˆA‰�
‰
�1�ð	ð —9‘9“;ò N‰ˆˆ4Ø�‰�QŒÜ�‹VˆØ�Š:ÝÚ@AÂ2ÁtÐLóNð Nð	Nð €Jùó# #Ps   ‡ B9c                 ó
  ‡‡— i }| j                  «       D ]  }t        | |   «      g f||<   Œ |D ]*  \  }Š|j                  D ]  }||v rŒt        «       g f||<   Œ Œ, d}|r¥d}|D ]›  \  }Št        |t        «      st        d«      ‚t        |j                  «      Š|j                  «       D ]S  \  }\  }}||hz  }	‰|	vsŒ‰j                  |	«      sŒ&|j                  ‰«       |j                  ‰«      }
|
�||
d   z  }d}ŒU Œ� |rŒ¥t        |«      D ]p  \  }\  }Št        |j                  «      Š|j                  «       D ]@  \  }\  }}||hz  }	‰|	v rŒt        ˆˆfd„|	D «       «      rŒ*‰|	z  sŒ0|j                  |«       ŒB Œr |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 Andr   c              3   óX   •K  — | ]!  }t        |«      ‰v xs t        |«      ‰k(  –— Œ# y ­w©N)r	   )Ú.0ÚxiÚbargsÚbimpls     €€r   ú	<genexpr>z,apply_beta_to_alpha_route.<locals>.<genexpr>Í   s+   øè ø€ ÒH¸B”3�r“7˜eÐ#Ò7¤s¨2£w°%Ñ'7Ó7ÑHùs   ƒ'*)Ú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_routerH   ‡   sÁ  ù€ ð8 €FØ×$Ñ$Ó&ò 5ˆÜÐ+¨AÑ.Ó/°Ð4ˆˆqŠ	ð5à"ò %‰ˆˆuØ—*‘*ò 	%ˆBØ�V‰|ØÜ›% ˜ˆF�2ŠJñ	%ð%ð !ÐÙ
Ø %Ðà&ò 	1‰LˆE�5Ü˜e¤SÔ)ÜÐ 1Ó2Ð2Ü˜Ÿ
™
“OˆEØ#)§<¡<£>ò 1‘�‘<�F˜BØ ! ™�à Ò%¨%¯.©.¸Õ*?Ø—J‘J˜uÔ%ð "(§¡¨EÓ!2�JØ!Ð-Ø *¨Q¡-Ñ/˜Ø,0Ñ)ñ1ð		1ò  ô* !*¨*Ó 5ò  Ñˆ‰nˆu�eÜ�E—J‘J“ˆØ%Ÿ|™|›~ò 	 ‰OˆA‰|�˜Ø˜a˜S‘LˆEà˜‰~Øô ÔHÀ%ÔHÔHØà�u‹}Ø—	‘	˜$•ñ	 ð ð €Mr   c                 ó  — t        t        «      }| j                  «       D ]d  \  \  }}}t        |t        «      r|j
                  d   }|D ]8  \  }}t        |t        «      r|j
                  d   }||   j                  |«       Œ: Œf |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	   r5   r   )ÚrulesÚprereqr'   Ú_r)   r   s         r   Úrules_2prereqrM   Ö   sƒ   € ô. œÓ€FØŸ™›ò ‰‰ˆˆA�Ü�aœÔØ—‘�q‘	ˆAØò 	‰FˆQ�Ü˜!œSÔ!Ø—F‘F˜1‘I�Ø�1‰I�M‰M˜!Õñ	ðð €Mr   c                   ó   — e Zd ZdZy)ÚTautologyDetectedz:(internal) Prover uses it for reporting detected tautologyN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   rO   rO   ü   s   „ ÙDØr   rO   c                   óH   — e Zd ZdZd„ Zd„ Zed„ «       Zed„ «       Zd„ Z	d„ Z
y)	Ú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                 ó0   — g | _         t        «       | _        y r.   )Úproved_rulesr   Ú_rules_seen©Úselfs    r   Ú__init__zProver.__init__  s   € ØˆÔÜ›5ˆÕr   c                 ó¨   — g }g }| j                   D ]<  \  }}t        |t        «      r|j                  ||f«       Œ*|j                  ||f«       Œ> ||fS )z-split proved rules into alpha and beta chains)rX   r   r   r;   )r[   Úrules_alphaÚ
rules_betar'   r(   s        r   Úsplit_alpha_betazProver.split_alpha_beta"  s`   € àˆØˆ
Ø×%Ñ%ò 	+‰DˆAˆqÜ˜!œSÔ!Ø×!Ñ! 1 a &Õ)à×"Ñ" A q 6Õ*ð		+ð
 ˜JÐ&Ð&r   c                 ó(   — | j                  «       d   S )Nr   ©r`   rZ   s    r   r^   zProver.rules_alpha-  ó   € à×$Ñ$Ó& qÑ)Ð)r   c                 ó(   — | j                  «       d   S )Nr   rb   rZ   s    r   r_   zProver.rules_beta1  rc   r   c                 óì   — |rt        |t        «      ryt        |t        «      ry||f| j                  v ry| j                  j                  ||f«       	 | j	                  ||«       y# t
        $ r Y yw xY w)zprocess a -> b ruleN)r   ÚboolrY   r   Ú_process_rulerO   )r[   r'   r(   s      r   Úprocess_rulezProver.process_rule5  sr   € á”j ¤DÔ)ØÜ�aœÔØØˆqˆ6�T×%Ñ%Ñ%Øà×Ñ× Ñ  ! Q Ô(ð	Ø×Ñ˜q !Õ$øÜ ò 	Ùð	ús   ÁA' Á'	A3Á2A3c           
      ó\  — t        |t        «      r5t        |j                  t        ¬«      }|D ]  }| j                  ||«       Œ y t        |t        «      rÖt        |j                  t        ¬«      }t        |t        «      s||v rt        ||d«      ‚| j                  t        |j                  D �cg c]  }t        |«      ‘Œ c}Ž t        |«      «       t        t        |«      «      D ]@  }||   }|d | ||dz   d  z   }| j                  t        |t        |«      «      t        |Ž «       ŒB y t        |t        «      rJt        |j                  t        ¬«      }||v rt        ||d«      ‚| j                  j                  ||f«       y t        |t        «      rFt        |j                  t        ¬«      }||v rt        ||d«      ‚|D ]  }| j                  ||«       Œ y | j                  j                  ||f«       | j                  j                  t        |«      t        |«      f«       y c c}w )N)Úkeyza -> a|c|...r   z
a & b -> az
a | b -> a)r   r   Úsortedr5   Ústrrh   r   r   rO   r	   ÚrangeÚlenrX   r;   )	r[   r'   r(   Úsorted_bargsÚbargrG   ÚbrestÚsorted_aargsÚaargs	            r   rg   zProver._process_ruleF  sä  € ô �aœÔÜ! !§&¡&¬cÔ2ˆLØ$ò +�Ø×!Ñ! ! TÕ*ñ+ô ˜œ2ÔÜ! !§&¡&¬cÔ2ˆLä˜a¤Ô'à˜Ñ$Ü+¨A¨q°.ÓAÐAØ×Ñœc¸!¿&¹&Ö#A°$¤C¨¥IÒ#AÐBÄCÈÃFÔKäœc ,Ó/Ó0ò A�Ø# DÑ)�Ø$ U dÐ+¨l¸4À!¹8¸9Ð.EÑE�Ø×!Ñ!¤# a¬¨T«Ó"3´R¸°ZÕ@ñAô ˜œ3ÔÜ! !§&¡&¬cÔ2ˆLØ�LÑ Ü'¨¨1¨lÓ;Ð;Ø×Ñ×$Ñ$ a¨ VÕ,ô ˜œ2ÔÜ! !§&¡&¬cÔ2ˆLØ�LÑ Ü'¨¨1¨lÓ;Ð;Ø$ò +�Ø×!Ñ! $¨Õ*ñ+ð
 ×Ñ×$Ñ$ a¨ VÔ,Ø×Ñ×$Ñ$¤c¨!£f¬c°!«fÐ%5Õ6ùò9 $Bs   Â0H)N)rP   rQ   rR   rS   r\   r`   Úpropertyr^   r_   rh   rg   rT   r   r   rV   rV     sC   „ ñò8!ò	'ð ñ*ó ð*ð ñ*ó ð*òó"17r   rV   c                   ób   — 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y)Ú	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|j                  «       }t        «       }|D ]‘  }|j	                  dd«      \  }}}t        j                  |«      }t        j                  |«      }|dk(  r|j                  ||«       Œ[|dk(  r%|j                  ||«       |j                  ||«       Œ…t        d|z  «      ‚ g | _	        |j                  D ]L  \  }}| j                  j                  |j                  D �ch c]  }t        |«      ’Œ c}t        |«      f«       ŒN t        |j                  «      }	t!        |	|j                  «      }
|
j#                  «       D �ch c]  }t%        |«      ’Œ c}| _        t)        t*        «      }t)        t*        «      }|
j-                  «       D ];  \  }\  }}|D �ch c]  }t        |«      ’Œ c}|t        |«      <   ||t        |«      <   Œ= || _        || _        t)        t*        «      }t3        |«      }|j-                  «       D ]  \  }}||xx   |z  cc<   Œ || _        yc c}w c c}w c c}w )z)Compile rules into internal lookup tablesNé   z->z==zunknown op %r)r   rl   Ú
splitlinesrV   Úsplitr   Ú
fromstringrh   r%   r=   r_   r;   r5   r   r+   r^   rH   r4   r   Údefined_factsr   r   r#   r   Úbeta_triggersrM   rK   )r[   rJ   ÚPÚruler'   Úopr(   r@   r2   Úimpl_aÚimpl_abr   r   r}   r)   Úbetaidxsr   rK   Ú
rel_prereqÚpitemss                       r   r\   zFactRules.__init__›  s  € ô �eœSÔ!Ø×$Ñ$Ó&ˆEô ‹Hˆàò 	7ˆDà—z‘z $¨Ó*‰HˆAˆr�1ä× Ñ  Ó#ˆAÜ× Ñ  Ó#ˆAà�TŠzØ—‘˜q !Õ$Ø�t’Ø—‘˜q !Ô$Ø—‘˜q !Õ$ä  °2Ñ!5Ó6Ð6ð	7ð  ˆŒØŸL™Lò 	F‰LˆE�5Ø�O‰O×"Ñ"Ø',§z¡zÖ2 !”(˜1•+Ò2´H¸U³OÐDõFð	Fô
 +¨1¯=©=Ó9ˆô ,¨F°A·L±LÓAˆð 6=·\±\³^ÖD°œj¨�mÒDˆÔô (¬Ó,ÐÜ#¤CÓ(ˆØ#*§=¡=£?ò 	2ÑˆAÑ��hØCGÖ-H¸a¬h°q­kÒ-HÐœh q›kÑ*Ø)1ˆMœ( 1›+Ò&ð	2ð "3ˆÔØ*ˆÔô œSÓ!ˆÜ"Ð#4Ó5ˆ
Ø#×)Ñ)Ó+ò 	 ‰IˆAˆvØ�1‹I˜ÑŒIð	 àˆ�ùò; 3ùò Eùò .Is   Ã=H;
Å I Æ5IÚreturnc                 ó@   — dj                  | j                  «       «      S )zD Generate a string with plain python representation of the instance ú
)ÚjoinÚprint_rulesrZ   s    r   Ú
_to_pythonzFactRules._to_pythonÖ  s   € à�y‰y˜×)Ñ)Ó+Ó,Ð,r   Údatac                 ó¾   —  | d«      }dD ]2  }t        t        «      }|j                  ||   «       t        |||«       Œ4 |d   |_        t        |d   «      |_        |S )z; Generate an instance from the plain python representation Ú )r   r}   rK   r=   r|   )r   r   ÚupdateÚsetattrr=   r|   )ÚclsrŒ   r[   rj   Úds        r   Ú_from_pythonzFactRules._from_pythonÚ  sg   € ñ �2‹wˆØCò 	"ˆCÜœ#ÓˆAØ�H‰H�T˜#‘YÔÜ�D˜#˜qÕ!ð	"ð ˜|Ñ,ˆŒÜ   oÑ!6Ó7ˆÔàˆr   c              #   ó`   K  — d–— t        | j                  «      D ]
  }d|›d�–— Œ d–— y ­w)Nzdefined_facts = [ú    ú,z] # defined_facts)rk   r|   )r[   Úfacts     r   Ú_defined_facts_lineszFactRules._defined_facts_linesç  s;   è ø€ Ø!Ò!Ü˜4×-Ñ-Ó.ò 	#ˆDØ˜˜ Ð"Ó"ð	#à!Ó!ùs   ‚,.c              #   óì   K  — d–— t        | j                  «      D ]P  }dD ]I  }d|› d|› d�–— d|›d|›d�–— | j                  ||f   }t        |«      D ]
  }d	|›d
�–— Œ d–— d–— ŒK ŒR d–— y ­w)Nzfull_implications = dict( [)TFz    # Implications of ú = ú:z    ((ú, z	), set( (ú        r–   z       ) ),z     ),z ] ) # full_implications)rk   r|   r   )r[   r—   Úvaluer   Úimplieds        r   Ú_full_implications_linesz"FactRules._full_implications_linesí  s©   è ø€ Ø+Ò+Ü˜4×-Ñ-Ó.ò 	 ˆDØ&ò  �Ø.¨t¨f°C¸°w¸aÐ@Ò@Ø˜t˜h b¨¨	°Ð;Ò;Ø#×5Ñ5°t¸U°mÑD�Ü% lÓ3ò 2�GØ$ W K¨qÐ1Ó1ð2à#Ò#Ø“ñ ð	 ð )Ó(ùs   ‚A2A4c              #   óÐ   K  — d–— d–— t        | j                  «      D ]>  }d|› �–— d|›d�–— t        | j                  |   «      D ]
  }d|›d�–— Œ d–— d–— Œ@ d	–— y ­w)
Nz
prereq = {rŽ   z.    # facts that could determine the value of r•   z: {r�   r–   z    },z
} # prereq)rk   rK   )r[   r—   Úpfacts      r   Ú_prereq_lineszFactRules._prereq_linesú  sƒ   è ø€ ØÒØŠÜ˜4Ÿ;™;Ó'ò 	ˆDØBÀ4À&ÐIÒIØ˜˜ Ð%Ò%Ü §¡¨DÑ 1Ó2ò ,�Ø   	¨Ð+Ó+ð,àŠNØ‹Hð	ð Óùs   ‚A$A&c           
   #   óN  K  — t        t        «      }t        | j                  «      D ]  \  }\  }}||   j	                  ||f«       Œ  d–— d–— d–— d}i }t        |«      D ]d  }|\  }}d|› d|› �–— ||   D ]G  \  }}|||<   |dz  }dj                  t        t        t        |«      «      «      }	d	|	› d
�–— d|›d�–— ŒI d–— Œf d–— d–— t        | j                  «      D ]1  }
|
\  }}| j                  |
   D �cg c]  }||   ‘Œ	 }}d|
›d|›d�–— Œ3 d–— y c c}w ­w)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   Úlistr9   r=   r;   rk   r‰   r   rl   r}   )r[   Úreverse_implicationsÚnÚprerŸ   ÚmÚindicesr—   rž   ÚsetstrÚqueryÚtriggerss               r   Ú_beta_rules_lineszFactRules._beta_rules_lines  sv  è ø€ Ü*¬4Ó0ÐÜ!*¨4¯?©?Ó!;ò 	;ÑˆA‰~��WØ  Ñ)×0Ñ0°#°q°Õ:ð	;ð QÒPØÒØŠØˆØˆÜÐ2Ó3ò 		ˆGØ!‰KˆD�%Ø)¨$¨¨s°5°'Ð:Ò:Ø.¨wÑ7ò /‘��QØ�˜‘
Ø�Q‘�ØŸ™¤3¤s¬F°3«KÓ#8Ó9�Ø ˜x sÐ+Ò+Ø   ¨2Ð.Ó.ð/ð ‹Hð		ð Òà!Ò!Ü˜D×.Ñ.Ó/ò 	2ˆEØ‰KˆD�%Ø,0×,>Ñ,>¸uÑ,EÖF q˜ ›
ÐFˆHÐFØ˜˜	  H <¨qÐ1Ó1ð	2ð "Ó!ùò Gùs   ‚C>D%Ä D ÄD%c              #   ó,  K  — | j                  «       E d{  –—†  d–— d–— | j                  «       E d{  –—†  d–— d–— | j                  «       E d{  –—†  d–— d–— | j                  «       E d{  –—†  d–— d–— d–— d–— y7 Œu7 ŒW7 Œ97 Œ­w)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®   rZ   s    r   rŠ   z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N)rP   rQ   rR   rS   r\   rl   r‹   ÚclassmethodÚdictr“   r˜   r    r£   r®   r   rŠ   rT   r   r   rv   rv   |  sZ   „ ñò<9ðv-˜Có -ð ð
 ò 
ó ð
ò"ò)ò
ò"ð:k˜X c™]ô kr   rv   c                   ó   — e Zd Zd„ Zy)ÚInconsistentAssumptionsc                 ó6   — | j                   \  }}}|›d|›d|›�S )Nrœ   ú=)r5   )r[   Úkbr—   rž   s       r   Ú__str__zInconsistentAssumptions.__str__6  s   € ØŸ)™)‰ˆˆD�%Ú ¢$©Ð.Ð.r   N)rP   rQ   rR   r·   rT   r   r   r³   r³   5  s   „ ó/r   r³   c                   ó(   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zy)ÚFactKBzT
    A simple propositional knowledge base relying on compiled inference rules.
    c                 ó„   — ddj                  t        | j                  «       «      D �cg c]  }d|z  ‘Œ	 c}«      z  S c c}w )Nz{
%s}z,
z	%s: %s)r‰   rk   r#   )r[   r   s     r   r·   zFactKB.__str__?  s:   € Ø˜%Ÿ*™*Ü%+¨D¯J©J«LÓ%9Ö: ˆZ˜!‹^Ò:ó<ñ <ð 	<ùÚ:s   ¨=
c                 ó   — || _         y r.   )rJ   )r[   rJ   s     r   r\   zFactKB.__init__C  s	   € Øˆ�
r   c                 óL   — || v r| |   �| |   |k(  ryt        | ||«      ‚|| |<   y)zxAdd fact k=v to the knowledge base.

        Returns True if the KB has actually been updated, False otherwise.
        FT)r³   )r[   r   Úvs      r   Ú_tellzFactKB._tellF  s=   € ð
 �‰9˜˜a™Ð,Ø�A‰w˜!Š|Øä-¨d°A°qÓ9Ð9àˆD�‰GØr   c                 ó  ‡ — ‰ j                   j                  }‰ j                   j                  }‰ j                   j                  }t	        |t
        «      r|j                  «       }|r›t        «       }|D ]Q  \  }}‰ j                  ||«      r|€Œ|||f   D ]  \  }}	‰ j                  ||	«       Œ |j                  |||f   «       ŒS g }|D ]0  }
||
   \  }}t        ˆ fd„|D «       «      sŒ |j                  |«       Œ2 |rŒšyy)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   óJ   •K  — | ]  \  }}‰j                  |«      |u –— Œ y ­wr.   )r8   )r/   r   r½   r[   s      €r   r3   z*FactKB.deduce_all_facts.<locals>.<genexpr>y  s"   øè ø€ Ò:©D¨A¨q�t—x‘x “{ aÔ'Ñ:ùs   ƒ #)rJ   r   r}   r=   r   r±   r#   r   r¾   r�   Úallr;   )r[   Úfactsr   r}   r=   Úbeta_maytriggerr   r½   rj   rž   rG   r@   r2   s   `            r   Údeduce_all_factszFactKB.deduce_all_factsW  s  ø€ ð !ŸJ™J×8Ñ8ÐØŸ
™
×0Ñ0ˆØ—Z‘Z×*Ñ*ˆ
ä�eœTÔ"Ø—K‘K“Mˆ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)rP   rQ   rR   rS   r·   r\   r¾   rÄ   rT   r   r   r¹   r¹   ;  s   „ ñò<òòó"#(r   r¹   N)rS   Úcollectionsr   Útypingr   Úlogicr   r   r   r	   r   r   r    r+   rH   rM   Ú	ExceptionrO   rV   rv   r%   r³   r±   r¹   rT   r   r   ú<module>rÉ      s{   ðñ.õ` $Ý ç &Ó &òòòò(%òPLò^ôL	˜	ô 	÷
v7ñ v7÷vvkñ vkôr/˜jô /ô?(ˆTõ ?(r   