
    'j)              	       b   d dl Z d dl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 	 d dlZn# e$ r d dlZY nw xY w ed          Zeeef         Z G d d          Z G d d          Zd	e
e         d
e
e         dee         fdZd	eeedf                  d
eeedf                  deeedf                  fdZdeeef         deeef         fdZdeeef         dedeeedf                  fdZdddeeeeedf         ee         f         f         deee
e         f         fdZdedefdZdS )    N)Path)	AnyDictIterableListOptionalSequenceTupleTypeVarUnionTc            	       f   e Zd ZdZdeeef         fdZdeeef         deeef         fdZ	de
e         deeef         defd	Zdeeef         defd
Zdeeef         dee         de
e         dee         fdZedefd            Zede
e         fd            Zede
e         fd            ZdS )BayesianNodezs
    Implementation of a single node in a bayesian network allowing sampling from its conditional distribution
    node_definitionc                     || _         d S Nr   )selfr   s     a/home/ice/.hermes/hermes-agent/venv/lib/python3.11/site-packages/browserforge/bayesian_network.py__init__zBayesianNode.__init__   s    .    parent_valuesreturnc                     | j         d         }| j        D ]T}|                    |          }||                    di           v r|d         |         }>|                    di           }U|S )zj
        Extracts unconditional probabilities of node values given the values of the parent nodes
        conditionalProbabilitiesdeeperskip)r   parent_namesget)r   r   probabilitiesparent_nameparent_values        r   $get_probabilities_given_known_valuesz1BayesianNode.get_probabilities_given_known_values   s     ,-GH, 	> 	>K(,,[99L}002>>>> -h 7 E - 1 1&" = =r   possible_valuesr    c                 p    t          j                     }d}|D ]}|||         z  }||k    r|c S |d         S )zV
        Randomly samples from the given values using the given probabilities
        g        r   )random)r   r$   r    anchorcumulative_probabilitypossible_values         r   &sample_random_value_from_possibilitiesz3BayesianNode.sample_random_value_from_possibilities&   s]     !$- 	& 	&N"mN&CC"%..%%%% / q!!r   c                     |                      |          }|                     t          |                                          |          S )zi
        Randomly samples from the conditional distribution of this node given values of parents
        )r#   r*   listkeys)r   r   r    s      r   samplezBayesianNode.sample7   sH     AA-PP::##%%&&
 
 	
r   value_possibilitiesbanned_valuesc                     |                      |          fd|D             }|r|                     |          S dS )z
        Randomly samples from the conditional distribution of this node given restrictions on the possible values and the values of the parents.
        c                 $    g | ]}|v|v 
