
    3j3                    z    d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	m
Z
mZmZ e G d d             Z G d d	      Zy
)u  anu_v3.batch_dependency_matrix — track dependency + overlap checkers.

Authority: task-2553+17.md §4(3,4,5) + §12 9-R.1.

Provides:
  * dependency matrix (declared blocking edges between tracks)
  * expected_files overlap checker
  * forbidden_write_targets overlap checker
  * independence query (does track X completion block track Y?)

Pure stdlib; never mutates existing tracked files.
    )annotations)	dataclassfield)combinations)DictListSequenceTuplec                      e Zd ZU ded<    ee      Zded<    ee      Zded<    ee      Zded<    ee      Z	ded<   y	)
	TrackSpecstrtrack_id)default_factoryz	List[str]expected_filesforbidden_write_targets
depends_onown_artifactsN)
__name__
__module____qualname____annotations__r   listr   r   r   r        @/home/jay/workspace/scripts/../anu_v3/batch_dependency_matrix.pyr   r      sD    M %d ;NI;).t)DYD!$7J	7$T:M9:r   r   c                  \    e Zd ZddZddZddZddZddZddZddZ	ddZ
dd	Zdd
Zy)BatchDependencyMatrixc                    i | _         |D ]K  }|j                  | j                   v rt        d|j                        || j                   |j                  <   M | j                          y )Nzduplicate track )_tracksr   
ValueError_validate_edges)selftracksts      r   __init__zBatchDependencyMatrix.__init__   s_    -/ 	)AzzT\\) #3AJJ>!BCC'(DLL$	) 	r   c                   | j                   j                         D ]d  }|j                  D ]S  }|| j                   vrt        d|j                  d|      ||j                  k(  s<t        d|j                  d       f y )Nztrack z depends on unknown z self-dependency)r   valuesr   r    r   )r"   r$   deps      r   r!   z%BatchDependencyMatrix._validate_edges'   s    $$& 	NA|| Ndll*$ .B3'J  !**$$vajj^;K%LMMN	Nr   c                    t        | j                        }|D ci c]-  }||D ci c]  }||| j                  |   j                  v   c}/ c}}S c c}w c c}}w )z9matrix[a][b] == True  =>  a depends on (is blocked by) b.)r   r   r   )r"   idsabs       r   matrixzBatchDependencyMatrix.matrix2   s]    4<<  
 cBAa3333BB
 	
B
s   
A#AAAc                r    || j                   |   j                  vxr || j                   |   j                  vS )z7True if neither track blocks the other (parallel-safe).r   r   )r"   r+   r,   s      r   is_independentz$BatchDependencyMatrix.is_independent:   s:     T\\!_/// 4a333	
r   c                8    || j                   |   j                  v S )z:Does *candidate_track* have to wait for *completed_track*?r/   )r"   completed_trackcandidate_tracks      r   blockszBatchDependencyMatrix.blocksA   s    $,,"?"J"JJJr   c                d   t        | j                        }t               g }|r|j                         D cg c]%  \  }}t	        fd|j
                  D              r|' }}}|st        d      |j                  t        |             |D ]  }j                  |       ||=  |r|S c c}}w )z=Topological layers; tracks in the same layer run in parallel.c              3  &   K   | ]  }|v  
 y wNr   ).0ddones     r   	<genexpr>z>BatchDependencyMatrix.parallelizable_groups.<locals>.<genexpr>N   s     7QqDy7s   zdependency cycle detected)
dictr   setitemsallr   r    appendsortedadd)r"   	remaininglayerstidr$   layerr:   s         @r   parallelizable_groupsz+BatchDependencyMatrix.parallelizable_groupsE   s    &	"$ (oo/C7!,,77 E 
  !<==MM&-( #cN#  s   *B,c                   g }t        | j                  d      D ]j  \  }}t        t        | j                  |   j                        t        | j                  |   j                        z        }|sW|j                  |||f       l |S )N   )r   r   rA   r=   r   r@   )r"   outr+   r,   shareds        r   expected_files_overlapz,BatchDependencyMatrix.expected_files_overlapY   s~    02 q1 	+DAqDLLO223dll1o4456F 

Aq&>*	+ 
r   c                   g }| j                   D ]  }| j                   |   }t        |j                        t        |j                        z  }| j                   D ]}  }||k(  r	| j                   |   }t        |j                        t        |j                        z  }t        ||z  t        |j                        z
        }|sj|j                  |||f         |S )a  Real cross-track write violation = a track writing a file that
        another track *owns* and/or has declared no-write, where the file is
        NOT the writer's own artifact.

        Returns (writer, owner, files). A track legitimately writing its own
        artifact that merely appears in a sibling's forbidden list is NOT a
        violation (that is the sibling declaring "I won't touch this").)r   r=   r   r   r   rA   r@   )	r"   rJ   r+   writerwriter_writesr,   owner	protectedrK   s	            r   forbidden_write_overlapz-BatchDependencyMatrix.forbidden_write_overlapd   s     13 	/A\\!_F 5 56$$: M \\ /6Q 3 34s118 	
  "Y.&../0 JJ1f~./	/( 
r   c                X    t        | j                         xs | j                               S r7   )boolrL   rR   )r"   s    r   has_boundary_conflictz+BatchDependencyMatrix.has_boundary_conflict   s)    '')KT-I-I-K
 	
r   c                ,   t        | j                        | j                         | j                         | j	                         D cg c]  \  }}}|||d c}}}| j                         D cg c]  \  }}}|||d c}}}dS c c}}}w c c}}}w )N)r+   r,   rK   )rN   rP   rK   )r#   r-   rG   rL   rR   )r   r   r-   rG   rL   rR   )r"   r+   r,   ss       r   to_dictzBatchDependencyMatrix.to_dict   s    4<<(kkm%)%?%?%A "&!<!<!>' 'Q1 a1-' "&!=!=!?( (Q1 qA6(
 	
'(s   B0BN)r#   zSequence[TrackSpec]returnNone)rY   rZ   )rY   zDict[str, Dict[str, bool]])r+   r   r,   r   rY   rT   )r2   r   r3   r   rY   rT   )rY   zList[List[str]])rY   z List[Tuple[str, str, List[str]]])rY   rT   )rY   zDict[str, object])r   r   r   r%   r!   r-   r0   r4   rG   rL   rR   rU   rX   r   r   r   r   r      s6    N

K(	>


r   r   N)__doc__
__future__r   dataclassesr   r   	itertoolsr   typingr   r   r	   r
   r   r   r   r   r   <module>r`      s@    # ( " . . ; ; ;w
 w
r   