o
    mi                      @  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   M/home/kim/smarthome/.venv/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"   sequenceZinverse_pathZalternative_pathZalternativesZzero_or_more_pathZone_or_more_pathZ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r=   r   r   
<listcomp>       z)_build_path_component.<locals>.<listcomp>r%   c                   r@   r   rA   rC   rE   r   r   rF      rG   NzUnknown path modifier )r*   r	   r   r+   typer   r
   r2   r1   argsr   r   r4   addr   r3   rB   rD   r6   r5   urir8   _PATH_MOD_TO_PREDgetmodr"   )r=   r>   ZbnodeZcollpredr   rE   r   rB   o   sV   
$rB   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   rB   )r"   rP   r   r   r   build_shacl_path   s
   
rS   )r   r   r   r   r   r   )r=   r   r>   r?   r   r   r   )r"   r?   rP   rQ   r   rR   )#__doc__
__future__r   typingr   r   r   Zrdflibr   r   r   r	   r
   Zrdflib.collectionr   Zrdflib.namespacer   r   Zrdflib.pathsr   Zrdflib.termr   r   	Exceptionr   Z
ZeroOrMorer7   Z	OneOrMorer9   Z	ZeroOrOner:   rL   r    rB   rS   r   r   r   r   <module>   s&    
	
NL