Skip to content
This repository was archived by the owner on Oct 8, 2020. It is now read-only.

Commit 752e661

Browse files
RDFS vs RDFS Simple support.
1 parent 0459925 commit 752e661

10 files changed

Lines changed: 184 additions & 9 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
<spark.version>2.0.2</spark.version>
6060
<flink.version>1.1.3</flink.version>
6161
<jena.version>3.1.1</jena.version>
62-
<sansa.stack.version>0.0.1-SNAPSHOT</sansa.stack.version>
62+
<sansa.stack.version>0.1.0-SNAPSHOT</sansa.stack.version>
6363
<sansa.rdf.version>${sansa.stack.version}</sansa.rdf.version>
6464
<sansa.query.version>${sansa.stack.version}</sansa.query.version>
6565
<sansa.owl.version>${sansa.stack.version}</sansa.owl.version>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
2+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
3+
4+
rdf:type rdfs:range rdfs:Class .
5+
rdfs:Resource rdf:type rdfs:Class .
6+
rdfs:Literal rdf:type rdfs:Class .
7+
rdf:Statement rdf:type rdfs:Class .
8+
rdf:nil rdf:type rdf:List .
9+
rdf:subject rdf:type rdf:Property .
10+
rdf:object rdf:type rdf:Property .
11+
rdf:predicate rdf:type rdf:Property .
12+
rdf:first rdf:type rdf:Property .
13+
rdf:rest rdf:type rdf:Property .
14+
15+
rdfs:subPropertyOf rdfs:domain rdf:Property .
16+
rdfs:subClassOf rdfs:domain rdfs:Class .
17+
rdfs:domain rdfs:domain rdf:Property .
18+
rdfs:range rdfs:domain rdf:Property .
19+
rdf:subject rdfs:domain rdf:Statement .
20+
rdf:predicate rdfs:domain rdf:Statement .
21+
rdf:object rdfs:domain rdf:Statement .
22+
rdf:first rdfs:domain rdf:List .
23+
rdf:rest rdfs:domain rdf:List .
24+
25+
rdfs:subPropertyOf rdfs:range rdf:Property .
26+
rdfs:subClassOf rdfs:range rdfs:Class .
27+
rdfs:domain rdfs:range rdfs:Class .
28+
rdfs:range rdfs:range rdfs:Class .
29+
rdf:type rdfs:range rdfs:Class .
30+
rdfs:comment rdfs:range rdfs:Literal .
31+
rdfs:label rdfs:range rdfs:Literal .
32+
rdf:rest rdfs:range rdf:List .
33+
34+
rdf:Alt rdfs:subClassOf rdfs:Container .
35+
rdf:Bag rdfs:subClassOf rdfs:Container .
36+
rdf:Seq rdfs:subClassOf rdfs:Container .
37+
rdfs:ContainerMembershipProperty rdfs:subClassOf rdf:Property .
38+
39+
rdfs:isDefinedBy rdfs:subPropertyOf rdfs:seeAlso .
40+
41+
rdf:XMLLiteral rdf:type rdfs:Datatype .
42+
rdfs:Datatype rdfs:subClassOf rdfs:Class .
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package net.sansa_stack.inference.rules
2+
3+
/**
4+
* The ForwardRuleReasonerRDFS can be configured to work at three different compliance levels:
5+
*
6+
* <p>
7+
* <b>Full</b><br/>
8+
* This implements all of the RDFS axioms and closure rules with the exception of bNode entailments and datatypes
9+
* (rdfD 1). See above for comments on these. This is an expensive mode because all statements in the data graph
10+
* need to be checked for possible use of container membership properties. It also generates type assertions
11+
* for all resources and properties mentioned in the data (rdf1, rdfs4a, rdfs4b).
12+
*</p>
13+
*
14+
* <p>
15+
* <b>Default</b><br/>
16+
* This omits the expensive checks for container membership properties and the "everything is a resource" and
17+
* "everything used as a property is one" rules (rdf1, rdfs4a, rdfs4b).
18+
* This mode does include all the axiomatic rules. Thus, for example, even materializing an "empty" RDF graph will
19+
* return triples such as [rdf:type rdfs:range rdfs:Class].
20+
* </p>
21+
*
22+
* <p>
23+
* <b>Simple</b><br/>
24+
* This implements just the transitive closure of subPropertyOf and subClassOf relations, the domain and range
25+
* entailments and the implications of subPropertyOf and subClassOf. It omits all of the axioms. This is probably
26+
* the most useful mode but is not the default because it is a less complete implementation of the standard.
27+
* </p>
28+
*
29+
* @author Lorenz Buehmann
30+
*/
31+
object RDFSLevel extends Enumeration {
32+
type RDFSLevel = Value
33+
val FULL, DEFAULT, SIMPLE = Value
34+
}