|S  r3   ).0valuer0   r    s     r   
<listcomp>zABayesianNode.sample_according_to_restrictions.<locals>.<listcomp>J   s8     
 
 
M))e}.D.D .D.D.Dr   N)r#   r*   )r   r   r/   r0   valid_valuesr    s      ` @r    sample_according_to_restrictionsz-BayesianNode.sample_according_to_restrictions@   sk     AA-PP
 
 
 
 
,
 
 

  	>>|][[[4r   c                     | j         d         S )Nnamer   r   s    r   r:   zBayesianNode.nameT   s    #F++r   c                 8    | j                             dg           S )NparentNamesr   r   r;   s    r   r   zBayesianNode.parent_namesX   s    #''r:::r   c                 8    | j                             dg           S )NpossibleValuesr>   r;   s    r   r$   zBayesianNode.possible_values\   s    #''(8"===r   N)__name__
__module____qualname____doc__r   strr   r   floatr#   r   r*   r.   r   r   r8   propertyr:   r   r$   r3   r   r   r   r      s        /S#X / / / /!#s(^	c5j	   "#Cy"9=c5j9I"	" " " ""
DcN 
s 
 
 
 
CH~ &c] Cy	
 
#   ( ,c , , , X, ;d3i ; ; ; X; >c > > > X> > >r   r   c                      e Zd ZdZdeddfdZddeeee	f                  deee	f         fdZ
deeee         f         deeee	f                  fd	Zd
eee	f         deeee         f         dedeeee	f                  fdZdS )BayesianNetworkza
    Implementation of a bayesian network capable of randomly sampling from its distribution
    pathr   Nc                 ~    t          |          }d |d         D             | _        d | j        D             | _        d S )Nc                 ,    g | ]}t          |          S r3   )r   )r4   node_defs     r   r6   z,BayesianNetwork.__init__.<locals>.<listcomp>h   s-     (
 (
 (
'/L""(
 (
 (
r   nodesc                     i | ]
}|j         |S r3   )r:   )r4   nodes     r   
<dictcomp>z,BayesianNetwork.__init__.<locals>.<dictcomp>k   s    WWW$diWWWr   )extract_jsonnodes_in_sampling_ordernodes_by_name)r   rJ   network_definitions      r   r   zBayesianNetwork.__init__f   sX    )$//(
 (
3Eg3N(
 (
 (
$ XW$:VWWWr   input_valuesc                     |i }|                                 }| j        D ](}|j        |vr|                    |          ||j        <   )|S )z]
        Randomly samples from the distribution represented by the bayesian network.
        )copyrS   r:   r.   )r   rV   r.   rP   s       r   generate_samplezBayesianNetwork.generate_samplem   s]     L""$$0 	8 	8Dy&&$(KK$7$7ty!r   r/   c                 0    |                      i |d          S )a  
        Randomly samples values from the distribution represented by the bayesian network,
        making sure the sample is consistent with the provided restrictions on value possibilities.
        Returns None if no such sample can be generated.
        r   )4recursively_generate_consistent_sample_when_possible)r   r/   s     r   (generate_consistent_sample_when_possiblez8BayesianNetwork.generate_consistent_sample_when_possibley   s     HHM`bcdddr   sample_so_fardepthc                 Z   |t          | j                  k    r|S | j        |         }g }d}	 |                    ||                    |j        |j                  |          }|nF|||j        <   |                     |||dz             }||S |                    |           ||j        = ~dS )zr
        Recursively generates a random sample consistent with the given restrictions on possible values.
        NT   )lenrS   r8   r   r:   r$   r[   append)r   r]   r/   r^   rP   r0   sample_valuenext_samples           r   r[   zDBayesianNetwork.recursively_generate_consistent_sample_when_possible   s     C45555  +E2#%	)@@#''	43GHH L
 #'3M$)$SS2EAI K &""  ...di(	)  tr   r   )rA   rB   rC   rD   r   r   r   r   rE   r   rY   r   r\   intr[   r3   r   r   rI   rI   a   s)        XT Xd X X X X
 
HT#s(^,D 
PTUXZ]U]P^ 
 
 
 
e#'Xc](:#;e	$sCx.	!e e e eCH~ "#x}"45 	
 
$sCx.	!     r   rI   abr   c                 >    t          |          fd| D             S )zB
    Performs a set "intersection" on the given (flat) arrays
    c                     g | ]}|v |	S r3   r3   )r4   xset_bs     r   r6   z&array_intersection.<locals>.<listcomp>   s    '''!AJJAJJJr   )set)rf   rg   rk   s     @r   array_intersectionrm      s*     FFE''''q''''r   .c                 6    d t          | |          D             S )z
    Combines two arrays into a single array using the set union
    Args:
        a: First array to be combined.
        b: Second array to be combined.
    Returns:
        Zipped (multi-dimensional) array.
    c                 r    g | ]4\  }}t          t          |                              |                    5S r3   )tuplerl   union)r4   rj   ys      r   r6   zarray_zip.<locals>.<listcomp>   s4    999tq!E#a&&,,q//""999r   )zip)rf   rg   s     r   	array_ziprt      s      :9s1ayy9999r   objc                     t          | t                    s| S i }|                                 D ]G\  }}|dk    r|dk    r#|                    t	          |                     5t	          |          ||<   H|S )zU
    Removes the "deeper/skip" structures from the conditional probability table
    r   r   )
isinstancedictitemsupdateundeeper)ru   resultkeyr5   s       r   r{   r{      s     c4   
Fiikk * *
U&==(??MM(5//****"5//F3KKMr   tree
valid_keysc                     g dt           t          t          f         dt          t          t          df         t
          t                   f         dt
          t                   ddffd | |g            S )a#  
    Performs DFS on the Tree and returns values of the nodes on the paths that end with the given keys
    (stored by levels - first level is the root)
    ```
       1
      / \
     2   3
    / \ / \
    4 5 6 7
    ```
    filter_by_last_level_keys(tree, ['4', '7']) => [[1], [2,3]]
    tvk.accr   Nc                 &   |                                  D ]z}t          | |         t                    r| |         >||v r9t                    dk    rd |D             nt	          d |D                       c | |         |||gz              {d S )Nr   c                     g | ]}|fS r3   r3   r4   rj   s     r   r6   z>filter_by_last_level_keys.<locals>.recurse.<locals>.<listcomp>   s    +++!!+++r   c                     g | ]}|fS r3   r3   r   s     r   r6   z>filter_by_last_level_keys.<locals>.recurse.<locals>.<listcomp>   s    ,?,?,?aaT,?,?,?r   )r-   rw   rx   ra   rt   )r   r   r   r}   outrecurses       r   r   z*filter_by_last_level_keys.<locals>.recurse   s    6688 	1 	1Cafd++ 
1qv~"99 s88q== ,+s++++&s,?,?3,?,?,?@@ 
 #C3%K0000	1 	1r   )r   rE   r   r   r
   r   )r~   r   r   r   s     @@r   filter_by_last_level_keysr      s     "$C14S> 1uU38_d3i-G'H 1tTWy 1]a 1 1 1 1 1 1 1 GD*b!!!Jr   networkr$   c           
      `   g }|                                 D ]\  }}t          |t          t          f          s"t	          |          dk    rt          d          | j        |         }t          |j        d                   }t          ||          }|
                    i t          t          |j        |                    ||i           i }|D ][}	|	                                D ]D}||v r3t          |	|         ||                   }
