Commit dc2f4381 authored by Fabien Amarger's avatar Fabien Amarger
Browse files

(feat): Handle if no domain/range or several domain/range for a relation or an attribute

parent dabdb7d5595a
from typing import Iterable
import subprocess
import re
import os
......@@ -2,5 +1,6 @@
import subprocess
import re
import os
from typing import Iterable, Optional, List
from argparse import ArgumentParser
......@@ -5,5 +5,6 @@
from argparse import ArgumentParser
import itertools
from rdflib import Graph, RDF, RDFS, OWL, XSD, URIRef # type: ignore
from urllib.parse import urlparse
from yams.schema import Schema # type: ignore
......@@ -26,5 +27,5 @@
}
def fragment_from_uri(uri: str) -> str:
def fragment_from_uri(uri: str) -> Optional[str]:
if uri == OWL.Thing:
......@@ -30,5 +31,5 @@
if uri == OWL.Thing:
return "*"
return None
url = urlparse(uri)
# if url.fragment is not None, the fragment is done with `#`
if url.fragment:
......@@ -37,6 +38,14 @@
return url.path.split("/")[-1]
def generate_yams_domain_from_urirefs(uris: Iterable[URIRef]) -> str:
fragments = [fragment_from_uri(uri) for uri in uris]
def yams_domain_from_urirefs(
uris: Iterable[URIRef], all_entity_types: Iterable[str]
) -> List[str]:
fragments: List[str] = []
for uri in uris:
fragment = fragment_from_uri(uri)
if fragment is not None:
fragments.append(fragment)
else:
return list(all_entity_types)
if not len(fragments):
......@@ -42,6 +51,6 @@
if not len(fragments):
return "*"
return ", ".join(fragments)
return list(all_entity_types)
return fragments
def owl_model_to_yams(owl_model: Graph, instance_name: str) -> Schema:
......@@ -55,6 +64,9 @@
# 1. fetch all classes
for class_uri, _, _ in owl_model.triples((None, RDF.type, OWL.Class)):
class_fragment = fragment_from_uri(class_uri)
if class_fragment is None:
print(f"Warning: class {class_uri} could not be parsed")
continue
schema.add_entity_type(EntityType(class_fragment))
entity_schema = schema._entities[class_fragment]
ETYPE_URI[class_fragment] = class_uri
......@@ -62,7 +74,9 @@
for _, _, superior_class_uri in owl_model.triples(
(class_uri, RDFS.subClassOf, None)
):
superior_classes.append(fragment_from_uri(superior_class_uri))
superior_class_fragment = fragment_from_uri(superior_class_uri)
if superior_class_fragment is not None:
superior_classes.append(superior_class_fragment)
if superior_classes:
entity_schema._specialized_type = ", ".join(superior_classes)
......@@ -74,6 +88,9 @@
_,
) in owl_model.triples((None, RDF.type, OWL.DatatypeProperty)):
datatype_property_uri_fragment = fragment_from_uri(datatype_property_uri)
if datatype_property_uri_fragment is None:
print(f"Warning: data property {datatype_property_uri} could not be parsed")
continue
schema.add_relation_type(RelationType(datatype_property_uri_fragment))
# take first range, if no range use RDFS.Literal
_, _, literal_type = next(
......@@ -81,8 +98,18 @@
(_, _, RDFS.Literal),
)
yams_type = LITERAL_TYPES_TO_YAMS_TYPES[literal_type]
yams_domains = generate_yams_domain_from_urirefs(
domain_uri
for _, _, domain_uri in owl_model.triples(
(datatype_property_uri, RDFS.domain, None)
domain_fragments = yams_domain_from_urirefs(
(
domain_uri
for _, _, domain_uri in owl_model.triples(
(datatype_property_uri, RDFS.domain, None)
)
),
ETYPE_URI.keys(),
)
for domain_fragment in domain_fragments:
schema.add_relation_def(
RelationDefinition(
domain_fragment, datatype_property_uri_fragment, yams_type
)
)
......@@ -88,8 +115,4 @@
)
)
schema.add_relation_def(
RelationDefinition(yams_domains, datatype_property_uri_fragment, yams_type)
)
# 3. fetch all object properties
......@@ -99,4 +122,7 @@
_,
) in owl_model.triples((None, RDF.type, OWL.ObjectProperty)):
object_property_uri_fragment = fragment_from_uri(object_property_uri)
if object_property_uri_fragment is None:
print(f"Warning: object property {object_property_uri} could not be parsed")
continue
schema.add_relation_type(RelationType(object_property_uri_fragment))
......@@ -102,7 +128,11 @@
schema.add_relation_type(RelationType(object_property_uri_fragment))
domain_fragments = generate_yams_domain_from_urirefs(
domain_uri
for _, _, domain_uri in owl_model.triples(
(object_property_uri, RDFS.domain, None)
)
all_types = list(ETYPE_URI.keys())
domain_fragments = yams_domain_from_urirefs(
(
domain_uri
for _, _, domain_uri in owl_model.triples(
(object_property_uri, RDFS.domain, None)
)
),
all_types,
)
......@@ -108,7 +138,10 @@
)
range_fragments = generate_yams_domain_from_urirefs(
range_uri
for _, _, range_uri in owl_model.triples(
(object_property_uri, RDFS.range, None)
)
range_fragments = yams_domain_from_urirefs(
(
range_uri
for _, _, range_uri in owl_model.triples(
(object_property_uri, RDFS.range, None)
)
),
all_types,
)
......@@ -114,7 +147,11 @@
)
schema.add_relation_def(
RelationDefinition(
domain_fragments,
object_property_uri_fragment,
range_fragments,
for domain_fragment, range_fragment in itertools.product(
domain_fragments, range_fragments
):
schema.add_relation_def(
RelationDefinition(
domain_fragment,
object_property_uri_fragment,
range_fragment,
)
)
......@@ -120,5 +157,4 @@
)
)
return schema
......
......@@ -10,3 +10,7 @@
subject = ('SubClass',)
object = ('FirstClass',)
class rel2(RelationDefinition):
subject = ('SubClass',)
object = '*'
......@@ -15,3 +15,6 @@
:rel1 a owl:ObjectProperty;
rdfs:domain :SubClass;
rdfs:range :FirstClass.
:rel2 a owl:ObjectProperty;
rdfs:domain :SubClass.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment