
     TiVE                    b   S r SSKJr  SSKrSSKrSSKJr  SSKJrJ	r	J
r
JrJr  SSKJr  \(       a  SSKJs  Jr  SSKJs  Jr   " S S5      r " S	 S
\\5      r " S S5      r " S S5      r " S S\R2                  5      r\R6                   " S S5      5       r " S S5      r " S S5      rg)z6Basic types for the pattern matching and rewriter API.    )annotationsN)defaultdict)TYPE_CHECKINGAnyMutableSequenceSequenceUnion)irc                  4    \ rS rSrSr S   SS jjrS rSrg)	MatchFailureInfo   z7Encapsulates information about a pattern match failure.c                    Xl         X l        [        S U 5       5      (       d$   SU Vs/ s H  n[        U5      PM     sn 35       eg s  snf )Nc              3  v   #    U  H/  n[        U[        R                  [        R                  45      v   M1     g 7fN)
isinstancer
   NodeValue).0items     Z/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/onnxscript/rewriter/_basics.py	<genexpr>,MatchFailureInfo.__init__.<locals>.<genexpr>   s'     T^T:dRWWbhh$788^s   79z=All items in failure_source must be ir.Node or ir.Value, got )reasonfailure_sourcesalltype)selfr   failure_sourcer   s       r   __init__MatchFailureInfo.__init__   sS    
 ?MT^TTT 	
KdrLsdr\`TRVZdrLsKtu	
TLss   A	c                @    SU R                   < SU R                  < S3$ )NzMatchFailureInfo(reason=z, failure_sources=))r   r   r   s    r   __str__MatchFailureInfo.__str__!   s$    )$++8J4K_K_Jbbcdd    )r   r   N r   strr   zir.Node | ir.Value)__name__
__module____qualname____firstlineno____doc__r   r$   __static_attributes__ r&   r   r   r      s'    A 	
	
 ,	
er&   r   c                  .    \ rS rSrSr S   SS jjrSrg)MatchFailureError%   a'  Exception raised when a pattern match fails.

This makes it easier to handle match failures in a compositional way,
for example, during the condition-checking phase of a pattern match.
It allows us to define utility functions without having to check for
and propagate match failures explicitly.
c                \    [         R                  " X/UQ76   [        R                  X5        g r   )r   r   	Exceptionr   r   r   s      r   r   MatchFailureError.__init__.   s%    
 	!!$@@4(r&   r1   Nr'   r)   )r+   r,   r-   r.   r/   r   r0   r1   r&   r   r3   r3   %   s(     )) ,) )r&   r3   c                  L   \ rS rSrSrSS jrSS jr\SS j5       rSS jr	SS jr
SS jrSS	 jr  S     SS jjr\SS j5       r\S S j5       rS!S jrS"S jrS#S jrS$S jr\S%S j5       r\S&S j5       r\S'S j5       r\S(S j5       r\S)S j5       rS*S jrS+S jrSrg
),MatchResult7   a7  The state object used by the pattern-matching algorithm.

A match can either succeed or fail.
If it succeeds, it returns a list of nodes that matched the pattern
and a set of bindings for the variables in the pattern.

Example:
::
    def pattern(x, shape1, shape2):
        t1 = op.Reshape(x, shape1)
        t2 = op.Reshape(t1, shape2)
        return t2
The above pattern matches a sequence of two Reshape ops.
The matched_nodes will contain the two Reshape ops, and the bindings will
contain the values that are bound to the variables `x`, `shape1`, and `shape2`.
c                $    [        5       /U l        g r   )PartialMatchResult_partial_matchesr#   s    r   r   MatchResult.__init__I   s    ;M;O:Pr&   c                |    U R                   (       d  gS[        U 5       SU R                  < SU R                  < S3$ )z4Returns a string representation of the match result.zMatchResult()zMatchResult(success=z	, reason=z, nodes=r"   )r>   boolr   nodesr#   s    r   __repr__MatchResult.__repr__M   s8    $$""4:,ihtzzn\]^	
r&   c                     U R                   S   $ )z!Returns the current match result.r>   r#   s    r   _current_matchMatchResult._current_matchU   s     $$R((r&   c                N    [        5       nU R                  R                  U5        g)z?Starts a new sub-match to try out one of multiple alternatives.N)r=   r>   append)r   matchs     r   enter_new_matchMatchResult.enter_new_matchZ   s    "$$$U+r&   c                ~    [        U R                  5      S:  a  [        S5      eU R                  R                  5       $ )z0Abandons the current alternative due to failure.   zNo match to abandon.)lenr>   
ValueErrorpopr#   s    r   abandon_current_match!MatchResult.abandon_current_match_   s6    t$$%)344$$((**r&   c                    [        U R                  5      S:  a  [        S5      eU R                  R                  5       nU R                  S   nU(       d  [        S5      eUR	                  U5        g)EMerges a successful sub-match for an alternative with the parent one.rP   zNo match to merge.rF   z Current match is not successful.N)rQ   r>   rR   rS   merge)r   current_matchprevious_matchs      r   merge_current_matchMatchResult.merge_current_matche   sb    t$$%)122--113..r2?@@]+r&   c                ,    [        U R                  5      $ )z0Returns True if the current match is successful.)rA   rH   r#   s    r   __bool__MatchResult.__bool__p   s    D''((r&   Nc                <    U R                   R                  X5        U $ r   )rH   failr7   s      r   ra   MatchResult.failt   s    
 	  8r&   c                .    U R                   R                  $ )z#Returns the reason for the failure.)rH   r   r#   s    r   r   MatchResult.reason|   s     "")))r&   c                .    U R                   R                  $ )z3Returns the list of nodes that matched the pattern.)rH   rB   r#   s    r   rB   MatchResult.nodes   s     ""(((r&   c                V    U R                  U5        X R                  R                  U'   g)z'Binds a pattern node to a matched node.N)add_noderH   node_bindings)r   pattern_nodenodes      r   	bind_nodeMatchResult.bind_node   s"    d:>)),7r&   c                :    U R                   R                  U5        gz)Adds a node to the list of matched nodes.N)rH   rh   r   rk   s     r   rh   MatchResult.add_node   s    $$T*r&   c                D   UR                   nUc  U R                   HX  nXR                  ;   d  M  UR                  U   U:X  a    gU R                  R	                  SU S3UR                  U   U/5          g   X R                  R                  U'   gU R                  X25      $ NTzBinding failure: z bound to two different values.F)namer>   value_bindingsrH   ra   bind)r   pattern_valuevaluevar_namerL   s        r   
bind_valueMatchResult.bind_value   s     %% .. $8$88++M:eC#'',,+M?:YZ--m<eD ! / AF..}=yy))r&   c                   U R                    HX  nXR                  ;   d  M  UR                  U   U:X  a    gU R                  R                  SU S3UR                  U   U/5          g   X R                  R                  U'   grs   )r>   bindingsrH   ra   )r   varrx   rL   s       r   rv   MatchResult.bind   s    **Enn$>>#&%/##(('u,KL^^C(%0  + -2$$S)r&   c                v    [        U R                  5      S:  a  [        S5      eU R                  R                  $ )z/Returns the bindings for the pattern variables.   z5Bindings can be accessed only at the top-level match.)rQ   r>   rR   rH   r}   r#   s    r   r}   MatchResult.bindings   s5     t$$%)TUU""+++r&   c                v    [        U R                  5      S:  a  [        S5      eU R                  R                  $ )z-Returns the bindings for the value variables.r   z;Value bindings can be accessed only at the top-level match.)rQ   r>   rR   rH   ru   r#   s    r   ru   MatchResult.value_bindings   s5     t$$%)Z[[""111r&   c                v    [        U R                  5      S:  a  [        S5      eU R                  R                  $ )z,Returns the bindings for the node variables.r   z:Node bindings can be accessed only at the top-level match.)rQ   r>   rR   rH   ri   r#   s    r   ri   MatchResult.node_bindings   s5     t$$%)YZZ""000r&   c                v    [        U R                  5      S:  a  [        S5      eU R                  R                  $ )z;Returns the list of output values that matched the pattern.r   z4Outputs can be accessed only at the top-level match.)rQ   r>   rR   rH   outputsr#   s    r   r   MatchResult.outputs   s5     t$$%)STT""***r&   c                .    U R                   R                  $ )z5Returns the nodes and values that caused the failure.)rH   _failure_nodes_and_valuesr#   s    r   failure_nodes_and_values$MatchResult.failure_nodes_and_values   s     ""<<<r&   c                j    U R                    H#  nXR                  ;   d  M  UR                  U   s  $    g)z6Looks up the node that matched the given pattern node.N)r>   ri   )r   rj   rL   s      r   lookup_nodeMatchResult.lookup_node   s4    **E222**<88 + r&   c                :    [        S U R                   5       5      $ )z+Returns the number of nodes matched so far.c              3  L   #    U  H  n[        UR                  5      v   M     g 7fr   )rQ   ri   )r   rL   s     r   r   0MatchResult.num_matched_nodes.<locals>.<genexpr>   s      O9N3u**++9Ns   "$)sumr>   r#   s    r   num_matched_nodesMatchResult.num_matched_nodes   s    O9N9NOOOr&   rG   returnNoner   r*   )r   r=   )r   rA   r(   N)r   r*   r   ?Union[ir.Node, ir.Value, list[Union[ir.Node, ir.Value]]] | Noner   r:   r   zSequence[ir.Node])rj   _pattern_ir.NodePatternrk   ir.Noderk   r   r   r   )rw   z_pattern_ir.ValuePatternrx   r   r   rA   )r~   r*   rx   r   r   rA   r   zdict[str, Any]r   z(dict[_pattern_ir.ValuePattern, ir.Value]r   z&dict[_pattern_ir.NodePattern, ir.Node]r   zMutableSequence[ir.Value])r   zlist[Union[ir.Node, ir.Value]])rj   r   r   zir.Node | Noner   int)r+   r,   r-   r.   r/   r   rC   propertyrH   rM   rT   r[   r^   ra   r   rB   rl   rh   rz   rv   r}   ru   ri   r   r   r   r   r0   r1   r&   r   r:   r:   7   s   "Q
 ) ),
+	,) Z^ X 
	 * * ) )?
+*( , , 2 2 1 1 + + = =Pr&   r:   c                      \ rS rSrSrSS jrS r  S     SS jjr\SS j5       r	\SS j5       r
SS	 jr\SS
 j5       r\SS j5       r\SS j5       r\SS j5       rSS jrSrg)r=      zHThe state object used by the pattern-matching algorithm for a sub-match.c                t    SU l         / U l        0 U l        0 U l        0 U l        / U l        SU l        / U l        g )NTr(   )_success_matched_nodes	_bindings_value_bindings_node_bindings_outputs_reasonr   r#   s    r   r   PartialMatchResult.__init__   sB    "
 9; *,IKFH(*IK&r&   c                    U R                   $ r   )r   r#   s    r   r^   PartialMatchResult.__bool__   s    }}r&   Nc                    SU l         Xl        UbM  [        U[        5      (       a  U R                  R                  U5        g U R                  R                  U5        g g )NF)r   r   r   listr   extendrK   r7   s      r   ra   PartialMatchResult.fail   sP    
 %.$//..55nE..55nE	 &r&   c                    U R                   $ r   )r   r#   s    r   r   PartialMatchResult.reason  s    ||r&   c                ,    [        U R                  5      $ r   )tupler   r#   s    r   rB   PartialMatchResult.nodes  s    T(())r&   c                :    U R                   R                  U5        gro   )r   rK   rp   s     r   rh   PartialMatchResult.add_node  s    ""4(r&   c                    U R                   $ r   )r   r#   s    r   r}   PartialMatchResult.bindings  s    ~~r&   c                    U R                   $ r   )r   r#   s    r   ru   !PartialMatchResult.value_bindings  s    ###r&   c                    U R                   $ r   )r   r#   s    r   r   PartialMatchResult.outputs  s    }}r&   c                    U R                   $ r   )r   r#   s    r   ri    PartialMatchResult.node_bindings  s    """r&   c                   U R                   (       ao  UR                   (       a^  U R                  R                  UR                  5        U R                  R	                  UR
                  5        UR                  (       a   eg[        S5      e)rW   z,Merging failed matches is not yet supported.N)r   r   updater   r   rB   r   NotImplementedError)r   others     r   rX   PartialMatchResult.merge   s^    ==U^^ NN!!%//2&&u{{3 ~~%%~ &&TUUr&   )r   r   r   r   r   r   r   r   r   r   )r   r*   r   r   r   r   r   r   r   r   r   r   r   )r   r=   r   r   )r+   r,   r-   r.   r/   r   r^   ra   r   r   rB   rh   r}   ru   r   ri   rX   r0   r1   r&   r   r=   r=      s    RL&
 Z^FF XF 
	F   * *)   $ $   # #Vr&   r=   c                  (    \ rS rSrSrSrSrSrSrSr	g)	MatchStatusi/  z+The status of a pattern-matching operation.r   r   rP      r1   N)
r+   r,   r-   r.   r/   NO_MATCHCONDITION_FAILEDREPLACEMENT_FAILEDSUCCESSr0   r1   r&   r   r   r   /  s    5HGr&   r   c                  R    \ rS rSr% SrS\S'   S\S'   S\S'   S	\S
'   SS jrS rSrg)	MatchInfoi8  zHThe status of a pattern-matching operation. An extension of MatchResult.r:   match_resultr   	root_nodeir.Graph | ir.Function	containerr   statusc                    [        U R                  R                  5      [        U R                  R
                  5      S-  -   $ )zReturn a score for the match.d   )rQ   r   rB   r   r   rx   r#   s    r   scoreMatchInfo.scoreA  s2    4$$**+c$++2C2C.Ds.JJJr&   c                p   Sn[        U5        [        SU R                  R                   35        U R                  [        R                  :w  a  U R
                  R                  nU(       a<  U R                  [        R                  :X  a  [        SU 35        O[        SU 35        O[        S5        U R
                  R                  n[        S5        U(       a  U H  nUR                  5         M     [        S5        SS K
Js  Jn  UR                  U R
                  R                  5        [        U5        g )	NzP--------------------------------------------------------------------------------zStatus: z7Graph matching failed due to failing check condition : zGraph matching failed: zGraph matching failed.z"Failure at or around nodes/values:zMatched nodes:r   )printr   rt   r   r   r   r   r   r   displayonnxscript.rewriter._ir_utilsrewriter	_ir_utilsdisplay_nodesrB   )r   	separatorr   r   failure_causeir_utilss         r   r   MatchInfo.printE  s    	i))*+,;;+---&&--F;;+">">>STZS[\]3F8<=./'+'8'8'Q'Q$67'%=M!))+ &>88t00667ir&   r1   Nr   )	r+   r,   r-   r.   r/   __annotations__r   r   r0   r1   r&   r   r   r   8  s(    R%%Kr&   r   c                      \ rS rSrSr          SS jr\SS j5       r\SS j5       r\SS j5       r	\SS j5       r
\SS j5       rS	S
.SS jjrSrg)MatchContexti^  a  A read-only context containing information about a pattern match.

This class captures information about the context describing a match to a given pattern,
providing access to the model, graph/function, root node, output values, and all
nodes of the matching subgraph.
c                4    Xl         X l        X0l        X@l        g)a  Initialize the pattern match context.

Args:
    model: The model being matched.
    graph_or_function: The graph or function being matched.
    root: The root node of the matching subgraph.
    match_result: The match result containing matched nodes and outputs.
N)_model_graph_or_function_root_match_result)r   modelgraph_or_functionrootr   s        r   r   MatchContext.__init__f  s     "3
)r&   c                    U R                   $ )zThe model being matched.)r   r#   s    r   r   MatchContext.modelz  s     {{r&   c                    U R                   $ )z$The graph or function being matched.)r   r#   s    r   r   MatchContext.graph_or_function  s     &&&r&   c                    U R                   $ )z'The root node of the matching subgraph.)r   r#   s    r   r   MatchContext.root  s     zzr&   c                .    U R                   R                  $ )z+The output values of the matching subgraph.)r   r   r#   s    r   output_valuesMatchContext.output_values  s     !!)))r&   c                .    U R                   R                  $ )z'All the nodes of the matching subgraph.)r   rB   r#   s    r   rB   MatchContext.nodes  s     !!'''r&   T)in_graph_orderc                   U R                   nU(       d  gU(       a+  U R                   H  nX2;   d  M
  UR                  5         M     gU H  nUR                  5         M     g)zDisplay the nodes in the pattern match context.

Args:
    in_graph_order: If True, display nodes in the order they appear in the
        graph/function. If False, display nodes in the order they appear
        in the match result.
N)rB   r   r   )r   r  rB   rk   s       r   r   MatchContext.display  sI     

//=LLN 0
  r&   )r   r   r   r   N)
r   ir.Modelr   r   r   r   r   r:   r   r   )r   r  )r   r   )r   r   )r   zSequence[ir.Value]r   )r  rA   r   r   )r+   r,   r-   r.   r/   r   r   r   r   r   r   rB   r   r0   r1   r&   r   r   r   ^  s    ** 2* 	*
 "* 
*(   ' '   * * ( ( 15  r&   r   c                  b    \ rS rSrSrS	S jr\S
S j5       r            SS jrS	S jr	Sr
g)MatchingTraceri  zA debugging helper class to trace the matching of a pattern against a graph.

This is used to track the best matches found for each rule, and to report the
results at the end of the matching.
c                ,    [        [        5      U l        g r   )r   r   _best_matches_mapr#   s    r   r   MatchingTracer.__init__  s    S^T
r&   c                    U R                   $ r   r  r#   s    r   best_matches_mapMatchingTracer.best_matches_map  s    %%%r&   c                   [        XCX%5      nUR                  5       nUS:X  a  g U R                  U   nU(       a=  XxS   R                  5       :  a  g XxS   R                  5       :  a  UR                  5         UR	                  U5        g )Nr   )r   r   r  clearrK   )	r   ruler   rk   r   r   
this_match
this_scorebest_matchess	            r   logMatchingTracer.log  s~     |9E
%%'
?--d3O1133O1133""$J'r&   c                &   SnU R                   R                  5        HA  u  p#U(       d  M  US   R                  5       U:  d  M'  US   R                  5       nUS   nUnMC     US:  a  [        SW 35        WR                  5         g [        S5        g )Nr   zRule: zNo matches found.)r  itemsr   r   )r   
best_scorer  matches
best_match	best_rules         r   reportMatchingTracer.report  s    
!3399;MDqz!J.$QZ--/
$QZ
 	 < >F9+&'%&r&   r  Nr   )r   z0dict[_rewrite_rule.RewriteRule, list[MatchInfo]])r  z_rewrite_rule.RewriteRuler   r   rk   r   r   r:   r   r   r   r   )r+   r,   r-   r.   r/   r   r   r  r  r  r0   r1   r&   r   r  r    sd    

 & &('( *( 	(
 "( ( 
(('r&   r  )r/   
__future__r   dataclassesenumcollectionsr   typingr   r   r   r   r	   
onnxscriptr
   onnxscript.rewriter._pattern_irr   _pattern_ir!onnxscript.rewriter._rewrite_rule_rewrite_ruler   r6   r3   r:   r=   IntEnumr   	dataclassr   r   r  r1   r&   r   <module>r*     s    = "   # G G 99==e e$)() )$dP dPNNV NVb$,,  " " "JI IX2' 2'r&   