
    3fib&                         d dl Z d dlmZ d dlmZmZmZmZmZ d dl	m
Z
  edg d      Z e
ddd	
       G d d             Zy)    N)
namedtuple)AnyDictListOptionalTuple)
deprecatedSchema)	left_noderelation
right_nodez0.3.8z1.0zAlangchain_neo4j.chains.graph_qa.cypher_utils.CypherQueryCorrector)sinceremovalalternative_importc                      e Zd ZdZ ej
                  d      Z ej
                  d      Z ej
                  d      Z ej
                  d      Z	 ej
                  d      Z
dee   fdZd	ed
efdZded
eeee   f   fdZded
dfdZded
efdZded
ee   fdZdedeeef   d
ee   fdZdee   dee   dee   d
efdZded
eeee   f   fdZded
efdZded
efdZy) CypherQueryCorrectorz
    Used to correct relationship direction in generated Cypher statements.
    This code is copied from the winner's submission to the Cypher competition:
    https://github.com/sakusaku-rich/cypher-direction-competition
    z\{.+?\}z\(.+?\)z^(\([^\,\(\)]*?(\{.+\})?[^\,\(\)]*?\))(<?-)(\[.*?\])?(->?)(\([^\,\(\)]*?(\{.+\})?[^\,\(\)]*?\))zL(\()+(?P<left_node>[^()]*?)\)(?P<relation>.*?)\((?P<right_node>[^()]*?)(\))+z":(?P<relation_type>.+?)?(\{.+\})?]schemasc                     || _         y)z<
        Args:
            schemas: list of schemas
        N)r   )selfr   s     n/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain_community/chains/graph_qa/cypher_utils.py__init__zCypherQueryCorrector.__init__    s    
     nodereturnc                     t        j                  | j                  d|      }|j                  dd      }|j                  dd      }|j	                         }|S )z@
        Args:
            node: node in string format

         ())resubproperty_patternreplacestrip)r   r   s     r   
clean_nodezCypherQueryCorrector.clean_node'   sL     vvd++R6||C$||C$zz|r   queryc                    t        j                  | j                  |      }|D cg c]  }| j                  |       }}i }|D ]7  }|j	                  d      }|dk(  r|d   }||vrg ||<   ||xx   |dd z  cc<   9 |S c c}w )7
        Args:
            query: cypher query
        :r   r      N)r   findallnode_patternr$   split)r   r%   nodesr   respartsvariables          r   detect_node_variablesz*CypherQueryCorrector.detect_node_variables3   s    
 

4,,e43894&99  	'DJJsOE{QxHs" "HMU12Y&M	' 
 :s   A?z	List[str]c           	         g }d}| j                   j                  ||d       x}r|d   }t        |      D cg c]  \  }}|dt        |      dz
  fvs| }}}dj	                  |      }|j                  |      t        |      z   t        |d         z
  }|j                  |       | j                   j                  ||d       x}r|S c c}}w )r'   r   Nr)   r   )path_patternr*   	enumeratelenjoinfindappend)r   r%   pathsidxmatchedimpaths           r   extract_pathsz"CypherQueryCorrector.extract_pathsE   s    
 **225;??g?ajG'0aAaWPQAQ=R4RG  777#D**T"SY.WR[1AACLL **225;??g? s   CCr   c                 2    d}|d   dk(  rd}|d   dk(  rd}|S )zG
        Args:
            relation: relation in string format
        BIDIRECTIONALr   <INCOMINGr3   >OUTGOING )r   r   	directions      r   judge_directionz$CypherQueryCorrector.judge_directionV   s1    
 $	A;#"IB<3"Ir   partc                     |j                  d      j                  d      }|j                  d      }|dk7  r|d| }|dk(  rdS |S )z?
        Args:
            part: node in string format
        r   r   r(   r3   Nr   )lstriprstripr8   )r   rJ   r;   s      r   extract_node_variablez*CypherQueryCorrector.extract_node_variableb   sM    
 {{3&&s+iin"9:Drzt+t+r   str_nodenode_variable_dictc                 |    |j                  d      }|d   }g }||v r||   }|S |dk(  rt        |      dkD  r|dd }|S )z
        Args:
            str_node: node in string format
            node_variable_dict: dictionary of node variables
        r(   r   r   r)   N)r,   r6   )r   rO   rP   splitted_noder0   labelss         r   detect_labelsz"CypherQueryCorrector.detect_labelsm   sa     !s+ #))'1F  ^M 2Q 6"12&Fr   from_node_labelsrelation_typesto_node_labelsc                    | j                   }|g k7  r5|D cg c]  }|j                  d       }}|D cg c]  }|d   |v s| }}|g k7  r5|D cg c]  }|j                  d       }}|D cg c]  }|d   |v s| }}|g k7  r5|D cg c]  }|j                  d       }}|D cg c]  }|d   |v s| }}|g k7  S c c}w c c}w c c}w c c}w c c}w c c}w )z
        Args:
            from_node_labels: labels of the from node
            relation_type: type of the relation
            to_node_labels: labels of the to node
        `r      r)   )r   r#   )r   rU   rV   rW   valid_schemaslabelschematypes           r   verify_schemaz"CypherQueryCorrector.verify_schema~   s    r!>NOUC 0OO%2!fQiCS6SM  R<JK5ekk#.KNK%2!fQi>6QM  R:HI$djjoINI%2!fQi>6QM  ""  P L Js4   C CCC
.C;C
C(C5Cstr_relationc                 .   | j                  |      }| j                  j                  |      }||j                  d      |g fS |j                  d      j	                  d      D cg c]!  }|j                         j                  d      # }}||fS c c}w )zK
        Args:
            str_relation: relation in string format
        relation_type|!)rI   relation_type_patternsearchgroupr,   r#   )r   r`   relation_directionrb   trV   s         r   detect_relation_typesz*CypherQueryCorrector.detect_relation_types   s    
 "11,?2299,G M$7$7$H$P%r)) #((9??D
 GGIOOC 
 
 ">11	