|
st          d          |
||<   9|	|         ||<   E\|S )z
    Given a `generative-bayesian-network` instance and a set of user constraints, returns an extended
    set of constraints **induced** by the original constraints and network structure
    r   zgThe current constraints are too restrictive. No possible values can be found for the given constraints.r   )ry   rw   r,   rp   ra   
ValueErrorrT   r{   r   r   rb   rx   rs   r   r-   rm   )r   r$   setsr}   r5   rP   r~   zipped_valuesr|   set_dictintersected_valuess              r   get_possible_valuesr      sk    D%++-- 
Q 
Q
U%$// 	u::??y   $S),-GHII1$>>OtC 1=AABBOCOOPPPP (*F 
, 
,==?? 		, 		,Cf}}%7vc{%S%S") $ B   1s&sms		, Mr   rJ   c                 j   | j         dk    rNt          | d          5 }t          j        |                                          cddd           S # 1 swxY w Y   t          j        | d          5 }	 t          d |                                D                       }n# t          $ r i cY cddd           S w xY w|                    |          5 }t          j        |                                          cddd           cddd           S # 1 swxY w Y   	 ddd           dS # 1 swxY w Y   dS )z
    Unzips a zip file if the path points to a zip file, otherwise directly loads a JSON file.

    Parameters:
        path: The path to the zip file or JSON file.

    Returns:
        A dictionary representing the JSON content.
    z.ziprbNrc              3   D   K   | ]}|                     d           |V  dS )z.jsonN)endswith)r4   files     r   	<genexpr>zextract_json.<locals>.<genexpr>#  s3      UUTdmmG>T>TUDUUUUUUr   )
suffixopenjsonloadsreadzipfileZipFilenextnamelistStopIteration)rJ   r   zffilenamefs        r   rR   rR     s    {f$ 	+:diikk**	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 
s	#	# (r	UUR[[]]UUUUUHH 	 	 	II( ( ( ( ( ( ( (	WWX 	(!:affhh''	( 	( 	( 	( 	( 	( 	(( ( ( ( ( ( ( (	( 	( 	( 	( 	( 	( 	( 	( 	(( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (sk   &AAA/D(1+BD(B8)D(7B88D(&D6D(D	D(D	D((D,/D,)r&   r   pathlibr   typingr   r   r   r   r   r	   r
   r   r   orjsonr   ImportErrorr   r,   rp   Mapr   rI   rm   rt   rE   r{   r   r   rx   rR   r3   r   r   <module>r      s           W W W W W W W W W W W W W W W W W W W W W W   KKKKK GCLLD%KO> O> O> O> O> O> O> O>d@ @ @ @ @ @ @ @F((1+ ((1+ ($q' ( ( ( (	:eAsFm$ 	:eAsFm)< 	:eAsFmAT 	: 	: 	: 	:$sCx. T#s(^    "DcN  USVX[S[_H]    B$$15c5sCxRVWZR[A[;\6\1]$	#x}
$ $ $ $N(t ( ( ( ( ( ( (s   + 	77