Skip to content

Commit

Permalink
Fixed cardinality checking bug on SADL with "uProp describes { This o…
Browse files Browse the repository at this point in the history
…r That } with a single value of type string"
  • Loading branch information
Paul Cuddihy committed Aug 7, 2023
1 parent d0f40d1 commit 9854ed3
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -556,18 +556,32 @@ public static String generateConstructConnected(SparqlConnection conn, OntologyI
* @throws Exception
*/
public static String generateGetCardinalityRestrictions(SparqlConnection conn, OntologyInfo oInfo) throws Exception {
StringBuffer sparql = new StringBuffer();
sparql.append("SELECT DISTINCT ?class ?property ?restriction ?limit \n");
sparql.append(generateSparqlFromOrUsing("", "FROM", conn, oInfo) + "\n");
sparql.append("WHERE { \n");
sparql.append(" ?r a <http://www.w3.org/2002/07/owl#Restriction>. \n");
sparql.append(" ?r <http://www.w3.org/2002/07/owl#onProperty> ?property. \n");
// note: very weird that the class is subClassOf the restriction -Paul
sparql.append(" OPTIONAL { ?class <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?r. } \n");
sparql.append(" ?r ?restriction ?limit. \n");
sparql.append(" FILTER REGEX (str(?restriction), \"ardinality\" ). \n");
sparql.append("} ORDER BY ?class ?property ?restriction \n");
return sparql.toString();
String ret = "PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n"
+ "PREFIX owl:<http://www.w3.org/2002/07/owl#> \n"
+ " \n"
+ "SELECT DISTINCT ?class ?property ?restriction ?limit \n"
+ " \n"
+ generateSparqlFromOrUsing("", "FROM", conn, oInfo) + "\n"
+ " \n"
+ "WHERE { \n"
+ " ?r a <http://www.w3.org/2002/07/owl#Restriction>. \n"
+ " ?r <http://www.w3.org/2002/07/owl#onProperty> ?property. \n"
+ " OPTIONAL { \n"
+ " { \n"
+ " ?class <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?r. \n"
+ genBlankNodeFilterStatement("?class", false) + "\n"
+ " } union { \n"
+ " ?un <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?r . \n"
+ " ?un owl:unionOf ?list . \n"
+ " ?list rdf:rest* ?item . \n"
+ " ?item rdf:first ?class. \n"
+ " } \n"
+ " } \n"
+ " ?r ?restriction ?limit. \n"
+ " FILTER REGEX (str(?restriction), \"ardinality\" ). \n"
+ "} ORDER BY ?class ?property ?restriction \n"
;
return ret;
}

/**
Expand All @@ -577,14 +591,14 @@ public static String generateGetCardinalityRestrictions(SparqlConnection conn, O
* @param domain
* @return
*/
public static String generateGetDatatypeRestriction(String graphName, String domain){
public static String generateGetDatatypeRestriction(String graphName, String domain, SparqlConnection conn, OntologyInfo oInfo) throws Exception {

// SADL makes datatypes either owl:onDatatype or a union of objects w/o the onDatatype predicate (curious)
String retval = "PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n" +
"PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX owl:<http://www.w3.org/2002/07/owl#> \n" +
"SELECT DISTINCT ?dataType ?equivType ?r_pred ?r_obj \n" +
" FROM <http://junit/GG2NQYY2E/200001934/both> \n" +
generateSparqlFromOrUsing("", "FROM", conn, oInfo) + "\n" +
"WHERE { \n" +
" ?dataType rdf:type rdfs:Datatype . \n" +
genDomainFilterStatement("dataType", domain, "") + "\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,35 @@ public void testOverrideStricter() throws Exception {
IntegrationTestUtility.compareResults(violationsTable.toCSVString(), this, "cardinality_testStricter_results_concise.csv"); // csv file contains expected violations in concise format
}

@Test
public void testWithSadlDescribesUnion() throws Exception {
// testing this type of SADL:
// myProp describes { This or That } with a single value of type string.

// setup
TestGraph.clearGraph();
TestGraph.uploadOwlResource(this, "CardinalityDescUnion.owl");
SparqlConnection conn = TestGraph.getSparqlConn();
OntologyInfo oInfo = new OntologyInfo(conn);
RestrictionChecker checker = new RestrictionChecker(conn, oInfo);

// check both restrictions
assertTrue(checker.hasCardinalityRestriction("http://CardinalityDescUnion#Class1", "http://CardinalityDescUnion#uProp"));
assertTrue(checker.hasCardinalityRestriction("http://CardinalityDescUnion#Class1", "http://CardinalityDescUnion#uProp"));

// check restrictions are exactly 1
assertTrue("1 did not satisfy 'exactly 1' cardinality", checker.satisfiesCardinality("http://CardinalityDescUnion#Class1", "http://CardinalityDescUnion#uProp", 1));
assertFalse("2 did satisfied 'exactly 1' cardinality", checker.satisfiesCardinality("http://CardinalityDescUnion#Class1", "http://CardinalityDescUnion#uProp", 2));
assertFalse("0 did satisfied 'exactly 1' cardinality", checker.satisfiesCardinality("http://CardinalityDescUnion#Class1", "http://CardinalityDescUnion#uProp", 0));
assertTrue("1 did not satisfy 'exactly 1' cardinality", checker.satisfiesCardinality("http://CardinalityDescUnion#Class2", "http://CardinalityDescUnion#uProp", 1));
assertFalse("2 did satisfied 'exactly 1' cardinality", checker.satisfiesCardinality("http://CardinalityDescUnion#Class2", "http://CardinalityDescUnion#uProp", 2));
assertFalse("0 did satisfied 'exactly 1' cardinality", checker.satisfiesCardinality("http://CardinalityDescUnion#Class2", "http://CardinalityDescUnion#uProp", 0));

// find one violation on Class2
Table violationsTable = checker.getCardinalityViolations(false);
assertEquals(violationsTable.getNumRows(), 1);
assertTrue(violationsTable.getCell(0, 0).endsWith("#Class2"));

}

}
45 changes: 45 additions & 0 deletions sparqlGraphLibrary/src/test/resources/CardinalityDescUnion.owl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:builtinfunctions="http://sadl.org/builtinfunctions#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:sadlimplicitmodel="http://sadl.org/sadlimplicitmodel#"
xmlns="http://CardinalityDescUnion#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:sadlbasemodel="http://sadl.org/sadlbasemodel#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xml:base="http://CardinalityDescUnion">
<owl:Ontology rdf:about="">
<owl:imports rdf:resource="http://sadl.org/builtinfunctions"/>
<owl:imports rdf:resource="http://sadl.org/sadlimplicitmodel"/>
<owl:imports rdf:resource="http://sadl.org/sadlbasemodel"/>
<rdfs:comment xml:lang="en">This ontology was created from a SADL file 'CardinalityDescUnion.sadl' and should not be directly edited.</rdfs:comment>
</owl:Ontology>
<owl:Class rdf:ID="Class2"/>
<owl:Class rdf:ID="Class1"/>
<owl:DatatypeProperty rdf:ID="uProp">
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<rdfs:domain>
<owl:Class>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onDataRange rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<owl:qualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#long"
>1</owl:qualifiedCardinality>
<owl:onProperty rdf:resource="#uProp"/>
</owl:Restriction>
</rdfs:subClassOf>
<owl:unionOf rdf:parseType="Collection">
<owl:Class rdf:about="#Class1"/>
<owl:Class rdf:about="#Class2"/>
</owl:unionOf>
</owl:Class>
</rdfs:domain>
</owl:DatatypeProperty>
<Class1 rdf:ID="Instance1a">
<uProp>first 1a</uProp>
</Class1>
<Class2 rdf:ID="Instance2a">
<uProp>second 2a</uProp>
<uProp>first 2a</uProp>
</Class2>
</rdf:RDF>
13 changes: 13 additions & 0 deletions sparqlGraphLibrary/src/test/resources/CardinalityDescUnion.sadl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
uri "http://CardinalityDescUnion".

Class1 is a class.
Class2 is a class.

uProp describes { Class1 or Class2 } with a single value of type string.

Instance1a is a Class1,
with uProp "first 1a".

Instance2a is a Class2,
with uProp "first 2a" ,
with uProp "second 2a".

0 comments on commit 9854ed3

Please sign in to comment.