o
    
i                      @  s   d Z ddlmZ ddlmZmZmZ ddlmZm	Z	m
Z
mZmZ ddlmZ ddlmZmZ ddlmZ ddlmZ erBdd	lmZ G d
d deZejejejejejejiZd!ddZ d"ddZ!	d#d$dd Z"dS )%zA
Utilities for interacting with SHACL Shapes Graphs more easily.
    )annotations)TYPE_CHECKINGOptionalUnion)BNodeGraphLiteralURIRefpaths)
Collection)RDFSH)Path)Node)IdentifiedNodec                   @  s   e Zd ZdS )SHACLPathErrorN)__name__
__module____qualname__ r   r   G/home/ubuntu/.local/lib/python3.10/site-packages/rdflib/extras/shacl.pyr      s    r   shapes_graphr   path_identifierr   returnUnion[URIRef, Path]c           
        s  d}t |trtdt |tr|tjkrtd|}|S  |tjdurEt	 
|}t|dk r7tdtj fdd|D  }|S  |tj }rXtt |}|S  |tj }rt	 
|}t|dk rrtdtj fd	d|D  }|S  |tj }rtt |d
}|S  |tj }rtt |d}|S  |tj }	rtt |	d}|S |du rtdt| d|S )a  
    Parse a valid SHACL path (e.g. the object of a triple with predicate sh:path)
    from a [`Graph`][rdflib.graph.Graph] as a [`URIRef`][rdflib.term.URIRef] if the path
    is simply a predicate or a [`Path`][rdflib.paths.Path] otherwise.

    Args:
        shapes_graph: A [`Graph`][rdflib.graph.Graph] containing the path to be parsed
        path_identifier: A [`Node`][rdflib.term.Node] of the path

    Returns:
        A [`URIRef`][rdflib.term.URIRef] or a [`Path`][rdflib.paths.Path]
    Nz$Literals are not a valid SHACL path.z;A list of SHACL Paths must contain at least two path items.   DA list of SHACL Sequence Paths must contain at least two path items.c                 3      | ]}t  |V  qd S Nparse_shacl_path).0pathr   r   r   	<genexpr>G   s    z#parse_shacl_path.<locals>.<genexpr>@List of SHACL alternate paths must have at least two path items.c                 3  r   r   r   )r!   alternativer#   r   r   r$   V   s
    
*+?zCannot parse z as a SHACL Path.)
isinstancer   	TypeErrorr	   r   nilr   valuefirstlistitemslenr
   SequencePathr   inversePathInvPathr    alternativePathAlternativePathzeroOrMorePathMulPathoneOrMorePathzeroOrOnePathrepr)
r   r   r"   sequenceinverse_pathalternative_pathalternativeszero_or_more_pathone_or_more_pathzero_or_one_pathr   r#   r   r    !   s^   


/& 

r    graphpath_componentURIRef | Pathr   c                   sJ  t |ttfstdt| dd t |tr|S t }t |tjr>t|j	dk r.t
dt | fdd|j	D  |S t |tjrS |tjt |jf |S t |tjrt|j	dk rdt
dt t  fd	d|j	D } |tj|jf |S t |tjrt|j}|d
u rt
d|j  ||t |jf |S )a  
    Helper method that implements the recursive component of SHACL path
    triple construction.

    Args:
        graph: A [`Graph`][rdflib.graph.Graph] into which to insert triples
        graph_component: A [`URIRef`][rdflib.term.URIRef] or
            [`Path`][rdflib.paths.Path] that is part of a path expression

    Returns:
        The [`IdentifiedNode`][rdflib.term.IdentifiedNode] of the resource in the
            graph that corresponds to the provided path_component
    zObjects of type z are not valid zcomponents of a SHACL path.r   r   c                      g | ]}t  |qS r   _build_path_componentr!   argrC   r   r   
<listcomp>       z)_build_path_component.<locals>.<listcomp>r%   c                   rF   r   rG   rI   rK   r   r   rL      rM   NzUnknown path modifier )r*   r	   r   r+   typer   r
   r2   r1   argsr   r   r4   addr   r3   rH   rJ   r6   r5   urir8   _PATH_MOD_TO_PREDgetmodr"   )rC   rD   bnodecollpredr   rK   r   rH   o   sV   
$rH   Nr"   target_graphGraph | None#tuple[IdentifiedNode, Graph | None]c                 C  s.   t | tr	| dfS |du rt }t|| |fS )a  
    Build the SHACL Path triples for a path given by a [`URIRef`][rdflib.term.URIRef] for
    simple paths or a [`Path`][rdflib.paths.Path] for complex paths.

    Returns an [`IdentifiedNode`][rdflib.term.IdentifiedNode] for the path (which should be
    the object of a triple with predicate `sh:path`) and the graph into which any
    new triples were added.

    Args:
        path: A [`URIRef`][rdflib.term.URIRef] or a [`Path`][rdflib.paths.Path]
        target_graph: Optionally, a [`Graph`][rdflib.graph.Graph] into which to put
            constructed triples. If not provided, a new graph will be created

    Returns:
        A (path_identifier, graph) tuple where:
            - path_identifier: If path is a [`URIRef`][rdflib.term.URIRef], this is simply
            the provided path. If path is a [`Path`][rdflib.paths.Path], this is
            the [`BNode`][rdflib.term.BNode] corresponding to the root of the SHACL
            path expression added to the graph.
            - graph: None if path is a [`URIRef`][rdflib.term.URIRef] (as no new triples
            are constructed). If path is a [`Path`][rdflib.paths.Path], this is either the
            target_graph provided or a new graph into which the path triples were added.
    N)r*   r	   r   rH   )r"   rX   r   r   r   build_shacl_path   s
   
r[   )r   r   r   r   r   r   )rC   r   rD   rE   r   r   r   )r"   rE   rX   rY   r   rZ   )#__doc__
__future__r   typingr   r   r   rdflibr   r   r   r	   r
   rdflib.collectionr   rdflib.namespacer   r   rdflib.pathsr   rdflib.termr   r   	Exceptionr   
ZeroOrMorer7   	OneOrMorer9   	ZeroOrOner:   rR   r    rH   r[   r   r   r   r   <module>   s&    
	
NL