sansa-inference-common/src/main/scala/net/sansa_stack/inference/rules/ReasoningProfile.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ package net.sansa_stack.inference.rules
77
*/
88
object ReasoningProfile extends Enumeration {
99
type ReasoningProfile = Value
10-
val RDFS, OWL_HORST, OWL_RL, OWL_EL = Value
10+
val RDFS, RDFS_SIMPLE, OWL_HORST, OWL_RL, OWL_EL = Value
1111

1212
/**
1313
* Returns the reasoning profile for the given name.

sansa-inference-flink/src/main/scala/net/sansa_stack/inference/flink/RDFGraphMaterializer.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import java.io.File
44

55
import net.sansa_stack.inference.flink.data.{RDFGraphLoader, RDFGraphWriter}
66
import net.sansa_stack.inference.flink.forwardchaining.{ForwardRuleReasonerOWLHorst, ForwardRuleReasonerRDFS}
7-
import net.sansa_stack.inference.rules.ReasoningProfile
87
import net.sansa_stack.inference.rules.ReasoningProfile._
8+
import net.sansa_stack.inference.rules.{RDFSLevel, ReasoningProfile}
99
import org.apache.flink.api.java.utils.ParameterTool
1010
import org.apache.flink.api.scala.ExecutionEnvironment
1111

@@ -44,6 +44,11 @@ object RDFGraphMaterializer {
4444
// create reasoner
4545
val reasoner = profile match {
4646
case RDFS => new ForwardRuleReasonerRDFS(env)
47+
case RDFS_SIMPLE => {
48+
val r = new ForwardRuleReasonerRDFS(env)
49+
r.level = RDFSLevel.SIMPLE
50+
r
51+
}
4752
case OWL_HORST => new ForwardRuleReasonerOWLHorst(env)
4853
}
4954

@@ -93,7 +98,7 @@ object RDFGraphMaterializer {
9398
opt[Unit]("sorted").optional().action( (_, c) =>
9499
c.copy(sortedOutput = true)).text("sorted output of the triples (per file)")
95100

96-
opt[ReasoningProfile]('p', "profile").required().valueName("{rdfs | owl-horst}").
101+
opt[ReasoningProfile]('p', "profile").required().valueName("{rdfs | rdfs-simple | owl-horst}").
97102
action((x, c) => c.copy(profile = x)).
98103
text("the reasoning profile")
99104

sansa-inference-flink/src/main/scala/net/sansa_stack/inference/flink/forwardchaining/ForwardRuleReasonerRDFS.scala

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import net.sansa_stack.inference.data.RDFTriple
77
import net.sansa_stack.inference.utils.CollectionUtils
88
import org.slf4j.LoggerFactory
99
import net.sansa_stack.inference.flink.utils.DataSetUtils.DataSetOps
10+
import net.sansa_stack.inference.rules.RDFSLevel._
11+
12+
import scala.collection.mutable
1013

1114
/**
1215
* A forward chaining implementation of the RDFS entailment regime.
@@ -19,6 +22,8 @@ class ForwardRuleReasonerRDFS(env: ExecutionEnvironment) extends ForwardRuleReas
1922

2023
private val logger = com.typesafe.scalalogging.Logger(LoggerFactory.getLogger(this.getClass.getName))
2124

25+
var level: RDFSLevel = DEFAULT
26+
2227
def apply(graph: RDFGraph): RDFGraph = {
2328
logger.info("materializing graph...")
2429
val startTime = System.currentTimeMillis()
@@ -113,7 +118,7 @@ class ForwardRuleReasonerRDFS(env: ExecutionEnvironment) extends ForwardRuleReas
113118
.flatMap(t => subClassOfMap(t.`object`).map(supCls => RDFTriple(t.subject, RDF.`type`.getURI, supCls))) // create triple (s a B)
114119

115120
// 5. merge triples and remove duplicates
116-
val allTriples = env.union(
121+
var allTriples = env.union(
117122
Seq(
118123
otherTriples,
119124
subClassOfTriplesTrans,
@@ -123,11 +128,49 @@ class ForwardRuleReasonerRDFS(env: ExecutionEnvironment) extends ForwardRuleReas
123128
triplesRDFS9))
124129
.distinct()
125130

131+
132+
// we perform also additional rules if enabled
133+
if(level != SIMPLE) {
134+
// rdfs1
135+
136+
// rdf1: (s p o) => (p rdf:type rdf:Property)
137+
138+
// rdfs4a: (s p o) => (s rdf:type rdfs:Resource)
139+
// rdfs4a: (s p o) => (o rdf:type rdfs:Resource)
140+
val rdfs4 = allTriples.flatMap(t => Set(
141+
RDFTriple(t.subject, RDF.`type`.getURI, RDFS.Resource.getURI),
142+
RDFTriple(t.`object`, RDF.`type`.getURI, RDFS.Resource.getURI)
143+
// RDFTriple(t.predicate, RDF.`type`.getURI, RDF.Property.getURI)
144+
))
145+
146+
//rdfs12: (?x rdf:type rdfs:ContainerMembershipProperty) -> (?x rdfs:subPropertyOf rdfs:member)
147+
val rdfs12 = typeTriples
148+
.filter(t => t.`object` == RDFS.ContainerMembershipProperty.getURI)
149+
.map(t => RDFTriple(t.subject, RDF.`type`.getURI, RDFS.member.getURI))
150+
151+
// rdfs6: (p rdf:type rdf:Property) => (p rdfs:subPropertyOf p)
152+
val rdfs6 = typeTriples
153+
.filter(t => t.`object` == RDF.Property.getURI)
154+
.map(t => RDFTriple(t.subject, RDFS.subPropertyOf.getURI, t.subject))
155+
156+
// rdfs8: (s rdf:type rdfs:Class ) => (s rdfs:subClassOf rdfs:Resource)
157+
// rdfs10: (s rdf:type rdfs:Class) => (s rdfs:subClassOf s)
158+
val rdfs8_10 = typeTriples
159+
.filter(t => t.`object` == RDFS.Class.getURI)
160+
.flatMap(t => Set(
161+
RDFTriple(t.subject, RDFS.subClassOf.getURI, RDFS.Resource.getURI),
162+
RDFTriple(t.subject, RDFS.subClassOf.getURI, t.subject)))
163+
164+
val additionalTripleRDDs = mutable.Seq(rdfs4, rdfs6, rdfs8_10)
165+
166+
allTriples = env.union(Seq(allTriples) ++ additionalTripleRDDs).distinct()
167+
}
168+
126169
logger.info("...finished materialization in " + (System.currentTimeMillis() - startTime) + "ms.")
127170
// val newSize = allTriples.count()
128171
// logger.info(s"|G_inf|=$newSize")
129172

130173
// return graph with inferred triples
131174
RDFGraph(allTriples)
132175
}
133-
}
176+
}

sansa-inference-flink/src/test/scala/net/sansa_stack/inference/flink/conformance/SharedRDFSReasonerContext.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.sansa_stack.inference.flink.conformance
22

33
import net.sansa_stack.inference.flink.forwardchaining.{ForwardRuleReasoner, ForwardRuleReasonerRDFS}
4+
import net.sansa_stack.inference.rules.RDFSLevel
45
import org.apache.flink.api.scala.ExecutionEnvironment
56
import org.junit.runner.RunWith
67
import org.junit.runners.Parameterized
@@ -27,5 +28,6 @@ trait SharedRDFSReasonerContext extends BeforeAndAfterAll with ReasonerContextPr
2728
_env = ExecutionEnvironment.getExecutionEnvironment
2829
_env.getConfig.disableSysoutLogging()
2930
_reasoner = new ForwardRuleReasonerRDFS(env)
31+
_reasoner.level = RDFSLevel.SIMPLE
3032
}
3133
}

sansa-inference-spark/src/main/scala/net/sansa_stack/inference/spark/RDFGraphMaterializer.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package net.sansa_stack.inference.spark
33
import java.io.File
44

55
import net.sansa_stack.inference.data.RDFTriple
6-
import net.sansa_stack.inference.rules.ReasoningProfile
76
import net.sansa_stack.inference.rules.ReasoningProfile._
7+
import net.sansa_stack.inference.rules.{RDFSLevel, ReasoningProfile}
88
import net.sansa_stack.inference.spark.data.{RDFGraphLoader, RDFGraphWriter}
99
import net.sansa_stack.inference.spark.forwardchaining.{ForwardRuleReasonerOWLHorst, ForwardRuleReasonerRDFS}
1010
import org.apache.spark.SparkConf
@@ -51,6 +51,11 @@ object RDFGraphMaterializer {
5151
// create reasoner
5252
val reasoner = profile match {
5353
case RDFS => new ForwardRuleReasonerRDFS(session.sparkContext)
54+
case RDFS_SIMPLE => {
55+
val r = new ForwardRuleReasonerRDFS(session.sparkContext)
56+
r.level = RDFSLevel.SIMPLE
57+
r
58+
}
5459
case OWL_HORST => new ForwardRuleReasonerOWLHorst(session.sparkContext)
5560
}
5661

@@ -94,7 +99,7 @@ object RDFGraphMaterializer {
9499
opt[Unit]("sorted").optional().action( (_, c) =>
95100
c.copy(sortedOutput = true)).text("sorted output of the triples (per file)")
96101

97-
opt[ReasoningProfile]('p', "profile").required().valueName("{rdfs | owl-horst}").
102+
opt[ReasoningProfile]('p', "profile").required().valueName("{rdfs | rdfs-simple | owl-horst}").
98103
action((x, c) => c.copy(profile = x)).
99104
text("the reasoning profile")
100105

sansa-inference-spark/src/main/scala/net/sansa_stack/inference/spark/forwardchaining/ForwardRuleReasonerRDFS.scala

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ package net.sansa_stack.inference.spark.forwardchaining
33
import org.apache.jena.vocabulary.{RDF, RDFS}
44
import org.apache.spark.SparkContext
55
import net.sansa_stack.inference.data.RDFTriple
6+
import net.sansa_stack.inference.rules.RDFSLevel._
67
import net.sansa_stack.inference.spark.data.RDFGraph
78
import net.sansa_stack.inference.spark.utils.RDDUtils
89
import net.sansa_stack.inference.utils.CollectionUtils
910
import org.slf4j.LoggerFactory
1011
import net.sansa_stack.inference.spark.utils.RDDUtils.RDDOps
1112

13+
import scala.collection.mutable
14+
1215
/**
1316
* A forward chaining implementation of the RDFS entailment regime.
1417
*
@@ -20,6 +23,8 @@ class ForwardRuleReasonerRDFS(sc: SparkContext) extends ForwardRuleReasoner{
2023

2124
private val logger = com.typesafe.scalalogging.Logger(LoggerFactory.getLogger(this.getClass.getName))
2225

26+
var level: RDFSLevel = DEFAULT
27+
2328
def apply(graph: RDFGraph): RDFGraph = {
2429
logger.info("materializing graph...")
2530
val startTime = System.currentTimeMillis()
@@ -124,7 +129,7 @@ class ForwardRuleReasonerRDFS(sc: SparkContext) extends ForwardRuleReasoner{
124129
.setName("rdfs9")
125130

126131
// 5. merge triples and remove duplicates
127-
val allTriples = sc.union(Seq(
132+
var allTriples = sc.union(Seq(
128133
otherTriples,
129134
subClassOfTriplesTrans,
130135
subPropertyOfTriplesTrans,
@@ -133,6 +138,43 @@ class ForwardRuleReasonerRDFS(sc: SparkContext) extends ForwardRuleReasoner{
133138
triplesRDFS9))
134139
.distinct()
135140

141+
// we perform also additional rules if enabled
142+
if(level != SIMPLE) {
143+
// rdfs1
144+
145+
// rdf1: (s p o) => (p rdf:type rdf:Property)
146+
147+
// rdfs4a: (s p o) => (s rdf:type rdfs:Resource)
148+
// rdfs4a: (s p o) => (o rdf:type rdfs:Resource)
149+
val rdfs4 = allTriples.flatMap(t => Set(
150+
RDFTriple(t.subject, RDF.`type`.getURI, RDFS.Resource.getURI),
151+
RDFTriple(t.`object`, RDF.`type`.getURI, RDFS.Resource.getURI)
152+
// RDFTriple(t.predicate, RDF.`type`.getURI, RDF.Property.getURI)
153+
))
154+
155+
//rdfs12: (?x rdf:type rdfs:ContainerMembershipProperty) -> (?x rdfs:subPropertyOf rdfs:member)
156+
val rdfs12 = typeTriples
157+
.filter(t => t.`object` == RDFS.ContainerMembershipProperty.getURI)
158+
.map(t => RDFTriple(t.subject, RDF.`type`.getURI, RDFS.member.getURI))
159+
160+
// rdfs6: (p rdf:type rdf:Property) => (p rdfs:subPropertyOf p)
161+
val rdfs6 = typeTriples
162+
.filter(t => t.`object` == RDF.Property.getURI)
163+
.map(t => RDFTriple(t.subject, RDFS.subPropertyOf.getURI, t.subject))
164+
165+
// rdfs8: (s rdf:type rdfs:Class ) => (s rdfs:subClassOf rdfs:Resource)
166+
// rdfs10: (s rdf:type rdfs:Class) => (s rdfs:subClassOf s)
167+
val rdfs8_10 = typeTriples
168+
.filter(t => t.`object` == RDFS.Class.getURI)
169+
.flatMap(t => Set(
170+
RDFTriple(t.subject, RDFS.subClassOf.getURI, RDFS.Resource.getURI),
171+
RDFTriple(t.subject, RDFS.subClassOf.getURI, t.subject)))
172+
173+
val additionalTripleRDDs = mutable.Seq(rdfs4, rdfs6, rdfs8_10)
174+
175+
allTriples = sc.union(Seq(allTriples) ++ additionalTripleRDDs).distinct()
176+
}
177+
136178
logger.info("...finished materialization in " + (System.currentTimeMillis() - startTime) + "ms.")
137179
// val newSize = allTriples.count()
138180
// logger.info(s"|G_inf|=$newSize")

sansa-inference-spark/src/test/scala/net/sansa_stack/inference/spark/conformance/SharedRDFSReasonerContext.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.sansa_stack.inference.spark.conformance
22

33
import com.holdenkarau.spark.testing.SharedSparkContext
4+
import net.sansa_stack.inference.rules.RDFSLevel
45
import net.sansa_stack.inference.spark.forwardchaining.{ForwardRuleReasoner, ForwardRuleReasonerRDFS}
56
import org.scalatest.{BeforeAndAfterAll, Suite}
67

@@ -19,6 +20,7 @@ trait SharedRDFSReasonerContext extends SharedSparkContext with ReasonerContextP
1920
override def beforeAll(): Unit = {
2021
super.beforeAll()
2122
_reasoner = new ForwardRuleReasonerRDFS(sc)
23+
_reasoner.level = RDFSLevel.SIMPLE
2224
}
2325

2426
}

0 commit comments

Comments
 (0)