s   &&Bc                    | j                  |      }| j                  |      }|D ]O  }|}d}|t        |      k  st        j                  | j
                  ||d       }|=||j                         z  }|j                         }| j                  |d   |      }	| j                  |d   |      }
|dz   t        |d         z   t        |d         z   t        |d         z   }|||dz    }| j                  |d         \  }}|g k7  rHdj                  |      j                  d	      d
k7  r%|t        |d         t        |d         z   dz   z  } |dk(  r_| j                  |	||
      }|s| j                  |
||	      }|r3d|d   dd
 z   }|j                  |d   |      }|j                  ||      }n y|dk(  r_| j                  |
||	      }|sw| j                  |	||
      }|r3|d   dd dz   }|j                  |d   |      }|j                  ||      }n/ y| j                  |	||
      }|| j                  |
||	      z  }|s y|t        |d         t        |d         z   dz   z  }|t        |      k  r9R |S )r'   r   Nr   r      r   r)   r   *r3   rZ   rF   rC   rD   rE   )r1   r@   r6   r   matchnode_relation_node_patternstart	groupdictrT   rj   r7   r8   r_   r"   )r   r%   rP   r:   r?   original_path	start_idx	match_res
match_dictleft_node_labelsright_node_labelsend_idxoriginal_partial_pathrh   rV   is_legalcorrected_relationcorrected_partial_paths                     r   correct_queryz"CypherQueryCorrector.correct_query   sC   
 "77>""5) Q	D MIc$i'HHT%D%Dd9:FVW	$Y__..	&002
#'#5#5{+-?$  %)$6$6|,.@%! *[123 *Z012 *\23	4  )6i'A+(N%595O5Oz*62"N "R'BGGN,C,H,H,MQS,SJ{34s:j;Q7RRUVVI %3#11(.:K H $#'#5#5-~?O$ $14z*7Mcr7R1R.5J5R5R *: 68J62 %*MM 57M%E $&':5#11)>;K H $#'#5#5,n>O$ $1;J1G1Kc1Q.5J5R5R *: 68J62 %*MM 57M%E $&#11(.:K H  2 2)>;K! H $!
;/03z*7M3NNQRR	Y c$i'Q	d r   c                 $    | j                  |      S )z]Correct the query to make it valid. If
        Args:
            query: cypher query
        )r}   )r   r%   s     r   __call__zCypherQueryCorrector.__call__  s    
 !!%((r   N)__name__
__module____qualname____doc__r   compiler!   r+   r4   ro   re   r   r
   r   strr$   r   r1   r@   rI   r   rN   r   rT   boolr_   r   rj   r}   r   rG   r   r   r   r   
   s    "rzz*-2::j)L2::iL ",W" 'BJJ'LMV 
s 
s 
3 4T#Y3G $3 ; "
 
 
	,# 	,(3- 	,15c3h	c"#s)# S	# S		#
 
#<2# 2%T#Y:O 2Y3 Y3 Yv)c )c )r   r   )r   collectionsr   typingr   r   r   r   r   langchain_core._api.deprecationr	   r
   r   rG   r   r   <module>r      sK    	 " 3 3 6	HE	F 
Z
|) |)
|)r   