From 312449082fb5b0a2bb9511d87c0e1281c998c8f6 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Fri, 16 Aug 2024 09:34:01 +0100 Subject: [PATCH 01/28] move doc mds to module, add validate mode parameter --- CHANGELOG.md | 6 ++++ README.md | 5 +++ cmem_plugin_reason/doc/__init__.py | 9 +++++ cmem_plugin_reason/{ => doc}/reason_doc.md | 0 cmem_plugin_reason/{ => doc}/validate_doc.md | 5 +++ cmem_plugin_reason/plugin_reason.py | 11 ++---- cmem_plugin_reason/plugin_validate.py | 35 ++++++++++++++----- cmem_plugin_reason/{bin => }/robot.jar | Bin cmem_plugin_reason/utils.py | 17 +++++---- tests/test_reason.py | 1 + 10 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 cmem_plugin_reason/doc/__init__.py rename cmem_plugin_reason/{ => doc}/reason_doc.md (100%) rename cmem_plugin_reason/{ => doc}/validate_doc.md (92%) rename cmem_plugin_reason/{bin => }/robot.jar (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 709cf2b..782920f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +### Added + + - Validate: added "mode" parameter + +## [1.0.0beta5] 2024-08-15 + ### Added - defined input and output schema diff --git a/README.md b/README.md index ea9783a..d707a83 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,11 @@ The filename of the Markdown file with the explanation of inconsistencies. ### Stop at inconsistencies Raise an error if inconsistencies are found. If enabled, the plugin does not output entities. +### Mode +Mode _inconsistency_ generates an explanation for an inconsistent ontology. + +Mode _unsatisfiability_ generates explanations for many unsatisfiable classes at once. + ### Validate OWL2 profiles Validate the input ontology against OWL profiles (DL, EL, QL, RL, and Full) and annotate the result graph. diff --git a/cmem_plugin_reason/doc/__init__.py b/cmem_plugin_reason/doc/__init__.py new file mode 100644 index 0000000..4dc90ec --- /dev/null +++ b/cmem_plugin_reason/doc/__init__.py @@ -0,0 +1,9 @@ +"""doc""" + +from pathlib import Path + +with (Path(__path__[0]) / "reason_doc.md").open("r") as f: + REASON_DOC = f.read() + +with (Path(__path__[0]) / "validate_doc.md").open("r") as f: + VALIDATE_DOC = f.read() diff --git a/cmem_plugin_reason/reason_doc.md b/cmem_plugin_reason/doc/reason_doc.md similarity index 100% rename from cmem_plugin_reason/reason_doc.md rename to cmem_plugin_reason/doc/reason_doc.md diff --git a/cmem_plugin_reason/validate_doc.md b/cmem_plugin_reason/doc/validate_doc.md similarity index 92% rename from cmem_plugin_reason/validate_doc.md rename to cmem_plugin_reason/doc/validate_doc.md index b21df69..3b03a38 100644 --- a/cmem_plugin_reason/validate_doc.md +++ b/cmem_plugin_reason/doc/validate_doc.md @@ -45,6 +45,11 @@ Raise an error if inconsistencies are found. If enabled, the plugin does not out Validate the input ontology against OWL profiles (DL, EL, QL, RL, and Full) and annotate the result graph. +### Mode +Mode _inconsistency_ generates an explanation for an inconsistent ontology. + +Mode _unsatisfiability_ generates explanations for many unsatisfiable classes at once. + ### Output entities Output entities. The plugin outputs the explanation as text in Markdown format on the path "markdown", the ontology IRI diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index ef97a62..26d646b 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -10,7 +10,6 @@ from cmem.cmempy.dp.proxy.update import post from cmem_plugin_base.dataintegration.context import ExecutionContext, ExecutionReport from cmem_plugin_base.dataintegration.description import Icon, Plugin, PluginParameter -from cmem_plugin_base.dataintegration.parameter.choice import ChoiceParameterType from cmem_plugin_base.dataintegration.parameter.graph import GraphParameterType from cmem_plugin_base.dataintegration.plugins import WorkflowPlugin from cmem_plugin_base.dataintegration.ports import FixedNumberOfInputs @@ -18,11 +17,12 @@ from cmem_plugin_base.dataintegration.utils import setup_cmempy_user_access from inflection import underscore +from cmem_plugin_reason.doc import REASON_DOC from cmem_plugin_reason.utils import ( MAX_RAM_PERCENTAGE_DEFAULT, MAX_RAM_PERCENTAGE_PARAMETER, ONTOLOGY_GRAPH_IRI_PARAMETER, - REASON_DOC, + REASONER_PARAMETER, REASONERS, VALIDATE_PROFILES_PARAMETER, create_xml_catalog_file, @@ -44,6 +44,7 @@ parameters=[ ONTOLOGY_GRAPH_IRI_PARAMETER, VALIDATE_PROFILES_PARAMETER, + REASONER_PARAMETER, MAX_RAM_PERCENTAGE_PARAMETER, PluginParameter( param_type=GraphParameterType( @@ -59,12 +60,6 @@ description="""The IRI of the output graph for the inconsistency validation. ⚠️ Existing graphs will be overwritten.""", ), - PluginParameter( - param_type=ChoiceParameterType(REASONERS), - name="reasoner", - label="Reasoner", - description="Reasoner option. Additionally, select axiom generators below.", - ), PluginParameter( param_type=GraphParameterType( classes=[ diff --git a/cmem_plugin_reason/plugin_validate.py b/cmem_plugin_reason/plugin_validate.py index 5f3dff6..dbec837 100644 --- a/cmem_plugin_reason/plugin_validate.py +++ b/cmem_plugin_reason/plugin_validate.py @@ -1,5 +1,6 @@ """Ontology consistency validation workflow plugin module""" +from collections import OrderedDict from datetime import UTC, datetime from pathlib import Path from tempfile import TemporaryDirectory @@ -19,12 +20,13 @@ from cmem_plugin_base.dataintegration.utils import setup_cmempy_user_access from pathvalidate import is_valid_filename +from cmem_plugin_reason.doc import VALIDATE_DOC from cmem_plugin_reason.utils import ( MAX_RAM_PERCENTAGE_DEFAULT, MAX_RAM_PERCENTAGE_PARAMETER, ONTOLOGY_GRAPH_IRI_PARAMETER, + REASONER_PARAMETER, REASONERS, - VALIDATE_DOC, VALIDATE_PROFILES_PARAMETER, create_xml_catalog_file, get_graphs_tree, @@ -46,6 +48,7 @@ ONTOLOGY_GRAPH_IRI_PARAMETER, MAX_RAM_PERCENTAGE_PARAMETER, VALIDATE_PROFILES_PARAMETER, + REASONER_PARAMETER, PluginParameter( param_type=GraphParameterType( allow_only_autocompleted_values=False, @@ -61,12 +64,6 @@ graphs will be overwritten.""", default_value="", ), - PluginParameter( - param_type=ChoiceParameterType(REASONERS), - name="reasoner", - label="Reasoner", - description="Reasoner option.", - ), PluginParameter( param_type=StringParameterType(), name="md_filename", @@ -92,17 +89,34 @@ if enabled, the valid OWL2 profiles on the path "valid_profiles".""", default_value=False, ), + PluginParameter( + param_type=ChoiceParameterType( + OrderedDict( + { + "inconsistency": "inconsistency", + "unsatisfiability": "unsatisfiability", + } + ) + ), + name="mode", + label="Mode", + description="""Mode "inconsistency" generates an explanation for an inconsistent + ontology.\nMode "unsatisfiability" generates explanations for many unsatisfiable classes + at once.""", + default_value="inconsistency", + ), ], ) class ValidatePlugin(WorkflowPlugin): """Validate plugin""" - def __init__( # noqa: PLR0913 C901 + def __init__( # noqa: PLR0912 PLR0913 C901 self, ontology_graph_iri: str, reasoner: str, output_graph_iri: str = "", md_filename: str = "", + mode: str = "inconsistency", validate_profile: bool = False, output_entities: bool = False, stop_at_inconsistencies: bool = False, @@ -121,6 +135,8 @@ def __init__( # noqa: PLR0913 C901 errors += 'Invalid filename for parameter "Output filename". ' if not output_graph_iri and not md_filename and not output_entities: errors += "No output selected. " + if mode not in ("inconsistency", "unsatisfiability"): + errors += 'Invalid value for parameter "Mode". ' if max_ram_percentage not in range(1, 101): errors += 'Invalid value for parameter "Maximum RAM Percentage". ' if errors: @@ -128,6 +144,7 @@ def __init__( # noqa: PLR0913 C901 self.ontology_graph_iri = ontology_graph_iri self.reasoner = reasoner self.output_graph_iri = output_graph_iri + self.mode = mode self.stop_at_inconsistencies = stop_at_inconsistencies if md_filename: self.md_filename = md_filename @@ -167,7 +184,7 @@ def explain(self, graphs: dict) -> None: utctime = str(datetime.fromtimestamp(int(time()), tz=UTC))[:-6].replace(" ", "T") + "Z" cmd = ( f'explain --input "{data_location}" ' - f"--reasoner {self.reasoner} -M inconsistency " + f"--reasoner {self.reasoner} -M {self.mode} " f'--explanation "{self.temp}/{self.md_filename}"' ) if self.output_graph_iri: diff --git a/cmem_plugin_reason/bin/robot.jar b/cmem_plugin_reason/robot.jar similarity index 100% rename from cmem_plugin_reason/bin/robot.jar rename to cmem_plugin_reason/robot.jar diff --git a/cmem_plugin_reason/utils.py b/cmem_plugin_reason/utils.py index 9eeafa8..d9f33ba 100644 --- a/cmem_plugin_reason/utils.py +++ b/cmem_plugin_reason/utils.py @@ -13,6 +13,7 @@ from cmem.cmempy.dp.proxy.update import post as post_update from cmem_plugin_base.dataintegration.context import ExecutionContext from cmem_plugin_base.dataintegration.description import PluginParameter +from cmem_plugin_base.dataintegration.parameter.choice import ChoiceParameterType from cmem_plugin_base.dataintegration.parameter.graph import GraphParameterType from cmem_plugin_base.dataintegration.plugins import WorkflowPlugin from cmem_plugin_base.dataintegration.types import BoolParameterType, IntParameterType @@ -20,11 +21,7 @@ from . import __path__ -with (Path(__path__[0]) / "reason_doc.md").open("r") as f: - REASON_DOC = f.read() - -with (Path(__path__[0]) / "validate_doc.md").open("r") as f: - VALIDATE_DOC = f.read() +ROBOT = Path(__path__[0]) / "robot.jar" REASONERS = OrderedDict( { @@ -39,6 +36,13 @@ MAX_RAM_PERCENTAGE_DEFAULT = 20 +REASONER_PARAMETER = PluginParameter( + param_type=ChoiceParameterType(REASONERS), + name="reasoner", + label="Reasoner", + description="Reasoner option.", +) + ONTOLOGY_GRAPH_IRI_PARAMETER = PluginParameter( param_type=GraphParameterType(classes=["http://www.w3.org/2002/07/owl#Ontology"]), name="ontology_graph_iri", @@ -194,8 +198,7 @@ def get_provenance(plugin: WorkflowPlugin, context: ExecutionContext) -> dict | def robot(cmd: str, max_ram_percentage: int) -> CompletedProcess: """Run robot.jar""" - jar = Path(__path__[0]) / "bin" / "robot.jar" - cmd = f"java -XX:MaxRAMPercentage={max_ram_percentage} -jar {jar} {cmd}" + cmd = f"java -XX:MaxRAMPercentage={max_ram_percentage} -jar {ROBOT} {cmd}" return run(shlex.split(cmd), check=False, capture_output=True) # noqa: S603 diff --git a/tests/test_reason.py b/tests/test_reason.py index e6d48de..1b5ee37 100644 --- a/tests/test_reason.py +++ b/tests/test_reason.py @@ -95,6 +95,7 @@ def test_validate(errors: str) -> str: validate_profile=True, md_filename=MD_FILENAME, output_entities=True, + mode="inconsistency", ).execute(None, context=TestExecutionContext(PROJECT_ID)) md_test = (Path(__path__[0]) / "test_validate.md").read_text() From 1a1ae558ad06ab8ec94571cd3a06de82726d0489 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Fri, 16 Aug 2024 09:39:35 +0100 Subject: [PATCH 02/28] edit --- cmem_plugin_reason/plugin_validate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmem_plugin_reason/plugin_validate.py b/cmem_plugin_reason/plugin_validate.py index dbec837..62c3eb4 100644 --- a/cmem_plugin_reason/plugin_validate.py +++ b/cmem_plugin_reason/plugin_validate.py @@ -101,7 +101,7 @@ name="mode", label="Mode", description="""Mode "inconsistency" generates an explanation for an inconsistent - ontology.\nMode "unsatisfiability" generates explanations for many unsatisfiable classes + ontology. Mode "unsatisfiability" generates explanations for many unsatisfiable classes at once.""", default_value="inconsistency", ), From 4f3f9851b9e42c8475da6ad44a9c21efb3a55acb Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Fri, 16 Aug 2024 10:04:45 +0100 Subject: [PATCH 03/28] edit doc --- cmem_plugin_reason/doc/validate_doc.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmem_plugin_reason/doc/validate_doc.md b/cmem_plugin_reason/doc/validate_doc.md index 3b03a38..11a584b 100644 --- a/cmem_plugin_reason/doc/validate_doc.md +++ b/cmem_plugin_reason/doc/validate_doc.md @@ -46,8 +46,7 @@ Raise an error if inconsistencies are found. If enabled, the plugin does not out Validate the input ontology against OWL profiles (DL, EL, QL, RL, and Full) and annotate the result graph. ### Mode -Mode _inconsistency_ generates an explanation for an inconsistent ontology. - +Mode _inconsistency_ generates an explanation for an inconsistent ontology. Mode _unsatisfiability_ generates explanations for many unsatisfiable classes at once. ### Output entities From 731f28571148abab291276235818e4cfcea9c892 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Fri, 16 Aug 2024 10:05:13 +0100 Subject: [PATCH 04/28] edit readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index d707a83..583dec0 100644 --- a/README.md +++ b/README.md @@ -152,8 +152,7 @@ The filename of the Markdown file with the explanation of inconsistencies. Raise an error if inconsistencies are found. If enabled, the plugin does not output entities. ### Mode -Mode _inconsistency_ generates an explanation for an inconsistent ontology. - +Mode _inconsistency_ generates an explanation for an inconsistent ontology. Mode _unsatisfiability_ generates explanations for many unsatisfiable classes at once. ### Validate OWL2 profiles From b1c971f1693e34571565b58aecdf9069c1e9af3a Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Fri, 16 Aug 2024 10:08:49 +0100 Subject: [PATCH 05/28] edit warning icon in readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 583dec0..d491540 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ The IRI of the input ontology graph. The graph IRI is selected from a list of gr The IRI of the output graph for the reasoning result. -:warning: Existing graphs will be overwritten. +⚠️ Existing graphs will be overwritten. ### Reasoner @@ -104,7 +104,7 @@ Add the triple ` owl:imports ` to the onto Maximum heap size for the Java virtual machine in the DI container running the reasoning process. -:warning: Setting the percentage too high may result in an out of memory error. +⚠️ Setting the percentage too high may result in an out of memory error. # Validate @@ -136,7 +136,7 @@ If enabled, an explanation graph is created. The IRI of the output graph for the reasoning result. -:warning: Existing graphs will be overwritten. +⚠️ Existing graphs will be overwritten. ### Write markdown explanation file @@ -146,7 +146,7 @@ If enabled, an explanation markdown file is written to the project. The filename of the Markdown file with the explanation of inconsistencies. -:warning: Existing files will be overwritten. +⚠️ Existing files will be overwritten. ### Stop at inconsistencies Raise an error if inconsistencies are found. If enabled, the plugin does not output entities. @@ -168,4 +168,4 @@ on the path "ontology_graph_iri", and, if enabled, the valid OWL2 profiles on th Maximum heap size for the Java virtual machine in the DI container running the reasoning process. -:warning: Setting the percentage too high may result in an out of memory error. \ No newline at end of file +⚠️ Setting the percentage too high may result in an out of memory error. \ No newline at end of file From 18486bd65b53bc4885e7f42e4fe8e4788e480a6f Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Fri, 16 Aug 2024 12:45:19 +0100 Subject: [PATCH 06/28] edit tests --- tests/test_reason.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/test_reason.py b/tests/test_reason.py index 1b5ee37..8e03da3 100644 --- a/tests/test_reason.py +++ b/tests/test_reason.py @@ -7,6 +7,7 @@ from cmem.cmempy.dp.proxy.graph import delete, get, post from cmem.cmempy.workspace.projects.project import delete_project, make_new_project from cmem.cmempy.workspace.projects.resources.resource import get_resource +from cmem_plugin_base.dataintegration.entity import Entities from rdflib import DCTERMS, OWL, RDF, RDFS, Graph, URIRef from rdflib.compare import to_isomorphic @@ -27,6 +28,15 @@ PROJECT_ID = f"validate_plugin_test_project_{UID}" +def get_value_dict(entities: Entities) -> dict: + """Make result path to value map""" + value_dict = {} + paths = [p.path for p in entities.schema.paths] + for p in paths: + value_dict[p] = next(iter(entities.entities)).values[paths.index(p)][0] # type: ignore[union-attr] + return value_dict + + @pytest.fixture() def _setup(request: pytest.FixtureRequest) -> None: """Set up""" @@ -99,29 +109,21 @@ def test_validate(errors: str) -> str: ).execute(None, context=TestExecutionContext(PROJECT_ID)) md_test = (Path(__path__[0]) / "test_validate.md").read_text() - paths = [p.path for p in result.schema.paths] # type: ignore[union-attr] + value_dict = get_value_dict(result) + output_graph = get_remote_graph(OUTPUT_GRAPH_IRI) + test = Graph().parse(Path(__path__[0]) / "test_validate_output.ttl", format="turtle") val_errors = "" - if next(iter(result.entities)).values[paths.index("markdown")][0] != md_test: # type: ignore[union-attr] + if value_dict["markdown"] != md_test: val_errors += 'EntityPath "markdown" output error. ' - if ( - next(iter(result.entities)).values[paths.index("ontology_graph_iri")][0] # type: ignore[union-attr] - != VALIDATE_ONTOLOGY_GRAPH_IRI - ): + if value_dict["ontology_graph_iri"] != VALIDATE_ONTOLOGY_GRAPH_IRI: val_errors += 'EntityPath "ontology_graph_iri" output error. ' - if ( - next(iter(result.entities)).values[paths.index("valid_profiles")][0] # type: ignore[union-attr] - != "Full,DL,EL,QL,RL" - ): + if value_dict["valid_profiles"] != "Full,DL,EL,QL,RL": val_errors += 'EntityPath "valid_profiles" output error. ' if md_test != get_resource(PROJECT_ID, MD_FILENAME).decode(): val_errors += "Markdown file error. " - - output_graph = get_remote_graph(OUTPUT_GRAPH_IRI) - test = Graph().parse(Path(__path__[0]) / "test_validate_output.ttl", format="turtle") if to_isomorphic(output_graph) != to_isomorphic(test): val_errors += "Output graph error. " - if val_errors: errors += "Validate: " + val_errors return errors From 26251bf8e045d425f29983761801dfd6dd4d700d Mon Sep 17 00:00:00 2001 From: Sebastian Tramp Date: Tue, 20 Aug 2024 13:52:43 +0200 Subject: [PATCH 07/28] add first description --- cmem_plugin_reason/plugin_reason.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index 26d646b..8d28396 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -35,6 +35,10 @@ validate_profiles, ) +SUBCLASS_DESC = """Infer assertions about the subclass relationship of classes. + +If there are classes *A* ,*B* and *C* as well as an object property *hasPart*, such that +*A ⊑ B and hasPart some C* holds, the reasoner will infer A ⊑ B.""" @Plugin( label="Reason", @@ -76,7 +80,7 @@ param_type=BoolParameterType(), name="sub_class", label="SubClass", - description="", + description=SUBCLASS_DESC, default_value=True, ), PluginParameter( From 9c9638a857b6a53233ef665995c085f5cce74ded Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Tue, 20 Aug 2024 17:24:22 +0200 Subject: [PATCH 08/28] Add descriptions for class axiom generators --- cmem_plugin_reason/plugin_reason.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index 8d28396..dbb14bb 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -37,8 +37,16 @@ SUBCLASS_DESC = """Infer assertions about the subclass relationship of classes. -If there are classes *A* ,*B* and *C* as well as an object property *hasPart*, such that -*A ⊑ B and hasPart some C* holds, the reasoner will infer A ⊑ B.""" +If there are classes `Person`, ` Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`""" + +EQUIVALENCE_DESC = """Infer assertions about the equivalency of classes. + +If there are classes `Person`, ` Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`.""" + +DISJOINT_DESC = """Infer assertions about the disjointness of classes. + +If there are classes `Person`, ` Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `DisjointClasses: Professor, Student`.""" + @Plugin( label="Reason", @@ -87,14 +95,14 @@ param_type=BoolParameterType(), name="equivalent_class", label="EquivalentClass", - description="", + description=EQUIVALENCE_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="disjoint_classes", label="DisjointClasses", - description="", + description=DISJOINT_DESC, default_value=False, ), PluginParameter( From 9b403a732cc95bb7aaba61e6914b55eaa9b2fa76 Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Thu, 22 Aug 2024 09:40:14 +0200 Subject: [PATCH 09/28] Add descriptions for data property axiom generators --- cmem_plugin_reason/plugin_reason.py | 64 +++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index dbb14bb..dbde3c7 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -35,18 +35,46 @@ validate_profiles, ) -SUBCLASS_DESC = """Infer assertions about the subclass relationship of classes. +SUBCLASS_DESC = """The reasoner will infer assertions about the hierarchy of classes, i.e. +`SubClassOf:` statements. -If there are classes `Person`, ` Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`""" +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`.""" -EQUIVALENCE_DESC = """Infer assertions about the equivalency of classes. +EQUIVALENCE_DESC = """The reasoner will infer assertions about the equivalence of classes, i.e. +`EquivalentTo:` statements. -If there are classes `Person`, ` Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`.""" +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. +""" -DISJOINT_DESC = """Infer assertions about the disjointness of classes. +DISJOINT_DESC = """The reasoner will infer assertions about the disjointness of classes, i.e. +`DisjointClasses:` statements. -If there are classes `Person`, ` Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `DisjointClasses: Professor, Student`.""" +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Student DisjointClasses: Student, Professor` +""" +DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. +`Characteristics:` statements. For data properties, this only pertains to functionality. + +If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will +infer `enrollmentNumber Characteristics: Functional`.""" + +DATA_PROP_EQUIV_DESC = """The reasoner will infer axioms about the equivalence of data properties, + i.e. `EquivalentProperties` statements. + +If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner +will infer `Student EquivalentProperties: identifier, enrollmentNumber`.""" + +DATA_PROP_SUB_DESC = """The reasoner will infer axioms about the hierarchy of data properties, i.e. +`SubPropertyOf:` statements. + +If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that +`studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: +studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`.""" @Plugin( label="Reason", @@ -87,43 +115,43 @@ PluginParameter( param_type=BoolParameterType(), name="sub_class", - label="SubClass", + label="Class inclusion (`rdfs:subClassOf`)", description=SUBCLASS_DESC, - default_value=True, + default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="equivalent_class", - label="EquivalentClass", + label="Class equivalence (`owl:equivalentClass`)", description=EQUIVALENCE_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="disjoint_classes", - label="DisjointClasses", + label="Class disjointness (`owl:disjointWith`) ", description=DISJOINT_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="data_property_characteristic", - label="DataPropertyCharacteristic", - description="", + label="Data property characteristics (Axiomatic triples) ", + description=DATA_PROP_CHAR_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="equivalent_data_properties", - label="EquivalentDataProperties", - description="", + label="Data property equivalence (`owl:equivalentDataProperty`) ", + description=DATA_PROP_EQUIV_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="sub_data_property", - label="SubDataProperty", - description="", + label="Data property inclusion (`rdfs:subPropertyOf`)", + description=DATA_PROP_SUB_DESC, default_value=False, ), PluginParameter( @@ -131,14 +159,14 @@ name="class_assertion", label="ClassAssertion", description="", - default_value=False, + default_value=True, ), PluginParameter( param_type=BoolParameterType(), name="property_assertion", label="PropertyAssertion", description="", - default_value=False, + default_value=True, ), PluginParameter( param_type=BoolParameterType(), From c812dd1b476dee93aa000ef94f36e865422802ba Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Thu, 22 Aug 2024 13:41:58 +0200 Subject: [PATCH 10/28] Add description for individual axiom generators --- cmem_plugin_reason/plugin_reason.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index dbde3c7..e76fe71 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -76,6 +76,24 @@ `studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`.""" +CLASS_ASSERT_DESC = """The reasoner will infer assertions about the classes of individuals, i.e. +`Types:` statements. + +Assume, there are classes `Person`, `Student` and `University` as well a the property `enrolledIn`, +such that `Student EquivalentTo: Person and enrolledIn some University` holds. For the individual +`John` with the assertions `John Types: Person; Facts: enrolledIn LeipzigUniversity`, the reasoner +will infer `John Types: Student`. +""" + +PROPERTY_ASSERT_DESC = """The reasoner will infer assertions about the properties of individuals, +i.e. `Facts:` statements. + +Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: +enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the +assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers +KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. +""" + @Plugin( label="Reason", icon=Icon(file_name="fluent--brain-circuit-24-regular.svg", package=__package__), @@ -157,15 +175,15 @@ PluginParameter( param_type=BoolParameterType(), name="class_assertion", - label="ClassAssertion", - description="", + label="Class assertions (`rdf:type`)", + description=CLASS_ASSERT_DESC, default_value=True, ), PluginParameter( param_type=BoolParameterType(), name="property_assertion", - label="PropertyAssertion", - description="", + label="Property assertions", + description=PROPERTY_ASSERT_DESC, default_value=True, ), PluginParameter( From c688f9f955a80b07185d6d6d1c4c30627eec77f0 Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Thu, 22 Aug 2024 17:03:30 +0200 Subject: [PATCH 11/28] Add description for object property characteristics --- cmem_plugin_reason/plugin_reason.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index e76fe71..95d3352 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -94,6 +94,16 @@ KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. """ +OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e +`Characteristics:` statements. + +If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn +SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will +infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact +nor in HermiT!** +""" + + @Plugin( label="Reason", icon=Icon(file_name="fluent--brain-circuit-24-regular.svg", package=__package__), @@ -203,8 +213,8 @@ PluginParameter( param_type=BoolParameterType(), name="object_property_characteristic", - label="ObjectPropertyCharacteristic", - description="", + label="Object property characteristic (Axiomatic triples)", + description=OBJECT_PROP_CHAR_DESC, default_value=False, ), PluginParameter( From 70fa1a1af09a75e8d5e037a7038dfde19508a1e7 Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Fri, 23 Aug 2024 13:36:59 +0200 Subject: [PATCH 12/28] Complete axiom generator descriptions --- cmem_plugin_reason/plugin_reason.py | 149 ++++++++++++++++++---------- 1 file changed, 97 insertions(+), 52 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index 95d3352..cc7bc1e 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -35,74 +35,119 @@ validate_profiles, ) -SUBCLASS_DESC = """The reasoner will infer assertions about the hierarchy of classes, i.e. -`SubClassOf:` statements. +SUBCLASS_DESC = """The reasoner will infer assertions about the hierarchy of classes, i.e. +`SubClassOf:` statements. -If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`.""" +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. +""" -EQUIVALENCE_DESC = """The reasoner will infer assertions about the equivalence of classes, i.e. -`EquivalentTo:` statements. +EQUIVALENCE_DESC = """The reasoner will infer assertions about the equivalence of classes, i.e. +`EquivalentTo:` statements. -If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. """ -DISJOINT_DESC = """The reasoner will infer assertions about the disjointness of classes, i.e. -`DisjointClasses:` statements. +DISJOINT_DESC = """The reasoner will infer assertions about the disjointness of classes, i.e. +`DisjointClasses:` statements. -If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -Student, Professor` holds, the reasoner will infer `Student DisjointClasses: Student, Professor` +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Student DisjointClasses: Student, Professor`. """ -DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. +DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. `Characteristics:` statements. For data properties, this only pertains to functionality. -If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber -SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will -infer `enrollmentNumber Characteristics: Functional`.""" +If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will +infer `enrollmentNumber Characteristics: Functional`. +""" DATA_PROP_EQUIV_DESC = """The reasoner will infer axioms about the equivalence of data properties, i.e. `EquivalentProperties` statements. -If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber -SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner -will infer `Student EquivalentProperties: identifier, enrollmentNumber`.""" +If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner +will infer `Student EquivalentProperties: identifier, enrollmentNumber`. +""" -DATA_PROP_SUB_DESC = """The reasoner will infer axioms about the hierarchy of data properties, i.e. -`SubPropertyOf:` statements. +DATA_PROP_SUB_DESC = """The reasoner will infer axioms about the hierarchy of data properties, +i.e. `SubPropertyOf:` statements. -If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that -`studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: -studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`.""" +If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that +`studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: +studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. +""" -CLASS_ASSERT_DESC = """The reasoner will infer assertions about the classes of individuals, i.e. -`Types:` statements. +CLASS_ASSERT_DESC = """The reasoner will infer assertions about the classes of individuals, i.e. +`Types:` statements. -Assume, there are classes `Person`, `Student` and `University` as well a the property `enrolledIn`, -such that `Student EquivalentTo: Person and enrolledIn some University` holds. For the individual -`John` with the assertions `John Types: Person; Facts: enrolledIn LeipzigUniversity`, the reasoner -will infer `John Types: Student`. +Assume, there are classes `Person`, `Student` and `University` as well a the property +`enrolledIn`, such that `Student EquivalentTo: Person and enrolledIn some University` holds. For +the individual `John` with the assertions `John Types: Person; Facts: enrolledIn +LeipzigUniversity`, the reasoner will infer `John Types: Student`. """ -PROPERTY_ASSERT_DESC = """The reasoner will infer assertions about the properties of individuals, -i.e. `Facts:` statements. +PROPERTY_ASSERT_DESC = """The reasoner will infer assertions about the properties of individuals, +i.e. `Facts:` statements. -Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: -enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the -assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers +Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: +enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the +assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. """ -OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e -`Characteristics:` statements. +OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e. +`Characteristics:` statements. -If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn -SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will -infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact +If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn +SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will +infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact nor in HermiT!** """ +OBJECT_PROP_EQUIV_DESC = """The reasoner will infer assertions about the equivalence of object +properties, i.e. `EquivalentTo:` statements. + +If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that +`hasAlternativeLecture Characteristics: Symmetric` and `hasSameTopicAs InverseOf: +hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: hasAlternativeLecture, +hasSameTopicAs`. +""" + +OBJECT_PROP_SUB_DESC = """The reasoner will infer axioms about the inclusion of object properties, +i.e. `SubPropertyOf:` statements. + +If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn +SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reasoner will infer +`hasStudent SubPropertyOf: inverse (studentOf)`. +""" + +OBJECT_PROP_INV_DESC = """The reasoner will infer axioms about the inversion about object +properties, i.e. `InverseOf:` statements. + +If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture +Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLecture InverseOf: +hasAlternativeLecture`. +""" + +OBJECT_PROP_RANGE_DESC = """The reasoner will infer axioms about the ranges of object properties, +i.e. `Range:` statements. + +If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and +`enrolledIn`, such that `hasStudent Range: Student and enrolledIn some Lecture` holds, the +reasoner will infer `hasStudent Range: Student`. +""" + +OBJECT_PROP_DOMAIN_DESC = """The reasoner will infer axioms about the domains of object +properties, i.e. `Domain:` statements. + +If there are classes `Person`, `Student` and `Professor` as wells as the object property +`hasRoleIn`, such that `Professor SubClassOf: Person`, `Student SubClassOf: Person` and +`hasRoleIn Domain: Professor or Student` holds, the reasoner will infer `hasRoleIn Domain: Person`. +""" + @Plugin( label="Reason", @@ -157,21 +202,21 @@ PluginParameter( param_type=BoolParameterType(), name="disjoint_classes", - label="Class disjointness (`owl:disjointWith`) ", + label="Class disjointness (`owl:disjointWith`)", description=DISJOINT_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="data_property_characteristic", - label="Data property characteristics (Axiomatic triples) ", + label="Data property characteristics (Axiomatic triples)", description=DATA_PROP_CHAR_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="equivalent_data_properties", - label="Data property equivalence (`owl:equivalentDataProperty`) ", + label="Data property equivalence (`owl:equivalentDataProperty`)", description=DATA_PROP_EQUIV_DESC, default_value=False, ), @@ -199,15 +244,15 @@ PluginParameter( param_type=BoolParameterType(), name="equivalent_object_property", - label="EquivalentObjectProperty", - description="", + label="Object property equivalence (`owl:equivalentProperty`)", + description=OBJECT_PROP_EQUIV_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="inverse_object_properties", - label="InverseObjectProperties", - description="", + label="Object property inversion (`owl:inverseOf`)", + description=OBJECT_PROP_INV_DESC, default_value=False, ), PluginParameter( @@ -220,22 +265,22 @@ PluginParameter( param_type=BoolParameterType(), name="sub_object_property", - label="SubObjectProperty", - description="", + label="Object property inclusion (`rdfs:subPropertyOf`)", + description=OBJECT_PROP_SUB_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="object_property_range", - label="ObjectPropertyRange", - description="", + label="Object property ranges (`rdfs:range`)", + description=OBJECT_PROP_RANGE_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="object_property_domain", - label="ObjectPropertyDomain", - description="", + label="Object property domains (`rdfs:domain`)", + description=OBJECT_PROP_DOMAIN_DESC, default_value=False, ), PluginParameter( From cafee72dd6886c448fc0f9a0df252fc8d043d0b1 Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Fri, 23 Aug 2024 13:49:26 +0200 Subject: [PATCH 13/28] Fix incorrect axiom example --- cmem_plugin_reason/plugin_reason.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index cc7bc1e..d224cbc 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -53,7 +53,7 @@ `DisjointClasses:` statements. If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -Student, Professor` holds, the reasoner will infer `Student DisjointClasses: Student, Professor`. +Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. """ DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. From 73a6a65de01d6b8a1c97d990cc687310cd20b51d Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Fri, 23 Aug 2024 14:16:48 +0200 Subject: [PATCH 14/28] Remove unused markdown --- cmem_plugin_reason/plugin_reason.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index d224cbc..83213b8 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -188,21 +188,21 @@ PluginParameter( param_type=BoolParameterType(), name="sub_class", - label="Class inclusion (`rdfs:subClassOf`)", + label="Class inclusion (rdfs:subClassOf)", description=SUBCLASS_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="equivalent_class", - label="Class equivalence (`owl:equivalentClass`)", + label="Class equivalence (owl:equivalentClass)", description=EQUIVALENCE_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="disjoint_classes", - label="Class disjointness (`owl:disjointWith`)", + label="Class disjointness (owl:disjointWith)", description=DISJOINT_DESC, default_value=False, ), @@ -216,21 +216,21 @@ PluginParameter( param_type=BoolParameterType(), name="equivalent_data_properties", - label="Data property equivalence (`owl:equivalentDataProperty`)", + label="Data property equivalence (owl:equivalentDataProperty)", description=DATA_PROP_EQUIV_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="sub_data_property", - label="Data property inclusion (`rdfs:subPropertyOf`)", + label="Data property inclusion (rdfs:subPropertyOf)", description=DATA_PROP_SUB_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="class_assertion", - label="Class assertions (`rdf:type`)", + label="Class assertions (rdf:type)", description=CLASS_ASSERT_DESC, default_value=True, ), @@ -244,14 +244,14 @@ PluginParameter( param_type=BoolParameterType(), name="equivalent_object_property", - label="Object property equivalence (`owl:equivalentProperty`)", + label="Object property equivalence (owl:equivalentProperty)", description=OBJECT_PROP_EQUIV_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="inverse_object_properties", - label="Object property inversion (`owl:inverseOf`)", + label="Object property inversion (owl:inverseOf)", description=OBJECT_PROP_INV_DESC, default_value=False, ), @@ -265,21 +265,21 @@ PluginParameter( param_type=BoolParameterType(), name="sub_object_property", - label="Object property inclusion (`rdfs:subPropertyOf`)", + label="Object property inclusion (rdfs:subPropertyOf)", description=OBJECT_PROP_SUB_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="object_property_range", - label="Object property ranges (`rdfs:range`)", + label="Object property ranges (rdfs:range)", description=OBJECT_PROP_RANGE_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="object_property_domain", - label="Object property domains (`rdfs:domain`)", + label="Object property domains (rdfs:domain)", description=OBJECT_PROP_DOMAIN_DESC, default_value=False, ), From c2f5692ec65f57b1d1933a5829836ee17b30d005 Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Fri, 23 Aug 2024 14:31:33 +0200 Subject: [PATCH 15/28] Refine naming and order --- cmem_plugin_reason/plugin_reason.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index 83213b8..ac24b6e 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -230,14 +230,14 @@ PluginParameter( param_type=BoolParameterType(), name="class_assertion", - label="Class assertions (rdf:type)", + label="Individual class assertions (rdf:type)", description=CLASS_ASSERT_DESC, default_value=True, ), PluginParameter( param_type=BoolParameterType(), name="property_assertion", - label="Property assertions", + label="Individual property assertions", description=PROPERTY_ASSERT_DESC, default_value=True, ), @@ -329,20 +329,20 @@ def __init__( # noqa: PLR0913 C901 ontology_graph_iri: str, output_graph_iri: str, reasoner: str, - class_assertion: bool = False, - data_property_characteristic: bool = False, - disjoint_classes: bool = False, + class_assertion: bool = True, + property_assertion: bool = True, + sub_class: bool = False, equivalent_class: bool = False, - equivalent_data_properties: bool = False, + disjoint_classes: bool = False, + sub_object_property: bool = False, equivalent_object_property: bool = False, - inverse_object_properties: bool = False, object_property_characteristic: bool = False, object_property_domain: bool = False, object_property_range: bool = False, - property_assertion: bool = False, - sub_class: bool = True, + inverse_object_properties: bool = False, sub_data_property: bool = False, - sub_object_property: bool = False, + equivalent_data_properties: bool = False, + data_property_characteristic: bool = False, validate_profile: bool = False, import_ontology: bool = True, import_result: bool = False, From 1357ede49217585792181e63cc58787304941242 Mon Sep 17 00:00:00 2001 From: Sebastian Siemoleit Date: Fri, 23 Aug 2024 15:40:08 +0200 Subject: [PATCH 16/28] Fix smaller errors --- cmem_plugin_reason/plugin_reason.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index ac24b6e..a4f57a6 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -83,7 +83,7 @@ CLASS_ASSERT_DESC = """The reasoner will infer assertions about the classes of individuals, i.e. `Types:` statements. -Assume, there are classes `Person`, `Student` and `University` as well a the property +Assume, there are classes `Person`, `Student` and `University` as well as the property `enrolledIn`, such that `Student EquivalentTo: Person and enrolledIn some University` holds. For the individual `John` with the assertions `John Types: Person; Facts: enrolledIn LeipzigUniversity`, the reasoner will infer `John Types: Student`. @@ -216,7 +216,7 @@ PluginParameter( param_type=BoolParameterType(), name="equivalent_data_properties", - label="Data property equivalence (owl:equivalentDataProperty)", + label="Data property equivalence (owl:equivalentProperty)", description=DATA_PROP_EQUIV_DESC, default_value=False, ), @@ -336,13 +336,16 @@ def __init__( # noqa: PLR0913 C901 disjoint_classes: bool = False, sub_object_property: bool = False, equivalent_object_property: bool = False, - object_property_characteristic: bool = False, +# This axiom generator does not yield any results. +# TODO: Create issue in github +# object_property_characteristic: bool = False, object_property_domain: bool = False, object_property_range: bool = False, inverse_object_properties: bool = False, sub_data_property: bool = False, equivalent_data_properties: bool = False, - data_property_characteristic: bool = False, +# Removing it, because the object property counterpart does not work +# data_property_characteristic: bool = False, validate_profile: bool = False, import_ontology: bool = True, import_result: bool = False, From d9f71af4e96e1d518fcbee12be2664565e05b75c Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 09:49:20 +0100 Subject: [PATCH 17/28] add detailed axiom generator description, remove non-working axiom generator EquivaletObjectProperty and its (working) counterpart EquivalentDataProperties --- CHANGELOG.md | 7 ++ README.md | 115 ++++++++++++++++++++----- cmem_plugin_reason/doc/reason_doc.md | 113 ++++++++++++++++++++---- cmem_plugin_reason/doc/validate_doc.md | 3 +- cmem_plugin_reason/plugin_reason.py | 80 ++++++++--------- cmem_plugin_reason/plugin_validate.py | 9 +- poetry.lock | 95 ++++++++++---------- pyproject.toml | 1 + tests/test_reason.py | 2 + 9 files changed, 295 insertions(+), 130 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 782920f..be7069f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Validate: added "mode" parameter +### Changed + + - Validate: the entity output includes the reasoner option on path "reason" + - Detailed axiom generator documentation + - The axiom generator EquivalentobjectProperty does not yield results possibly due to a bug in the OWL API. Currently, +this axiom generator and its (working) counterpart EquivalentDataProperties are removed from the Reason plugin. + ## [1.0.0beta5] 2024-08-15 ### Added diff --git a/README.md b/README.md index d491540..4f26733 100644 --- a/README.md +++ b/README.md @@ -61,26 +61,100 @@ By default, the reason operation will only assert inferred subclass axioms. The parameters to include inferred axiom generators: #### Class axiom generators -- SubClass -- EquivalentClass -- DisjointClasses - -#### Data property axiom generators -- DataPropertyCharacteristic -- EquivalentDataProperties -- SubDataProperty +- **SubClass** +The reasoner will infer assertions about the hierarchy of classes, i.e. +`SubClassOf:` statements. +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. + + +- **EquivalentClass** +The reasoner will infer assertions about the equivalence of classes, i.e. +`EquivalentTo:` statements. +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. + + +- **DisjointClasses** +The reasoner will infer assertions about the disjointness of classes, i.e. +`DisjointClasses:` statements. +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. + + +- **EquivalentDataProperties** +The reasoner will infer axioms about the equivalence of data properties, + i.e. `EquivalentProperties` statements. +If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner +will infer `Student EquivalentProperties: identifier, enrollmentNumber`. + + +- **SubDataProperty** +The reasoner will infer axioms about the hierarchy of data properties, +i.e. `SubPropertyOf:` statements. +If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that +`studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: +studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. #### Individual axiom generators -- ClassAssertion -- PropertyAssertion +- **ClassAssertion** +The reasoner will infer assertions about the classes of individuals, i.e. +`Types:` statements. +Assume, there are classes `Person`, `Student` and `University` as well as the property +`enrolledIn`, such that `Student EquivalentTo: Person and enrolledIn some University` holds. For +the individual `John` with the assertions `John Types: Person; Facts: enrolledIn +LeipzigUniversity`, the reasoner will infer `John Types: Student`. + + +- **PropertyAssertion** +The reasoner will infer assertions about the properties of individuals, +i.e. `Facts:` statements. +Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: +enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the +assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers +KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. #### Object property axiom generators -- EquivalentObjectProperty -- InverseObjectProperties -- ObjectPropertyCharacteristic -- SubObjectProperty -- ObjectPropertyRange -- ObjectPropertyDomain +- **EquivalentObjectProperty** +The reasoner will infer assertions about the equivalence of object +properties, i.e. `EquivalentTo:` statements. +If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that +`hasAlternativeLecture Characteristics: Symmetric` and `hasSameTopicAs InverseOf: +hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: hasAlternativeLecture, +hasSameTopicAs`. + + +- **InverseObjectProperties** +The reasoner will infer axioms about the inversion about object +properties, i.e. `InverseOf:` statements. +If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture +Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLecture InverseOf: +hasAlternativeLecture`. + + +- **SubObjectProperty** +The reasoner will infer axioms about the inclusion of object properties, +i.e. `SubPropertyOf:` statements. +If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn +SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reasoner will infer +`hasStudent SubPropertyOf: inverse (studentOf)`. + + +- **ObjectPropertyRange** +The reasoner will infer axioms about the ranges of object properties, +i.e. `Range:` statements. +If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and +`enrolledIn`, such that `hasStudent Range: Student and enrolledIn some Lecture` holds, the +reasoner will infer `hasStudent Range: Student`. + + +- **ObjectPropertyDomain** +The reasoner will infer axioms about the domains of object +properties, i.e. `Domain:` statements. +If there are classes `Person`, `Student` and `Professor` as wells as the object property +`hasRoleIn`, such that `Professor SubClassOf: Person`, `Student SubClassOf: Person` and +`hasRoleIn Domain: Professor or Student` holds, the reasoner will infer `hasRoleIn Domain: Person`. ### Validate OWL2 profiles @@ -88,9 +162,9 @@ Validate the input ontology against OWL profiles (DL, EL, QL, RL, and Full) and ### Process valid OWL profiles from input -If enabled along with the "Validate OWL2 profiles" parameter, the valid profiles and ontology IRI is taken from the -config port input (parameters "valid_profiles" and "ontology_graph_iri") instead of from running the validation in the -plugin. The valid profiles input is a comma-separated string (e.g. "Full,DL"). +If enabled along with the "Validate OWL2 profiles" parameter, the valid profiles, ontology IRI and reasoner option is +taken from the config port input (parameters "valid_profiles", "ontology_graph_iri" and "reasoner") and the OWL2 +profiles validation is not done in the plugin. The valid profiles input is a comma-separated string (e.g. "Full,DL"). ### Add ontology graph import to result graph @@ -162,7 +236,8 @@ Validate the input ontology against OWL profiles (DL, EL, QL, RL, and Full) and ### Output entities Output entities. The plugin outputs the explanation as text in Markdown format on the path "markdown", the ontology IRI -on the path "ontology_graph_iri", and, if enabled, the valid OWL2 profiles on the path "valid_profiles +on the path "ontology_graph_iri", the reasoner option on the path "reasoner", and, if enabled, the valid OWL2 profiles +on the path "valid_profiles". ### Maximum RAM Percentage diff --git a/cmem_plugin_reason/doc/reason_doc.md b/cmem_plugin_reason/doc/reason_doc.md index f6a7b09..e203aba 100644 --- a/cmem_plugin_reason/doc/reason_doc.md +++ b/cmem_plugin_reason/doc/reason_doc.md @@ -33,26 +33,101 @@ By default, the reason operation will only assert inferred subclass axioms. The parameters to include inferred axiom generators: #### Class axiom generators -- SubClass -- EquivalentClass -- DisjointClasses - -#### Data property axiom generators -- DataPropertyCharacteristic -- EquivalentDataProperties -- SubDataProperty +- **SubClass** +The reasoner will infer assertions about the hierarchy of classes, i.e. +`SubClassOf:` statements. +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. + + +- **EquivalentClass** +The reasoner will infer assertions about the equivalence of classes, i.e. +`EquivalentTo:` statements. +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. + + +- **DisjointClasses** +The reasoner will infer assertions about the disjointness of classes, i.e. +`DisjointClasses:` statements. +If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. + + +- **EquivalentDataProperties** +The reasoner will infer axioms about the equivalence of data properties, + i.e. `EquivalentProperties` statements. +If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner +will infer `Student EquivalentProperties: identifier, enrollmentNumber`. + + +- **SubDataProperty** +The reasoner will infer axioms about the hierarchy of data properties, +i.e. `SubPropertyOf:` statements. +If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that +`studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: +studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. #### Individual axiom generators -- ClassAssertion -- PropertyAssertion +- **ClassAssertion** +The reasoner will infer assertions about the classes of individuals, i.e. +`Types:` statements. +Assume, there are classes `Person`, `Student` and `University` as well as the property +`enrolledIn`, such that `Student EquivalentTo: Person and enrolledIn some University` holds. For +the individual `John` with the assertions `John Types: Person; Facts: enrolledIn +LeipzigUniversity`, the reasoner will infer `John Types: Student`. + + +- **PropertyAssertion** +The reasoner will infer assertions about the properties of individuals, +i.e. `Facts:` statements. +Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: +enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the +assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers +KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. #### Object property axiom generators -- EquivalentObjectProperty -- InverseObjectProperties -- ObjectPropertyCharacteristic -- SubObjectProperty -- ObjectPropertyRange -- ObjectPropertyDomain +- **EquivalentObjectProperty** +The reasoner will infer assertions about the equivalence of object +properties, i.e. `EquivalentTo:` statements. +If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that +`hasAlternativeLecture Characteristics: Symmetric` and `hasSameTopicAs InverseOf: +hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: hasAlternativeLecture, +hasSameTopicAs`. + + +- **InverseObjectProperties** +The reasoner will infer axioms about the inversion about object +properties, i.e. `InverseOf:` statements. +If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture +Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLecture InverseOf: +hasAlternativeLecture`. + + +- **SubObjectProperty** +The reasoner will infer axioms about the inclusion of object properties, +i.e. `SubPropertyOf:` statements. +If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn +SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reasoner will infer +`hasStudent SubPropertyOf: inverse (studentOf)`. + + +- **ObjectPropertyRange** +The reasoner will infer axioms about the ranges of object properties, +i.e. `Range:` statements. +If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and +`enrolledIn`, such that `hasStudent Range: Student and enrolledIn some Lecture` holds, the +reasoner will infer `hasStudent Range: Student`. + + +- **ObjectPropertyDomain** +The reasoner will infer axioms about the domains of object +properties, i.e. `Domain:` statements. +If there are classes `Person`, `Student` and `Professor` as wells as the object property +`hasRoleIn`, such that `Professor SubClassOf: Person`, `Student SubClassOf: Person` and +`hasRoleIn Domain: Professor or Student` holds, the reasoner will infer `hasRoleIn Domain: Person`. + ### Validate OWL2 profiles @@ -60,9 +135,9 @@ Validate the input ontology against OWL profiles (DL, EL, QL, RL, and Full) and ### Process valid OWL profiles from input -If enabled along with the "Validate OWL2 profiles" parameter, the valid profiles and ontology IRI is taken from the -config port input (parameters "valid_profiles" and "ontology_graph_iri") instead of from running the validation in the -plugin. The valid profiles input is a comma-separated string (e.g. "Full,DL"). +If enabled along with the "Validate OWL2 profiles" parameter, the valid profiles, ontology IRI and reasoner option is +taken from the config port input (parameters "valid_profiles", "ontology_graph_iri" and "reasoner") and the OWL2 +profiles validation is not done in the plugin. The valid profiles input is a comma-separated string (e.g. "Full,DL"). ### Add ontology graph import to result graph diff --git a/cmem_plugin_reason/doc/validate_doc.md b/cmem_plugin_reason/doc/validate_doc.md index 11a584b..3cc4ba3 100644 --- a/cmem_plugin_reason/doc/validate_doc.md +++ b/cmem_plugin_reason/doc/validate_doc.md @@ -52,7 +52,8 @@ Mode _unsatisfiability_ generates explanations for many unsatisfiable classes at ### Output entities Output entities. The plugin outputs the explanation as text in Markdown format on the path "markdown", the ontology IRI -on the path "ontology_graph_iri", and, if enabled, the valid OWL2 profiles on the path "valid_profiles +on the path "ontology_graph_iri", the reasoner option on the path "reasoner", and, if enabled, the valid OWL2 profiles +on the path "valid_profiles". ### Maximum RAM Percentage diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index a4f57a6..290f116 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -56,13 +56,13 @@ Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. """ -DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. -`Characteristics:` statements. For data properties, this only pertains to functionality. - -If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber -SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will -infer `enrollmentNumber Characteristics: Functional`. -""" +# DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. +# `Characteristics:` statements. For data properties, this only pertains to functionality. +# +# If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +# SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will +# infer `enrollmentNumber Characteristics: Functional`. +# """ DATA_PROP_EQUIV_DESC = """The reasoner will infer axioms about the equivalence of data properties, i.e. `EquivalentProperties` statements. @@ -98,14 +98,14 @@ KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. """ -OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e. -`Characteristics:` statements. - -If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn -SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will -infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact -nor in HermiT!** -""" +# OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e. +# `Characteristics:` statements. +# +# If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn +# SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will +# infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact +# nor in HermiT!** +# """ OBJECT_PROP_EQUIV_DESC = """The reasoner will infer assertions about the equivalence of object properties, i.e. `EquivalentTo:` statements. @@ -206,13 +206,13 @@ description=DISJOINT_DESC, default_value=False, ), - PluginParameter( - param_type=BoolParameterType(), - name="data_property_characteristic", - label="Data property characteristics (Axiomatic triples)", - description=DATA_PROP_CHAR_DESC, - default_value=False, - ), + # PluginParameter( + # param_type=BoolParameterType(), + # name="data_property_characteristic", + # label="Data property characteristics (Axiomatic triples)", + # description=DATA_PROP_CHAR_DESC, + # default_value=False, + # ), PluginParameter( param_type=BoolParameterType(), name="equivalent_data_properties", @@ -255,13 +255,13 @@ description=OBJECT_PROP_INV_DESC, default_value=False, ), - PluginParameter( - param_type=BoolParameterType(), - name="object_property_characteristic", - label="Object property characteristic (Axiomatic triples)", - description=OBJECT_PROP_CHAR_DESC, - default_value=False, - ), + # PluginParameter( + # param_type=BoolParameterType(), + # name="object_property_characteristic", + # label="Object property characteristic (Axiomatic triples)", + # description=OBJECT_PROP_CHAR_DESC, + # default_value=False, + # ), PluginParameter( param_type=BoolParameterType(), name="sub_object_property", @@ -288,9 +288,10 @@ name="input_profiles", label="Process valid OWL profiles from input", description="""If enabled along with the "Validate OWL2 profiles" parameter, the valid - profiles and ontology IRI is taken from the config port input (parameters - "valid_profiles" and "ontology_graph_iri") instead of from running the validation in the - plugin. The valid profiles input is a comma-separated string (e.g. "Full,DL").""", + profiles, ontology IRI and reasoner option is taken from the config port input + (parameters "valid_profiles", "ontology_graph_iri" and "reasoner") and the OWL2 profiles + validation is not done in the plugin. The valid profiles input is a comma-separated + string (e.g. "Full,DL").""", default_value=False, advanced=True, ), @@ -336,16 +337,17 @@ def __init__( # noqa: PLR0913 C901 disjoint_classes: bool = False, sub_object_property: bool = False, equivalent_object_property: bool = False, -# This axiom generator does not yield any results. -# TODO: Create issue in github -# object_property_characteristic: bool = False, + # This axiom generator does not yield any results. + # TODO: Create issue in github # noqa: TD002 + # https://github.com/eccenca/cmem-plugin-reason/issues/10 + # object_property_characteristic: bool = False, object_property_domain: bool = False, object_property_range: bool = False, inverse_object_properties: bool = False, sub_data_property: bool = False, equivalent_data_properties: bool = False, -# Removing it, because the object property counterpart does not work -# data_property_characteristic: bool = False, + # Removed because the object property counterpart does not work + # data_property_characteristic: bool = False, validate_profile: bool = False, import_ontology: bool = True, import_result: bool = False, @@ -357,14 +359,14 @@ def __init__( # noqa: PLR0913 C901 "SubClass": sub_class, "EquivalentClass": equivalent_class, "DisjointClasses": disjoint_classes, - "DataPropertyCharacteristic": data_property_characteristic, + # "DataPropertyCharacteristic": data_property_characteristic, "EquivalentDataProperties": equivalent_data_properties, "SubDataProperty": sub_data_property, "ClassAssertion": class_assertion, "PropertyAssertion": property_assertion, "EquivalentObjectProperty": equivalent_object_property, "InverseObjectProperties": inverse_object_properties, - "ObjectPropertyCharacteristic": object_property_characteristic, + # "ObjectPropertyCharacteristic": object_property_characteristic, "SubObjectProperty": sub_object_property, "ObjectPropertyRange": object_property_range, "ObjectPropertyDomain": object_property_domain, diff --git a/cmem_plugin_reason/plugin_validate.py b/cmem_plugin_reason/plugin_validate.py index 62c3eb4..3483480 100644 --- a/cmem_plugin_reason/plugin_validate.py +++ b/cmem_plugin_reason/plugin_validate.py @@ -85,8 +85,9 @@ name="output_entities", label="Output entities", description="""Output entities. The plugin outputs the explanation as text in Markdown - format on the path "markdown", the ontology IRI on the path "ontology_graph_iri", and, - if enabled, the valid OWL2 profiles on the path "valid_profiles".""", + format on the path "markdown", the ontology IRI on the path "ontology_graph_iri", the + reasoner option on the path "reasoner", and, if enabled, the valid OWL2 profiles on the + path "valid_profiles".""", default_value=False, ), PluginParameter( @@ -165,7 +166,7 @@ def __init__( # noqa: PLR0912 PLR0913 C901 def generate_output_schema(self) -> EntitySchema | None: """Generate output entity schema.""" - paths = [EntityPath("markdown"), EntityPath("ontology_graph_iri")] + paths = [EntityPath("markdown"), EntityPath("ontology_graph_iri"), EntityPath("reasoner")] if self.validate_profile: paths.append(EntityPath("valid_profiles")) return EntitySchema(type_uri="validate", paths=paths) @@ -227,7 +228,7 @@ def add_profiles(self, valid_profiles: list) -> list: def make_entities(self, text: str, valid_profiles: list) -> Entities: """Make entities""" - values = [[text], [self.ontology_graph_iri]] + values = [[text], [self.ontology_graph_iri], [self.reasoner]] if self.validate_profile: values.append([",".join(valid_profiles)]) entities = [ diff --git a/poetry.lock b/poetry.lock index 4669b19..4899fc0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -307,13 +307,13 @@ tests = ["defusedxml"] [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -574,38 +574,38 @@ test = ["Cython", "greenlet", "ipython", "pytest", "pytest-cov", "pytest-textual [[package]] name = "mypy" -version = "1.11.1" +version = "1.11.2" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, - {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, - {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, - {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, - {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, - {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, - {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, - {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, - {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, - {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, - {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, - {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, - {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, - {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, - {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, - {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, - {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, - {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, - {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, + {file = "mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a"}, + {file = "mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef"}, + {file = "mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383"}, + {file = "mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8"}, + {file = "mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7"}, + {file = "mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385"}, + {file = "mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca"}, + {file = "mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104"}, + {file = "mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4"}, + {file = "mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6"}, + {file = "mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318"}, + {file = "mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36"}, + {file = "mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987"}, + {file = "mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca"}, + {file = "mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70"}, + {file = "mypy-1.11.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b"}, + {file = "mypy-1.11.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86"}, + {file = "mypy-1.11.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce"}, + {file = "mypy-1.11.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1"}, + {file = "mypy-1.11.2-cp38-cp38-win_amd64.whl", hash = "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b"}, + {file = "mypy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6"}, + {file = "mypy-1.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70"}, + {file = "mypy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"}, + {file = "mypy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d"}, + {file = "mypy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24"}, + {file = "mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12"}, + {file = "mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79"}, ] [package.dependencies] @@ -642,18 +642,19 @@ files = [ [[package]] name = "pathvalidate" -version = "3.2.0" +version = "3.2.1" description = "pathvalidate is a Python library to sanitize/validate a string such as filenames/file-paths/etc." optional = false python-versions = ">=3.7" files = [ - {file = "pathvalidate-3.2.0-py3-none-any.whl", hash = "sha256:cc593caa6299b22b37f228148257997e2fa850eea2daf7e4cc9205cef6908dee"}, - {file = "pathvalidate-3.2.0.tar.gz", hash = "sha256:5e8378cf6712bff67fbe7a8307d99fa8c1a0cb28aa477056f8fc374f0dff24ad"}, + {file = "pathvalidate-3.2.1-py3-none-any.whl", hash = "sha256:9a6255eb8f63c9e2135b9be97a5ce08f10230128c4ae7b3e935378b82b22c4c9"}, + {file = "pathvalidate-3.2.1.tar.gz", hash = "sha256:f5d07b1e2374187040612a1fcd2bcb2919f8db180df254c9581bb90bf903377d"}, ] [package.extras] docs = ["Sphinx (>=2.4)", "sphinx-rtd-theme (>=1.2.2)", "urllib3 (<2)"] -test = ["Faker (>=1.0.8)", "allpairspy (>=2)", "click (>=6.2)", "pytest (>=6.0.1)", "pytest-discord (>=0.1.4)", "pytest-md-report (>=0.4.1)"] +readme = ["path (>=13,<17)", "readmemaker (>=1.1.0)"] +test = ["Faker (>=1.0.8)", "allpairspy (>=2)", "click (>=6.2)", "pytest (>=6.0.1)", "pytest-md-report (>=0.6.2)"] [[package]] name = "pillow" @@ -794,13 +795,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.1.4" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] [package.extras] @@ -1064,19 +1065,19 @@ setuptools = "*" [[package]] name = "setuptools" -version = "72.2.0" +version = "73.0.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-72.2.0-py3-none-any.whl", hash = "sha256:f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4"}, - {file = "setuptools-72.2.0.tar.gz", hash = "sha256:80aacbf633704e9c8bfa1d99fa5dd4dc59573efcf9e4042c13d3bcef91ac2ef9"}, + {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, + {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] [[package]] name = "six" @@ -1091,13 +1092,13 @@ files = [ [[package]] name = "textual" -version = "0.76.0" +version = "0.77.0" description = "Modern Text User Interface framework" optional = false python-versions = "<4.0.0,>=3.8.1" files = [ - {file = "textual-0.76.0-py3-none-any.whl", hash = "sha256:e2035609c889dba507d34a5d7b333f1c8c53a29fb170962cb92101507663517a"}, - {file = "textual-0.76.0.tar.gz", hash = "sha256:b12e8879d591090c0901b5cb8121d086e28e677353b368292d3865ec99b83b70"}, + {file = "textual-0.77.0-py3-none-any.whl", hash = "sha256:f117d29ddf9764c8969d1ac23724a7bd8cfe9111e158f2355d8a0e5ad10f5bd7"}, + {file = "textual-0.77.0.tar.gz", hash = "sha256:866c1e18e87b2817ce08e09259224b771caaf8824988c4c717094c6bf106b20f"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 42d9f3b..6f58d99 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -96,5 +96,6 @@ ignore = [ "PD", # opinionated linting for pandas code "S101", # use of assert detected "TRY003", # Avoid specifying long messages outside the exception class + "ERA001", # Found commented-out code ] diff --git a/tests/test_reason.py b/tests/test_reason.py index 8e03da3..ef7e418 100644 --- a/tests/test_reason.py +++ b/tests/test_reason.py @@ -118,6 +118,8 @@ def test_validate(errors: str) -> str: val_errors += 'EntityPath "markdown" output error. ' if value_dict["ontology_graph_iri"] != VALIDATE_ONTOLOGY_GRAPH_IRI: val_errors += 'EntityPath "ontology_graph_iri" output error. ' + if value_dict["reasoner"] != "elk": + val_errors += 'EntityPath "reasoner" output error. ' if value_dict["valid_profiles"] != "Full,DL,EL,QL,RL": val_errors += 'EntityPath "valid_profiles" output error. ' if md_test != get_resource(PROJECT_ID, MD_FILENAME).decode(): From 8bb4b8feb8e4ee4cad169c2e246da9ffbdb25ba2 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 10:16:16 +0100 Subject: [PATCH 18/28] remove todo for creating issue --- CHANGELOG.md | 2 +- cmem_plugin_reason/plugin_reason.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be7069f..be2e07e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Validate: the entity output includes the reasoner option on path "reason" - Detailed axiom generator documentation - - The axiom generator EquivalentobjectProperty does not yield results possibly due to a bug in the OWL API. Currently, + - The axiom generator EquivalentObjectProperty does not yield results possibly due to a bug in the OWL API. Currently, this axiom generator and its (working) counterpart EquivalentDataProperties are removed from the Reason plugin. ## [1.0.0beta5] 2024-08-15 diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index 290f116..b806a8c 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -338,8 +338,7 @@ def __init__( # noqa: PLR0913 C901 sub_object_property: bool = False, equivalent_object_property: bool = False, # This axiom generator does not yield any results. - # TODO: Create issue in github # noqa: TD002 - # https://github.com/eccenca/cmem-plugin-reason/issues/10 + # Issue: https://github.com/eccenca/cmem-plugin-reason/issues/10 # object_property_characteristic: bool = False, object_property_domain: bool = False, object_property_range: bool = False, From 45cec6bcb5c4e78f370bf03f46ef68bf8e653895 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 10:28:49 +0100 Subject: [PATCH 19/28] corrected changelog entry for removed aximo generators --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be2e07e..35f5fc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Validate: the entity output includes the reasoner option on path "reason" - Detailed axiom generator documentation - - The axiom generator EquivalentObjectProperty does not yield results possibly due to a bug in the OWL API. Currently, -this axiom generator and its (working) counterpart EquivalentDataProperties are removed from the Reason plugin. + - The axiom generator ObjectPropertyCharacteristic does not yield results possibly due to a bug in the OWL API. Currently, +this axiom generator and its (working) counterpart DataPropertyCharacteristic are removed from the Reason plugin. ## [1.0.0beta5] 2024-08-15 From 69626d5e1935060b8739225ad9137ff926e1f258 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 11:20:30 +0100 Subject: [PATCH 20/28] edit README --- README-public.md | 9 ++++++--- README.md | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README-public.md b/README-public.md index 4500bbf..3959217 100644 --- a/README-public.md +++ b/README-public.md @@ -1,10 +1,13 @@ # cmem-plugin-reason -This [eccenca](https://eccenca.com) [Corporate Memory](https://documentation.eccenca.com) workflow plugin performs reasoning using [ROBOT](http://robot.obolibrary.org/). +This [eccenca](https://eccenca.com) [Corporate Memory](https://documentation.eccenca.com) workflow plugin bundle contains plugins performing reasoning (Reason) andontology consistency checking (Validate) using [ROBOT](http://robot.obolibrary.org/). ROBOT is published under the [BSD 3-Clause "New" or "Revised" License](https://choosealicense.com/licenses/bsd-3-clause/). -Copyright © 2015, the Authors - +Copyright © 2015, the Authors. All rights reserved. +### Installation +``` +➜ cmemc admin workspace python install cmem-plugin-reason +``` diff --git a/README.md b/README.md index 4f26733..669f1e5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This [eccenca](https://eccenca.com) [Corporate Memory](https://documentation.ecc [![eccenca Corporate Memory](https://img.shields.io/badge/eccenca-Corporate%20Memory-orange)](https://documentation.eccenca.com) [![workflow](https://github.com/eccenca/cmem-plugin-pyshacl/actions/workflows/check.yml/badge.svg)](https://github.com/eccenca/cmem-plugin-pyshacl/actions) [![pypi version](https://img.shields.io/pypi/v/cmem-plugin-reason)](https://pypi.org/project/cmem-plugin-reason/) [![license](https://img.shields.io/pypi/l/cmem-plugin-reason)](https://pypi.org/project/cmem-plugin-reasom) ROBOT is published under the [BSD 3-Clause "New" or "Revised" License](https://choosealicense.com/licenses/bsd-3-clause/). -Copyright © 2015, the Authors +Copyright © 2015, the Authors. All rights reserved. ## Build From b4a98ffec0f1600296bfa67e1bd628cbb18c9f48 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 11:21:34 +0100 Subject: [PATCH 21/28] edit README --- README-public.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README-public.md b/README-public.md index 3959217..0689bbd 100644 --- a/README-public.md +++ b/README-public.md @@ -3,7 +3,7 @@ This [eccenca](https://eccenca.com) [Corporate Memory](https://documentation.eccenca.com) workflow plugin bundle contains plugins performing reasoning (Reason) andontology consistency checking (Validate) using [ROBOT](http://robot.obolibrary.org/). ROBOT is published under the [BSD 3-Clause "New" or "Revised" License](https://choosealicense.com/licenses/bsd-3-clause/). -Copyright © 2015, the Authors. All rights reserved. +Copyright © 2015, the authors. All rights reserved. ### Installation diff --git a/README.md b/README.md index 669f1e5..cf6db82 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This [eccenca](https://eccenca.com) [Corporate Memory](https://documentation.ecc [![eccenca Corporate Memory](https://img.shields.io/badge/eccenca-Corporate%20Memory-orange)](https://documentation.eccenca.com) [![workflow](https://github.com/eccenca/cmem-plugin-pyshacl/actions/workflows/check.yml/badge.svg)](https://github.com/eccenca/cmem-plugin-pyshacl/actions) [![pypi version](https://img.shields.io/pypi/v/cmem-plugin-reason)](https://pypi.org/project/cmem-plugin-reason/) [![license](https://img.shields.io/pypi/l/cmem-plugin-reason)](https://pypi.org/project/cmem-plugin-reasom) ROBOT is published under the [BSD 3-Clause "New" or "Revised" License](https://choosealicense.com/licenses/bsd-3-clause/). -Copyright © 2015, the Authors. All rights reserved. +Copyright © 2015, the authors. All rights reserved. ## Build From d4c446d18cc2e47c056bf5c4d10ac56e08a39df4 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 13:57:57 +0100 Subject: [PATCH 22/28] edit doctring --- cmem_plugin_reason/plugin_reason.py | 2 +- cmem_plugin_reason/plugin_validate.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index b806a8c..a4b3270 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -531,7 +531,7 @@ def _execute(self, context: ExecutionContext) -> None: ) def execute(self, inputs: None, context: ExecutionContext) -> None: # noqa: ARG002 - """Validate input, execute plugin with temporary directory""" + """Execute plugin with temporary directory""" context.report.update( ExecutionReport( operation="reason", diff --git a/cmem_plugin_reason/plugin_validate.py b/cmem_plugin_reason/plugin_validate.py index 3483480..a9c7f4d 100644 --- a/cmem_plugin_reason/plugin_validate.py +++ b/cmem_plugin_reason/plugin_validate.py @@ -287,7 +287,7 @@ def _execute(self, context: ExecutionContext) -> Entities | None: return None def execute(self, inputs: None, context: ExecutionContext) -> Entities | None: # noqa: ARG002 - """Remove temp files on error""" + """Execute plugin with temporary directory""" context.report.update( ExecutionReport( operation="validate", From 2d71c92a2a10fe9114767b269d45c5ad98e515ec Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 14:42:11 +0100 Subject: [PATCH 23/28] axiom generator desctiptions only in main plugin decription, rename axiom generatot parameter labels, outout graph IRI parameter in utils --- README.md | 28 +-- cmem_plugin_reason/doc/reason_doc.md | 32 ++-- cmem_plugin_reason/plugin_reason.py | 259 +++++++++++++------------- cmem_plugin_reason/plugin_validate.py | 22 +-- cmem_plugin_reason/utils.py | 14 ++ 5 files changed, 180 insertions(+), 175 deletions(-) diff --git a/README.md b/README.md index cf6db82..b55d7a0 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ and `owl:Ontology`. The IRI of the input ontology graph. The graph IRI is selected from a list of graphs of type`owl:Ontology`. -### Result graph IRI +### Output graph IRI The IRI of the output graph for the reasoning result. @@ -61,28 +61,28 @@ By default, the reason operation will only assert inferred subclass axioms. The parameters to include inferred axiom generators: #### Class axiom generators -- **SubClass** +- **Class inclusion (rdfs:subClassOf)** The reasoner will infer assertions about the hierarchy of classes, i.e. `SubClassOf:` statements. If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. -- **EquivalentClass** +- **Class equivalence (owl:equivalentClass)** The reasoner will infer assertions about the equivalence of classes, i.e. `EquivalentTo:` statements. If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. -- **DisjointClasses** +- **Class disjointness (owl:disjointWith)** The reasoner will infer assertions about the disjointness of classes, i.e. `DisjointClasses:` statements. If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. -- **EquivalentDataProperties** +- **Data property equivalence (owl:equivalentProperty)** The reasoner will infer axioms about the equivalence of data properties, i.e. `EquivalentProperties` statements. If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber @@ -90,15 +90,16 @@ SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` hold will infer `Student EquivalentProperties: identifier, enrollmentNumber`. -- **SubDataProperty** +- **Data property inclusion (rdfs:subPropertyOf)** The reasoner will infer axioms about the hierarchy of data properties, i.e. `SubPropertyOf:` statements. If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that `studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. + #### Individual axiom generators -- **ClassAssertion** +- **Individual class assertions (rdf:type)** The reasoner will infer assertions about the classes of individuals, i.e. `Types:` statements. Assume, there are classes `Person`, `Student` and `University` as well as the property @@ -107,7 +108,7 @@ the individual `John` with the assertions `John Types: Person; Facts: enrolledIn LeipzigUniversity`, the reasoner will infer `John Types: Student`. -- **PropertyAssertion** +- **Individual property assertions** The reasoner will infer assertions about the properties of individuals, i.e. `Facts:` statements. Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: @@ -115,8 +116,9 @@ enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniv assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. + #### Object property axiom generators -- **EquivalentObjectProperty** +- **Object property equivalence (owl:equivalentProperty)** The reasoner will infer assertions about the equivalence of object properties, i.e. `EquivalentTo:` statements. If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that @@ -125,7 +127,7 @@ hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: has hasSameTopicAs`. -- **InverseObjectProperties** +- **Object property inversion (owl:inverseOf)** The reasoner will infer axioms about the inversion about object properties, i.e. `InverseOf:` statements. If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture @@ -133,7 +135,7 @@ Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLectur hasAlternativeLecture`. -- **SubObjectProperty** +- **Object property inclusion (rdfs:subPropertyOf)** The reasoner will infer axioms about the inclusion of object properties, i.e. `SubPropertyOf:` statements. If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn @@ -141,7 +143,7 @@ SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reas `hasStudent SubPropertyOf: inverse (studentOf)`. -- **ObjectPropertyRange** +- **Object property ranges (rdfs:range)** The reasoner will infer axioms about the ranges of object properties, i.e. `Range:` statements. If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and @@ -149,7 +151,7 @@ If there are classes `Student` and `Lecture` as wells as object properties `hasS reasoner will infer `hasStudent Range: Student`. -- **ObjectPropertyDomain** +- **Object property domains (rdfs:domain)** The reasoner will infer axioms about the domains of object properties, i.e. `Domain:` statements. If there are classes `Person`, `Student` and `Professor` as wells as the object property diff --git a/cmem_plugin_reason/doc/reason_doc.md b/cmem_plugin_reason/doc/reason_doc.md index e203aba..5f1ae59 100644 --- a/cmem_plugin_reason/doc/reason_doc.md +++ b/cmem_plugin_reason/doc/reason_doc.md @@ -11,7 +11,7 @@ and `owl:Ontology`. The IRI of the input ontology graph. The graph IRI is selected from a list of graphs of type`owl:Ontology`. -### Result graph IRI +### Output graph IRI The IRI of the output graph for the reasoning result. @@ -33,28 +33,32 @@ By default, the reason operation will only assert inferred subclass axioms. The parameters to include inferred axiom generators: #### Class axiom generators -- **SubClass** +By default, the reason operation will only assert inferred subclass axioms. The plugin provides the following +parameters to include inferred axiom generators: + +#### Class axiom generators +- **Class inclusion (rdfs:subClassOf)** The reasoner will infer assertions about the hierarchy of classes, i.e. `SubClassOf:` statements. If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. -- **EquivalentClass** +- **Class equivalence (owl:equivalentClass)** The reasoner will infer assertions about the equivalence of classes, i.e. `EquivalentTo:` statements. If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. -- **DisjointClasses** +- **Class disjointness (owl:disjointWith)** The reasoner will infer assertions about the disjointness of classes, i.e. `DisjointClasses:` statements. If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. -- **EquivalentDataProperties** +- **Data property equivalence (owl:equivalentProperty)** The reasoner will infer axioms about the equivalence of data properties, i.e. `EquivalentProperties` statements. If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber @@ -62,15 +66,16 @@ SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` hold will infer `Student EquivalentProperties: identifier, enrollmentNumber`. -- **SubDataProperty** +- **Data property inclusion (rdfs:subPropertyOf)** The reasoner will infer axioms about the hierarchy of data properties, i.e. `SubPropertyOf:` statements. If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that `studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. + #### Individual axiom generators -- **ClassAssertion** +- **Individual class assertions (rdf:type)** The reasoner will infer assertions about the classes of individuals, i.e. `Types:` statements. Assume, there are classes `Person`, `Student` and `University` as well as the property @@ -79,7 +84,7 @@ the individual `John` with the assertions `John Types: Person; Facts: enrolledIn LeipzigUniversity`, the reasoner will infer `John Types: Student`. -- **PropertyAssertion** +- **Individual property assertions** The reasoner will infer assertions about the properties of individuals, i.e. `Facts:` statements. Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: @@ -87,8 +92,9 @@ enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniv assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. + #### Object property axiom generators -- **EquivalentObjectProperty** +- **Object property equivalence (owl:equivalentProperty)** The reasoner will infer assertions about the equivalence of object properties, i.e. `EquivalentTo:` statements. If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that @@ -97,7 +103,7 @@ hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: has hasSameTopicAs`. -- **InverseObjectProperties** +- **Object property inversion (owl:inverseOf)** The reasoner will infer axioms about the inversion about object properties, i.e. `InverseOf:` statements. If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture @@ -105,7 +111,7 @@ Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLectur hasAlternativeLecture`. -- **SubObjectProperty** +- **Object property inclusion (rdfs:subPropertyOf)** The reasoner will infer axioms about the inclusion of object properties, i.e. `SubPropertyOf:` statements. If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn @@ -113,7 +119,7 @@ SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reas `hasStudent SubPropertyOf: inverse (studentOf)`. -- **ObjectPropertyRange** +- **Object property ranges (rdfs:range)** The reasoner will infer axioms about the ranges of object properties, i.e. `Range:` statements. If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and @@ -121,7 +127,7 @@ If there are classes `Student` and `Lecture` as wells as object properties `hasS reasoner will infer `hasStudent Range: Student`. -- **ObjectPropertyDomain** +- **Object property domains (rdfs:domain)** The reasoner will infer axioms about the domains of object properties, i.e. `Domain:` statements. If there are classes `Person`, `Student` and `Professor` as wells as the object property diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index a4b3270..6d6a7bc 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -22,6 +22,7 @@ MAX_RAM_PERCENTAGE_DEFAULT, MAX_RAM_PERCENTAGE_PARAMETER, ONTOLOGY_GRAPH_IRI_PARAMETER, + OUTPUT_GRAPH_IRI_PARAMETER, REASONER_PARAMETER, REASONERS, VALIDATE_PROFILES_PARAMETER, @@ -35,118 +36,123 @@ validate_profiles, ) -SUBCLASS_DESC = """The reasoner will infer assertions about the hierarchy of classes, i.e. -`SubClassOf:` statements. - -If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. -""" - -EQUIVALENCE_DESC = """The reasoner will infer assertions about the equivalence of classes, i.e. -`EquivalentTo:` statements. - -If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. -""" - -DISJOINT_DESC = """The reasoner will infer assertions about the disjointness of classes, i.e. -`DisjointClasses:` statements. - -If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. -""" - -# DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. -# `Characteristics:` statements. For data properties, this only pertains to functionality. +# REASONER_PARAMETER.description += " Select axiom generators below [Click (?) for documentation]." +# OUTPUT_GRAPH_IRI_PARAMETER.description = """The IRI of the output graph for the reasoning result. +# ⚠️ Existing graphs will be overwritten.""" +# +# SUBCLASS_DESC = """The reasoner will infer assertions about the hierarchy of classes, i.e. +# `SubClassOf:` statements. +# +# If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +# Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. +# """ +# +# EQUIVALENCE_DESC = """The reasoner will infer assertions about the equivalence of classes, i.e. +# `EquivalentTo:` statements. +# +# If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +# Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. +# """ +# +# DISJOINT_DESC = """The reasoner will infer assertions about the disjointness of classes, i.e. +# `DisjointClasses:` statements. +# +# If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: +# Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. +# """ +# +# # DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. +# # `Characteristics:` statements. For data properties, this only pertains to functionality. +# # +# # If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber +# # SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will +# # infer `enrollmentNumber Characteristics: Functional`. +# # """ +# +# DATA_PROP_EQUIV_DESC = """The reasoner will infer axioms about the equivalence of data properties, +# i.e. `EquivalentProperties` statements. # # If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber -# SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will -# infer `enrollmentNumber Characteristics: Functional`. +# SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner +# will infer `Student EquivalentProperties: identifier, enrollmentNumber`. # """ - -DATA_PROP_EQUIV_DESC = """The reasoner will infer axioms about the equivalence of data properties, - i.e. `EquivalentProperties` statements. - -If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber -SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner -will infer `Student EquivalentProperties: identifier, enrollmentNumber`. -""" - -DATA_PROP_SUB_DESC = """The reasoner will infer axioms about the hierarchy of data properties, -i.e. `SubPropertyOf:` statements. - -If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that -`studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: -studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. -""" - -CLASS_ASSERT_DESC = """The reasoner will infer assertions about the classes of individuals, i.e. -`Types:` statements. - -Assume, there are classes `Person`, `Student` and `University` as well as the property -`enrolledIn`, such that `Student EquivalentTo: Person and enrolledIn some University` holds. For -the individual `John` with the assertions `John Types: Person; Facts: enrolledIn -LeipzigUniversity`, the reasoner will infer `John Types: Student`. -""" - -PROPERTY_ASSERT_DESC = """The reasoner will infer assertions about the properties of individuals, -i.e. `Facts:` statements. - -Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: -enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the -assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers -KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. -""" - -# OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e. -# `Characteristics:` statements. # -# If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn -# SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will -# infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact -# nor in HermiT!** +# DATA_PROP_SUB_DESC = """The reasoner will infer axioms about the hierarchy of data properties, +# i.e. `SubPropertyOf:` statements. +# +# If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that +# `studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: +# studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. +# """ +# +# CLASS_ASSERT_DESC = """The reasoner will infer assertions about the classes of individuals, i.e. +# `Types:` statements. +# +# Assume, there are classes `Person`, `Student` and `University` as well as the property +# `enrolledIn`, such that `Student EquivalentTo: Person and enrolledIn some University` holds. For +# the individual `John` with the assertions `John Types: Person; Facts: enrolledIn +# LeipzigUniversity`, the reasoner will infer `John Types: Student`. +# """ +# +# PROPERTY_ASSERT_DESC = """The reasoner will infer assertions about the properties of individuals, +# i.e. `Facts:` statements. +# +# Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: +# enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the +# assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers +# KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. +# """ +# +# # OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e. +# # `Characteristics:` statements. +# # +# # If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn +# # SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will +# # infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact +# # nor in HermiT!** +# # """ +# +# OBJECT_PROP_EQUIV_DESC = """The reasoner will infer assertions about the equivalence of object +# properties, i.e. `EquivalentTo:` statements. +# +# If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that +# `hasAlternativeLecture Characteristics: Symmetric` and `hasSameTopicAs InverseOf: +# hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: +# hasAlternativeLecture, hasSameTopicAs`. +# """ +# +# OBJECT_PROP_SUB_DESC = """The reasoner will infer axioms about the inclusion of object properties, +# i.e. `SubPropertyOf:` statements. +# +# If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn +# SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reasoner will infer +# `hasStudent SubPropertyOf: inverse (studentOf)`. +# """ +# +# OBJECT_PROP_INV_DESC = """The reasoner will infer axioms about the inversion about object +# properties, i.e. `InverseOf:` statements. +# +# If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture +# Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLecture InverseOf: +# hasAlternativeLecture`. +# """ +# +# OBJECT_PROP_RANGE_DESC = """The reasoner will infer axioms about the ranges of object properties, +# i.e. `Range:` statements. +# +# If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and +# `enrolledIn`, such that `hasStudent Range: Student and enrolledIn some Lecture` holds, the +# reasoner will infer `hasStudent Range: Student`. +# """ +# +# OBJECT_PROP_DOMAIN_DESC = """The reasoner will infer axioms about the domains of object +# properties, i.e. `Domain:` statements. +# +# If there are classes `Person`, `Student` and `Professor` as wells as the object property +# `hasRoleIn`, such that `Professor SubClassOf: Person`, `Student SubClassOf: Person` and +# `hasRoleIn Domain: Professor or Student` holds, the reasoner will infer `hasRoleIn Domain: +# Person`. # """ - -OBJECT_PROP_EQUIV_DESC = """The reasoner will infer assertions about the equivalence of object -properties, i.e. `EquivalentTo:` statements. - -If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that -`hasAlternativeLecture Characteristics: Symmetric` and `hasSameTopicAs InverseOf: -hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: hasAlternativeLecture, -hasSameTopicAs`. -""" - -OBJECT_PROP_SUB_DESC = """The reasoner will infer axioms about the inclusion of object properties, -i.e. `SubPropertyOf:` statements. - -If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn -SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reasoner will infer -`hasStudent SubPropertyOf: inverse (studentOf)`. -""" - -OBJECT_PROP_INV_DESC = """The reasoner will infer axioms about the inversion about object -properties, i.e. `InverseOf:` statements. - -If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture -Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLecture InverseOf: -hasAlternativeLecture`. -""" - -OBJECT_PROP_RANGE_DESC = """The reasoner will infer axioms about the ranges of object properties, -i.e. `Range:` statements. - -If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and -`enrolledIn`, such that `hasStudent Range: Student and enrolledIn some Lecture` holds, the -reasoner will infer `hasStudent Range: Student`. -""" - -OBJECT_PROP_DOMAIN_DESC = """The reasoner will infer axioms about the domains of object -properties, i.e. `Domain:` statements. - -If there are classes `Person`, `Student` and `Professor` as wells as the object property -`hasRoleIn`, such that `Professor SubClassOf: Person`, `Student SubClassOf: Person` and -`hasRoleIn Domain: Professor or Student` holds, the reasoner will infer `hasRoleIn Domain: Person`. -""" @Plugin( @@ -156,23 +162,10 @@ documentation=REASON_DOC, parameters=[ ONTOLOGY_GRAPH_IRI_PARAMETER, + OUTPUT_GRAPH_IRI_PARAMETER, VALIDATE_PROFILES_PARAMETER, REASONER_PARAMETER, MAX_RAM_PERCENTAGE_PARAMETER, - PluginParameter( - param_type=GraphParameterType( - allow_only_autocompleted_values=False, - classes=[ - "https://vocab.eccenca.com/di/Dataset", - "http://rdfs.org/ns/void#Dataset", - "http://www.w3.org/2002/07/owl#Ontology", - ], - ), - name="output_graph_iri", - label="Output graph IRI", - description="""The IRI of the output graph for the inconsistency validation. ⚠️ Existing - graphs will be overwritten.""", - ), PluginParameter( param_type=GraphParameterType( classes=[ @@ -189,21 +182,21 @@ param_type=BoolParameterType(), name="sub_class", label="Class inclusion (rdfs:subClassOf)", - description=SUBCLASS_DESC, + # description=SUBCLASS_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="equivalent_class", label="Class equivalence (owl:equivalentClass)", - description=EQUIVALENCE_DESC, + # description=EQUIVALENCE_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="disjoint_classes", label="Class disjointness (owl:disjointWith)", - description=DISJOINT_DESC, + # description=DISJOINT_DESC, default_value=False, ), # PluginParameter( @@ -217,42 +210,42 @@ param_type=BoolParameterType(), name="equivalent_data_properties", label="Data property equivalence (owl:equivalentProperty)", - description=DATA_PROP_EQUIV_DESC, + # description=DATA_PROP_EQUIV_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="sub_data_property", label="Data property inclusion (rdfs:subPropertyOf)", - description=DATA_PROP_SUB_DESC, + # description=DATA_PROP_SUB_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="class_assertion", label="Individual class assertions (rdf:type)", - description=CLASS_ASSERT_DESC, + # description=CLASS_ASSERT_DESC, default_value=True, ), PluginParameter( param_type=BoolParameterType(), name="property_assertion", label="Individual property assertions", - description=PROPERTY_ASSERT_DESC, + # description=PROPERTY_ASSERT_DESC, default_value=True, ), PluginParameter( param_type=BoolParameterType(), name="equivalent_object_property", label="Object property equivalence (owl:equivalentProperty)", - description=OBJECT_PROP_EQUIV_DESC, + # description=OBJECT_PROP_EQUIV_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="inverse_object_properties", label="Object property inversion (owl:inverseOf)", - description=OBJECT_PROP_INV_DESC, + # description=OBJECT_PROP_INV_DESC, default_value=False, ), # PluginParameter( @@ -266,21 +259,21 @@ param_type=BoolParameterType(), name="sub_object_property", label="Object property inclusion (rdfs:subPropertyOf)", - description=OBJECT_PROP_SUB_DESC, + # description=OBJECT_PROP_SUB_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="object_property_range", label="Object property ranges (rdfs:range)", - description=OBJECT_PROP_RANGE_DESC, + # description=OBJECT_PROP_RANGE_DESC, default_value=False, ), PluginParameter( param_type=BoolParameterType(), name="object_property_domain", label="Object property domains (rdfs:domain)", - description=OBJECT_PROP_DOMAIN_DESC, + # description=OBJECT_PROP_DOMAIN_DESC, default_value=False, ), PluginParameter( diff --git a/cmem_plugin_reason/plugin_validate.py b/cmem_plugin_reason/plugin_validate.py index a9c7f4d..0e3cbb5 100644 --- a/cmem_plugin_reason/plugin_validate.py +++ b/cmem_plugin_reason/plugin_validate.py @@ -13,7 +13,6 @@ from cmem_plugin_base.dataintegration.description import Icon, Plugin, PluginParameter from cmem_plugin_base.dataintegration.entity import Entities, Entity, EntityPath, EntitySchema from cmem_plugin_base.dataintegration.parameter.choice import ChoiceParameterType -from cmem_plugin_base.dataintegration.parameter.graph import GraphParameterType from cmem_plugin_base.dataintegration.plugins import WorkflowPlugin from cmem_plugin_base.dataintegration.ports import FixedNumberOfInputs, FixedSchemaPort from cmem_plugin_base.dataintegration.types import BoolParameterType, StringParameterType @@ -25,6 +24,7 @@ MAX_RAM_PERCENTAGE_DEFAULT, MAX_RAM_PERCENTAGE_PARAMETER, ONTOLOGY_GRAPH_IRI_PARAMETER, + OUTPUT_GRAPH_IRI_PARAMETER, REASONER_PARAMETER, REASONERS, VALIDATE_PROFILES_PARAMETER, @@ -38,6 +38,10 @@ validate_profiles, ) +OUTPUT_GRAPH_IRI_PARAMETER.description = """The IRI of the output graph for the inconsistency +validation. ⚠️ Existing graphs will be overwritten.""" +OUTPUT_GRAPH_IRI_PARAMETER.default_value = "" + @Plugin( label="Validate OWL consistency", @@ -46,24 +50,10 @@ icon=Icon(file_name="file-icons--owl.svg", package=__package__), parameters=[ ONTOLOGY_GRAPH_IRI_PARAMETER, + OUTPUT_GRAPH_IRI_PARAMETER, MAX_RAM_PERCENTAGE_PARAMETER, VALIDATE_PROFILES_PARAMETER, REASONER_PARAMETER, - PluginParameter( - param_type=GraphParameterType( - allow_only_autocompleted_values=False, - classes=[ - "https://vocab.eccenca.com/di/Dataset", - "http://rdfs.org/ns/void#Dataset", - "http://www.w3.org/2002/07/owl#Ontology", - ], - ), - name="output_graph_iri", - label="Output graph IRI", - description="""The IRI of the output graph for the inconsistency validation. ⚠️ Existing - graphs will be overwritten.""", - default_value="", - ), PluginParameter( param_type=StringParameterType(), name="md_filename", diff --git a/cmem_plugin_reason/utils.py b/cmem_plugin_reason/utils.py index d9f33ba..c3ec7da 100644 --- a/cmem_plugin_reason/utils.py +++ b/cmem_plugin_reason/utils.py @@ -36,6 +36,20 @@ MAX_RAM_PERCENTAGE_DEFAULT = 20 + +OUTPUT_GRAPH_IRI_PARAMETER = PluginParameter( + param_type=GraphParameterType( + allow_only_autocompleted_values=False, + classes=[ + "https://vocab.eccenca.com/di/Dataset", + "http://rdfs.org/ns/void#Dataset", + "http://www.w3.org/2002/07/owl#Ontology", + ], + ), + name="output_graph_iri", + label="Output graph IRI", +) + REASONER_PARAMETER = PluginParameter( param_type=ChoiceParameterType(REASONERS), name="reasoner", From 15b73402147b10af976d97bb703dc11aa914fc81 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 14:51:45 +0100 Subject: [PATCH 24/28] edit README for new default axiom generators --- README.md | 3 +-- cmem_plugin_reason/doc/reason_doc.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b55d7a0..de66ab8 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,7 @@ The following reasoner options are supported: ### Generated Axioms -By default, the reason operation will only assert inferred subclass axioms. The plugin provides the following -parameters to include inferred axiom generators: +The plugin provides the following parameters to include inferred axiom generators: #### Class axiom generators - **Class inclusion (rdfs:subClassOf)** diff --git a/cmem_plugin_reason/doc/reason_doc.md b/cmem_plugin_reason/doc/reason_doc.md index 5f1ae59..3412928 100644 --- a/cmem_plugin_reason/doc/reason_doc.md +++ b/cmem_plugin_reason/doc/reason_doc.md @@ -29,8 +29,7 @@ The following reasoner options are supported: ### Generated Axioms -By default, the reason operation will only assert inferred subclass axioms. The plugin provides the following -parameters to include inferred axiom generators: +The plugin provides the following parameters to include inferred axiom generators: #### Class axiom generators By default, the reason operation will only assert inferred subclass axioms. The plugin provides the following From 0ac4485ebe85cb99d07335deb3143cac93e8ecb9 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 14:55:41 +0100 Subject: [PATCH 25/28] edit --- cmem_plugin_reason/doc/reason_doc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmem_plugin_reason/doc/reason_doc.md b/cmem_plugin_reason/doc/reason_doc.md index 3412928..b1c403e 100644 --- a/cmem_plugin_reason/doc/reason_doc.md +++ b/cmem_plugin_reason/doc/reason_doc.md @@ -31,10 +31,6 @@ The following reasoner options are supported: The plugin provides the following parameters to include inferred axiom generators: -#### Class axiom generators -By default, the reason operation will only assert inferred subclass axioms. The plugin provides the following -parameters to include inferred axiom generators: - #### Class axiom generators - **Class inclusion (rdfs:subClassOf)** The reasoner will infer assertions about the hierarchy of classes, i.e. From 76675c264e5f5e72e16adc9724dc60e34e406982 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Mon, 26 Aug 2024 15:05:17 +0100 Subject: [PATCH 26/28] output graph type for Reason owl:Ontology only --- cmem_plugin_reason/plugin_reason.py | 17 ++++++++++++----- cmem_plugin_reason/plugin_validate.py | 22 ++++++++++++++++------ cmem_plugin_reason/utils.py | 13 ------------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index 6d6a7bc..9aab801 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -22,7 +22,6 @@ MAX_RAM_PERCENTAGE_DEFAULT, MAX_RAM_PERCENTAGE_PARAMETER, ONTOLOGY_GRAPH_IRI_PARAMETER, - OUTPUT_GRAPH_IRI_PARAMETER, REASONER_PARAMETER, REASONERS, VALIDATE_PROFILES_PARAMETER, @@ -36,9 +35,8 @@ validate_profiles, ) -# REASONER_PARAMETER.description += " Select axiom generators below [Click (?) for documentation]." -# OUTPUT_GRAPH_IRI_PARAMETER.description = """The IRI of the output graph for the reasoning result. -# ⚠️ Existing graphs will be overwritten.""" +REASONER_PARAMETER.description += " Select axiom generators below [Click (?) for documentation]." + # # SUBCLASS_DESC = """The reasoner will infer assertions about the hierarchy of classes, i.e. # `SubClassOf:` statements. @@ -162,7 +160,6 @@ documentation=REASON_DOC, parameters=[ ONTOLOGY_GRAPH_IRI_PARAMETER, - OUTPUT_GRAPH_IRI_PARAMETER, VALIDATE_PROFILES_PARAMETER, REASONER_PARAMETER, MAX_RAM_PERCENTAGE_PARAMETER, @@ -178,6 +175,16 @@ label="Data graph IRI", description="The IRI of the input data graph.", ), + PluginParameter( + param_type=GraphParameterType( + allow_only_autocompleted_values=False, + classes=["http://www.w3.org/2002/07/owl#Ontology"], + ), + name="output_graph_iri", + label="Output graph IRI", + description="""The IRI of the output graph for the reasoning result. ⚠️ Existing graphs + will be overwritten.""", + ), PluginParameter( param_type=BoolParameterType(), name="sub_class", diff --git a/cmem_plugin_reason/plugin_validate.py b/cmem_plugin_reason/plugin_validate.py index 0e3cbb5..6a71a67 100644 --- a/cmem_plugin_reason/plugin_validate.py +++ b/cmem_plugin_reason/plugin_validate.py @@ -13,6 +13,7 @@ from cmem_plugin_base.dataintegration.description import Icon, Plugin, PluginParameter from cmem_plugin_base.dataintegration.entity import Entities, Entity, EntityPath, EntitySchema from cmem_plugin_base.dataintegration.parameter.choice import ChoiceParameterType +from cmem_plugin_base.dataintegration.parameter.graph import GraphParameterType from cmem_plugin_base.dataintegration.plugins import WorkflowPlugin from cmem_plugin_base.dataintegration.ports import FixedNumberOfInputs, FixedSchemaPort from cmem_plugin_base.dataintegration.types import BoolParameterType, StringParameterType @@ -24,7 +25,6 @@ MAX_RAM_PERCENTAGE_DEFAULT, MAX_RAM_PERCENTAGE_PARAMETER, ONTOLOGY_GRAPH_IRI_PARAMETER, - OUTPUT_GRAPH_IRI_PARAMETER, REASONER_PARAMETER, REASONERS, VALIDATE_PROFILES_PARAMETER, @@ -38,10 +38,6 @@ validate_profiles, ) -OUTPUT_GRAPH_IRI_PARAMETER.description = """The IRI of the output graph for the inconsistency -validation. ⚠️ Existing graphs will be overwritten.""" -OUTPUT_GRAPH_IRI_PARAMETER.default_value = "" - @Plugin( label="Validate OWL consistency", @@ -50,7 +46,6 @@ icon=Icon(file_name="file-icons--owl.svg", package=__package__), parameters=[ ONTOLOGY_GRAPH_IRI_PARAMETER, - OUTPUT_GRAPH_IRI_PARAMETER, MAX_RAM_PERCENTAGE_PARAMETER, VALIDATE_PROFILES_PARAMETER, REASONER_PARAMETER, @@ -62,6 +57,21 @@ "inconsistencies.⚠️ Existing files will be overwritten.", default_value="", ), + PluginParameter( + param_type=GraphParameterType( + allow_only_autocompleted_values=False, + classes=[ + "https://vocab.eccenca.com/di/Dataset", + "http://rdfs.org/ns/void#Dataset", + "http://www.w3.org/2002/07/owl#Ontology", + ], + ), + name="output_graph_iri", + label="Output graph IRI", + description="""The IRI of the output graph for the inconsistency validation. ⚠️ Existing + graphs will be overwritten.""", + default_value="", + ), PluginParameter( param_type=BoolParameterType(), name="stop_at_inconsistencies", diff --git a/cmem_plugin_reason/utils.py b/cmem_plugin_reason/utils.py index c3ec7da..7d76195 100644 --- a/cmem_plugin_reason/utils.py +++ b/cmem_plugin_reason/utils.py @@ -37,19 +37,6 @@ MAX_RAM_PERCENTAGE_DEFAULT = 20 -OUTPUT_GRAPH_IRI_PARAMETER = PluginParameter( - param_type=GraphParameterType( - allow_only_autocompleted_values=False, - classes=[ - "https://vocab.eccenca.com/di/Dataset", - "http://rdfs.org/ns/void#Dataset", - "http://www.w3.org/2002/07/owl#Ontology", - ], - ), - name="output_graph_iri", - label="Output graph IRI", -) - REASONER_PARAMETER = PluginParameter( param_type=ChoiceParameterType(REASONERS), name="reasoner", From b66fbd63738c33e1b4880360b5653e827610c835 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Tue, 27 Aug 2024 16:28:55 +0100 Subject: [PATCH 27/28] edit docstring --- cmem_plugin_reason/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmem_plugin_reason/utils.py b/cmem_plugin_reason/utils.py index 7d76195..295e5c7 100644 --- a/cmem_plugin_reason/utils.py +++ b/cmem_plugin_reason/utils.py @@ -89,7 +89,7 @@ def create_xml_catalog_file(dir_: str, graphs: dict) -> None: def get_graphs_tree(graph_iris: tuple) -> dict: - """Get graph import tree. Last item in tuple is output_graph_iri which is excluded""" + """Get graph import tree. Last item in graph_iris is output_graph_iris which is excluded""" graphs = {} for graph_iri in graph_iris[:-1]: if graph_iri not in graphs: From e3517c7bc18248f6062c6d1e67b11430009d9704 Mon Sep 17 00:00:00 2001 From: muddymudskipper Date: Wed, 28 Aug 2024 10:17:42 +0100 Subject: [PATCH 28/28] fix validate_profiles, test import tree --- CHANGELOG.md | 8 +- cmem_plugin_reason/plugin_reason.py | 115 ------------------ cmem_plugin_reason/utils.py | 2 +- poetry.lock | 24 ++-- tests/test_reason.py | 48 +++++--- .../{vocab.ttl => test_reason_ontology_1.ttl} | 26 +--- tests/test_reason_ontology_2.ttl | 24 ++++ tests/test_reason_ontology_3.ttl | 27 ++++ tests/test_validate.md | 8 +- tests/test_validate_ontology_1.ttl | 9 ++ tests/test_validate_ontology_2.ttl | 9 ++ ...ology.ttl => test_validate_ontology_3.ttl} | 4 +- 12 files changed, 128 insertions(+), 176 deletions(-) rename tests/{vocab.ttl => test_reason_ontology_1.ttl} (96%) create mode 100644 tests/test_reason_ontology_2.ttl create mode 100644 tests/test_reason_ontology_3.ttl create mode 100644 tests/test_validate_ontology_1.ttl create mode 100644 tests/test_validate_ontology_2.ttl rename tests/{test_validate_ontology.ttl => test_validate_ontology_3.ttl} (94%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35f5fc0..2638129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Validate: added "mode" parameter +### Fixed + +- respect owl:imports in OWL2 profile validation + ### Changed - Validate: the entity output includes the reasoner option on path "reason" - Detailed axiom generator documentation - - The axiom generator ObjectPropertyCharacteristic does not yield results possibly due to a bug in the OWL API. Currently, -this axiom generator and its (working) counterpart DataPropertyCharacteristic are removed from the Reason plugin. + - The axiom generator ObjectPropertyCharacteristic does not yield results. Currently, this axiom generator and its + - (working) counterpart DataPropertyCharacteristic are removed from the Reason plugin. ## [1.0.0beta5] 2024-08-15 diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index 9aab801..8b78971 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -37,121 +37,6 @@ REASONER_PARAMETER.description += " Select axiom generators below [Click (?) for documentation]." -# -# SUBCLASS_DESC = """The reasoner will infer assertions about the hierarchy of classes, i.e. -# `SubClassOf:` statements. -# -# If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -# Student, Professor` holds, the reasoner will infer `Student SubClassOf: Person`. -# """ -# -# EQUIVALENCE_DESC = """The reasoner will infer assertions about the equivalence of classes, i.e. -# `EquivalentTo:` statements. -# -# If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -# Student, Professor` holds, the reasoner will infer `Person EquivalentTo: Student and Professor`. -# """ -# -# DISJOINT_DESC = """The reasoner will infer assertions about the disjointness of classes, i.e. -# `DisjointClasses:` statements. -# -# If there are classes `Person`, `Student` and `Professor`, such that `Person DisjointUnionOf: -# Student, Professor` holds, the reasoner will infer `DisjointClasses: Student, Professor`. -# """ -# -# # DATA_PROP_CHAR_DESC = """The reasoner will infer characteristics of data properties, i.e. -# # `Characteristics:` statements. For data properties, this only pertains to functionality. -# # -# # If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber -# # SubPropertyOf: identifier` and `identifier Characteristics: Functional` holds, the reasoner will -# # infer `enrollmentNumber Characteristics: Functional`. -# # """ -# -# DATA_PROP_EQUIV_DESC = """The reasoner will infer axioms about the equivalence of data properties, -# i.e. `EquivalentProperties` statements. -# -# If there are data properties `identifier` and `enrollmentNumber`, such that `enrollmentNumber -# SubPropertyOf: identifier` and `identifier SubPropertyOf: enrollmentNumber` holds, the reasoner -# will infer `Student EquivalentProperties: identifier, enrollmentNumber`. -# """ -# -# DATA_PROP_SUB_DESC = """The reasoner will infer axioms about the hierarchy of data properties, -# i.e. `SubPropertyOf:` statements. -# -# If there are data properties `identifier`, `studentIdentifier` and `enrollmentNumber`, such that -# `studentIdentifier SubPropertyOf: identifier` and `enrollmentNumber SubPropertyOf: -# studentIdentifier` holds, the reasoner will infer `enrollmentNumber SubPropertyOf: identifier`. -# """ -# -# CLASS_ASSERT_DESC = """The reasoner will infer assertions about the classes of individuals, i.e. -# `Types:` statements. -# -# Assume, there are classes `Person`, `Student` and `University` as well as the property -# `enrolledIn`, such that `Student EquivalentTo: Person and enrolledIn some University` holds. For -# the individual `John` with the assertions `John Types: Person; Facts: enrolledIn -# LeipzigUniversity`, the reasoner will infer `John Types: Student`. -# """ -# -# PROPERTY_ASSERT_DESC = """The reasoner will infer assertions about the properties of individuals, -# i.e. `Facts:` statements. -# -# Assume, there are properties `enrolledIn` and `offers`, such that `enrolled SubPropertyChain: -# enrolledIn o inverse (offers)` holds. For the individuals `John`and `LeipzigUniversity` with the -# assertions `John Facts: enrolledIn KnowledgeRepresentation` and `LeipzigUniversity Facts: offers -# KnowledgeRepresentation`, the reasoner will infer `John Facts: enrolledIn LeipzigUniversity`. -# """ -# -# # OBJECT_PROP_CHAR_DESC = """The reasoner will infer characteristics of object properties, i.e. -# # `Characteristics:` statements. -# # -# # If there are object properties `enrolledIn` and `studentOf`, such that `enrolledIn -# # SubPropertyOf: studentOf` and `enrolledIn Characteristics: Functional` holds, the reasoner will -# # infer `studentOf Characteristics: Functional`. **Note: this inference does neither work in JFact -# # nor in HermiT!** -# # """ -# -# OBJECT_PROP_EQUIV_DESC = """The reasoner will infer assertions about the equivalence of object -# properties, i.e. `EquivalentTo:` statements. -# -# If there are object properties `hasAlternativeLecture` and `hasSameTopicAs`, such that -# `hasAlternativeLecture Characteristics: Symmetric` and `hasSameTopicAs InverseOf: -# hasAlternativeLecture` holds, the reasoner will infer `EquivalentProperties: -# hasAlternativeLecture, hasSameTopicAs`. -# """ -# -# OBJECT_PROP_SUB_DESC = """The reasoner will infer axioms about the inclusion of object properties, -# i.e. `SubPropertyOf:` statements. -# -# If there are object properties `enrolledIn`, `studentOf` and `hasStudent`, such that `enrolledIn -# SubPropertyOf: studentOf` and `enrolledIn InverseOf: hasStudent` holds, the reasoner will infer -# `hasStudent SubPropertyOf: inverse (studentOf)`. -# """ -# -# OBJECT_PROP_INV_DESC = """The reasoner will infer axioms about the inversion about object -# properties, i.e. `InverseOf:` statements. -# -# If there is a object property `hasAlternativeLecture`, such that `hasAlternativeLecture -# Characteristics: Symmetric` holds, the reasoner will infer `hasAlternativeLecture InverseOf: -# hasAlternativeLecture`. -# """ -# -# OBJECT_PROP_RANGE_DESC = """The reasoner will infer axioms about the ranges of object properties, -# i.e. `Range:` statements. -# -# If there are classes `Student` and `Lecture` as wells as object properties `hasStudent` and -# `enrolledIn`, such that `hasStudent Range: Student and enrolledIn some Lecture` holds, the -# reasoner will infer `hasStudent Range: Student`. -# """ -# -# OBJECT_PROP_DOMAIN_DESC = """The reasoner will infer axioms about the domains of object -# properties, i.e. `Domain:` statements. -# -# If there are classes `Person`, `Student` and `Professor` as wells as the object property -# `hasRoleIn`, such that `Professor SubClassOf: Person`, `Student SubClassOf: Person` and -# `hasRoleIn Domain: Professor or Student` holds, the reasoner will infer `hasRoleIn Domain: -# Person`. -# """ - @Plugin( label="Reason", diff --git a/cmem_plugin_reason/utils.py b/cmem_plugin_reason/utils.py index 295e5c7..1e12d5f 100644 --- a/cmem_plugin_reason/utils.py +++ b/cmem_plugin_reason/utils.py @@ -209,7 +209,7 @@ def validate_profiles(plugin: WorkflowPlugin, graphs: dict) -> list: valid_profiles = [] for profile in ("Full", "DL", "EL", "QL", "RL"): plugin.log.info(f"Validating {profile} profile.") - cmd = f"validate-profile --profile {profile} --input {ontology_location}" + cmd = f"merge --input {ontology_location} validate-profile --profile {profile}" response = robot(cmd, plugin.max_ram_percentage) if response.stdout.endswith(b"[Ontology and imports closure in profile]\n\n"): valid_profiles.append(profile) diff --git a/poetry.lock b/poetry.lock index 4899fc0..7b89598 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1003,13 +1003,13 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "rich" -version = "13.7.1" +version = "13.8.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, + {file = "rich-13.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc"}, + {file = "rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"}, ] [package.dependencies] @@ -1065,19 +1065,23 @@ setuptools = "*" [[package]] name = "setuptools" -version = "73.0.1" +version = "74.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, - {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, + {file = "setuptools-74.0.0-py3-none-any.whl", hash = "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f"}, + {file = "setuptools-74.0.0.tar.gz", hash = "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] [[package]] name = "six" @@ -1092,13 +1096,13 @@ files = [ [[package]] name = "textual" -version = "0.77.0" +version = "0.78.0" description = "Modern Text User Interface framework" optional = false python-versions = "<4.0.0,>=3.8.1" files = [ - {file = "textual-0.77.0-py3-none-any.whl", hash = "sha256:f117d29ddf9764c8969d1ac23724a7bd8cfe9111e158f2355d8a0e5ad10f5bd7"}, - {file = "textual-0.77.0.tar.gz", hash = "sha256:866c1e18e87b2817ce08e09259224b771caaf8824988c4c717094c6bf106b20f"}, + {file = "textual-0.78.0-py3-none-any.whl", hash = "sha256:c9d3c7dc467c37ee2e54a0283ac2c85dac35e4fc949518ed054a65b8e3e9b822"}, + {file = "textual-0.78.0.tar.gz", hash = "sha256:421f508b0d41ea0b8ecf273bf83f0d19376667eb0a87f70575252395d90ab315"}, ] [package.dependencies] diff --git a/tests/test_reason.py b/tests/test_reason.py index ef7e418..09f9375 100644 --- a/tests/test_reason.py +++ b/tests/test_reason.py @@ -20,9 +20,13 @@ UID = "e02aaed014c94e0c91bf960fed127750" REASON_DATA_GRAPH_IRI = f"https://ns.eccenca.com/reasoning/{UID}/data/" -REASON_ONTOLOGY_GRAPH_IRI = f"https://ns.eccenca.com/reasoning/{UID}/vocab/" +REASON_ONTOLOGY_GRAPH_IRI_1 = f"https://ns.eccenca.com/reasoning/{UID}/vocab/" +REASON_ONTOLOGY_GRAPH_IRI_2 = f"https://ns.eccenca.com/reasoning/{UID}/vocab2/" +REASON_ONTOLOGY_GRAPH_IRI_3 = f"https://ns.eccenca.com/reasoning/{UID}/vocab3/" REASON_RESULT_GRAPH_IRI = f"https://ns.eccenca.com/reasoning/{UID}/result/" -VALIDATE_ONTOLOGY_GRAPH_IRI = f"https://ns.eccenca.com/validateontology/{UID}/vocab/" +VALIDATE_ONTOLOGY_GRAPH_IRI_1 = f"https://ns.eccenca.com/validateontology/{UID}/vocab/" +VALIDATE_ONTOLOGY_GRAPH_IRI_2 = f"https://ns.eccenca.com/validateontology/{UID}/vocab2/" +VALIDATE_ONTOLOGY_GRAPH_IRI_3 = f"https://ns.eccenca.com/validateontology/{UID}/vocab3/" OUTPUT_GRAPH_IRI = f"https://ns.eccenca.com/validateontology/{UID}/output/" MD_FILENAME = f"{UID}.md" PROJECT_ID = f"validate_plugin_test_project_{UID}" @@ -37,31 +41,39 @@ def get_value_dict(entities: Entities) -> dict: return value_dict +def import_graph(iri: str, filename: str) -> None: + """Import graph to CMEM""" + res = post(iri, Path(__path__[0]) / filename, replace=True) + if res.status_code != 204: # noqa: PLR2004 + raise ValueError(f"Response {res.status_code}: {res.url}") + + @pytest.fixture() def _setup(request: pytest.FixtureRequest) -> None: """Set up""" - res = post(REASON_DATA_GRAPH_IRI, Path(__path__[0]) / "dataset_owl.ttl", replace=True) - if res.status_code != 204: # noqa: PLR2004 - raise ValueError(f"Response {res.status_code}: {res.url}") - res = post(REASON_ONTOLOGY_GRAPH_IRI, Path(__path__[0]) / "vocab.ttl", replace=True) - if res.status_code != 204: # noqa: PLR2004 - raise ValueError(f"Response {res.status_code}: {res.url}") + import_graph(REASON_DATA_GRAPH_IRI, "dataset_owl.ttl") + import_graph(REASON_ONTOLOGY_GRAPH_IRI_1, "test_reason_ontology_1.ttl") + import_graph(REASON_ONTOLOGY_GRAPH_IRI_2, "test_reason_ontology_2.ttl") + import_graph(REASON_ONTOLOGY_GRAPH_IRI_3, "test_reason_ontology_3.ttl") with suppress(Exception): delete_project(PROJECT_ID) make_new_project(PROJECT_ID) - res = post( - VALIDATE_ONTOLOGY_GRAPH_IRI, Path(__path__[0]) / "test_validate_ontology.ttl", replace=True - ) - if res.status_code != 204: # noqa: PLR2004 - raise ValueError(f"Response {res.status_code}: {res.url}") + + import_graph(VALIDATE_ONTOLOGY_GRAPH_IRI_1, "test_validate_ontology_1.ttl") + import_graph(VALIDATE_ONTOLOGY_GRAPH_IRI_2, "test_validate_ontology_2.ttl") + import_graph(VALIDATE_ONTOLOGY_GRAPH_IRI_3, "test_validate_ontology_3.ttl") request.addfinalizer(lambda: delete(REASON_DATA_GRAPH_IRI)) - request.addfinalizer(lambda: delete(REASON_ONTOLOGY_GRAPH_IRI)) + request.addfinalizer(lambda: delete(REASON_ONTOLOGY_GRAPH_IRI_1)) + request.addfinalizer(lambda: delete(REASON_ONTOLOGY_GRAPH_IRI_2)) + request.addfinalizer(lambda: delete(REASON_ONTOLOGY_GRAPH_IRI_3)) request.addfinalizer(lambda: delete(REASON_RESULT_GRAPH_IRI)) request.addfinalizer(lambda: delete_project(PROJECT_ID)) request.addfinalizer(lambda: delete(OUTPUT_GRAPH_IRI)) - request.addfinalizer(lambda: delete(VALIDATE_ONTOLOGY_GRAPH_IRI)) # noqa: PT021 + request.addfinalizer(lambda: delete(VALIDATE_ONTOLOGY_GRAPH_IRI_1)) + request.addfinalizer(lambda: delete(VALIDATE_ONTOLOGY_GRAPH_IRI_2)) + request.addfinalizer(lambda: delete(VALIDATE_ONTOLOGY_GRAPH_IRI_3)) # noqa: PT021 @needs_cmem @@ -81,7 +93,7 @@ def get_remote_graph(iri: str) -> Graph: def test_reasoner(reasoner: str, err_list: list) -> list: ReasonPlugin( data_graph_iri=REASON_DATA_GRAPH_IRI, - ontology_graph_iri=REASON_ONTOLOGY_GRAPH_IRI, + ontology_graph_iri=REASON_ONTOLOGY_GRAPH_IRI_1, output_graph_iri=REASON_RESULT_GRAPH_IRI, reasoner=reasoner, sub_class=False, @@ -99,7 +111,7 @@ def test_reasoner(reasoner: str, err_list: list) -> list: def test_validate(errors: str) -> str: result = ValidatePlugin( - ontology_graph_iri=VALIDATE_ONTOLOGY_GRAPH_IRI, + ontology_graph_iri=VALIDATE_ONTOLOGY_GRAPH_IRI_1, output_graph_iri=OUTPUT_GRAPH_IRI, reasoner="elk", validate_profile=True, @@ -116,7 +128,7 @@ def test_validate(errors: str) -> str: if value_dict["markdown"] != md_test: val_errors += 'EntityPath "markdown" output error. ' - if value_dict["ontology_graph_iri"] != VALIDATE_ONTOLOGY_GRAPH_IRI: + if value_dict["ontology_graph_iri"] != VALIDATE_ONTOLOGY_GRAPH_IRI_1: val_errors += 'EntityPath "ontology_graph_iri" output error. ' if value_dict["reasoner"] != "elk": val_errors += 'EntityPath "reasoner" output error. ' diff --git a/tests/vocab.ttl b/tests/test_reason_ontology_1.ttl similarity index 96% rename from tests/vocab.ttl rename to tests/test_reason_ontology_1.ttl index f2e778e..407257d 100644 --- a/tests/vocab.ttl +++ b/tests/test_reason_ontology_1.ttl @@ -9,7 +9,8 @@ rdf:type owl:Ontology ; rdfs:comment "Vocabulary for a reasoning use case"@en ; rdfs:label "Eccenca Reasoning Vocabulary"@en ; - rdfs:seeAlso . + rdfs:seeAlso ; + owl:imports . ################################################################# # Object Properties @@ -141,16 +142,6 @@ owl:Thing rdf:type owl:Class . rdfs:label "adult"^^xsd:string . -### https://ns.eccenca.com/reasoning/e02aaed014c94e0c91bf960fed127750/vocab/animal -:animal rdf:type owl:Class ; - rdfs:subClassOf [ rdf:type owl:Restriction ; - owl:onProperty :eats ; - owl:someValuesFrom owl:Thing - ] ; - rdfs:comment ""^^xsd:string ; - rdfs:isDefinedBy ; - rdfs:label "animal"^^xsd:string . - ### https://ns.eccenca.com/reasoning/e02aaed014c94e0c91bf960fed127750/vocab/animal_lover :animal_lover rdf:type owl:Class ; @@ -261,19 +252,6 @@ owl:Thing rdf:type owl:Class . rdfs:label "cat liker"^^xsd:string . -### https://ns.eccenca.com/reasoning/e02aaed014c94e0c91bf960fed127750/vocab/cat_owner -:cat_owner rdf:type owl:Class ; - owl:equivalentClass [ owl:intersectionOf ( :person - [ rdf:type owl:Restriction ; - owl:onProperty :has_pet ; - owl:someValuesFrom :cat - ] - ) ; - rdf:type owl:Class - ] ; - rdfs:comment ""^^xsd:string ; - rdfs:isDefinedBy ; - rdfs:label "cat owner"^^xsd:string . ### https://ns.eccenca.com/reasoning/e02aaed014c94e0c91bf960fed127750/vocab/company diff --git a/tests/test_reason_ontology_2.ttl b/tests/test_reason_ontology_2.ttl new file mode 100644 index 0000000..fde26ff --- /dev/null +++ b/tests/test_reason_ontology_2.ttl @@ -0,0 +1,24 @@ +@prefix : . +@prefix owl: . +@prefix rdf: . +@prefix xml: . +@prefix xsd: . +@prefix rdfs: . +@base . + + rdf:type owl:Ontology ; + rdfs:comment "Vocabulary for a reasoning use case"@en ; + rdfs:label "Eccenca Reasoning Vocabulary"@en ; + rdfs:seeAlso ; + owl:imports . + + +### https://ns.eccenca.com/reasoning/e02aaed014c94e0c91bf960fed127750/vocab/animal +:animal rdf:type owl:Class ; + rdfs:subClassOf [ rdf:type owl:Restriction ; + owl:onProperty :eats ; + owl:someValuesFrom owl:Thing + ] ; + rdfs:comment ""^^xsd:string ; + rdfs:isDefinedBy ; + rdfs:label "animal"^^xsd:string . diff --git a/tests/test_reason_ontology_3.ttl b/tests/test_reason_ontology_3.ttl new file mode 100644 index 0000000..0e7e0ae --- /dev/null +++ b/tests/test_reason_ontology_3.ttl @@ -0,0 +1,27 @@ +@prefix : . +@prefix owl: . +@prefix rdf: . +@prefix xml: . +@prefix xsd: . +@prefix rdfs: . +@base . + + rdf:type owl:Ontology ; + rdfs:comment "Vocabulary for a reasoning use case"@en ; + rdfs:label "Eccenca Reasoning Vocabulary"@en ; + rdfs:seeAlso . + + +### https://ns.eccenca.com/reasoning/e02aaed014c94e0c91bf960fed127750/vocab/cat_owner +:cat_owner rdf:type owl:Class ; + owl:equivalentClass [ owl:intersectionOf ( :person + [ rdf:type owl:Restriction ; + owl:onProperty :has_pet ; + owl:someValuesFrom :cat + ] + ) ; + rdf:type owl:Class + ] ; + rdfs:comment ""^^xsd:string ; + rdfs:isDefinedBy ; + rdfs:label "cat owner"^^xsd:string . \ No newline at end of file diff --git a/tests/test_validate.md b/tests/test_validate.md index f0ee2ce..f7a6f74 100644 --- a/tests/test_validate.md +++ b/tests/test_validate.md @@ -6,14 +6,14 @@ # Axiom Impact ## Axioms used 1 times -- [A](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/A) SubClassOf [B](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/B) [vocab] -- [A](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/A) DisjointWith [B](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/B) [vocab] -- [D_6](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/D_6) Type [A](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/A) [vocab] +- [A](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/A) SubClassOf [B](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/B) [] +- [A](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/A) DisjointWith [B](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/B) [] +- [D_6](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/D_6) Type [A](https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab/A) [] # Ontologies used: -- vocab (https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab) +- (https://ns.eccenca.com/validateontology/e02aaed014c94e0c91bf960fed127750/vocab3/) diff --git a/tests/test_validate_ontology_1.ttl b/tests/test_validate_ontology_1.ttl new file mode 100644 index 0000000..f27b0c2 --- /dev/null +++ b/tests/test_validate_ontology_1.ttl @@ -0,0 +1,9 @@ +@prefix : . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@base . + + rdf:type owl:Ontology ; + owl:imports . + diff --git a/tests/test_validate_ontology_2.ttl b/tests/test_validate_ontology_2.ttl new file mode 100644 index 0000000..008cd76 --- /dev/null +++ b/tests/test_validate_ontology_2.ttl @@ -0,0 +1,9 @@ +@prefix : . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@base . + + rdf:type owl:Ontology ; + owl:imports . + diff --git a/tests/test_validate_ontology.ttl b/tests/test_validate_ontology_3.ttl similarity index 94% rename from tests/test_validate_ontology.ttl rename to tests/test_validate_ontology_3.ttl index e6fa516..2f5424e 100644 --- a/tests/test_validate_ontology.ttl +++ b/tests/test_validate_ontology_3.ttl @@ -2,9 +2,9 @@ @prefix owl: . @prefix rdf: . @prefix rdfs: . -@base . +@base . - rdf:type owl:Ontology . + rdf:type owl:Ontology . ################################################################# # Classes