diff options
author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-08-16 16:27:41 +0100 |
---|---|---|
committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-08-16 16:27:41 +0100 |
commit | 99b932a358e0fcf5b463c3a98fb12fdfa393152c (patch) | |
tree | 9a78d5363937a2707cf516f37f48d2d0c65db5ae /src/main/scala/rsacomb/RDFoxClassExprConverter.scala | |
parent | 6fc6fc2bde597c79e66c3dbf8e3a1f94526ea672 (diff) | |
download | RSAComb-99b932a358e0fcf5b463c3a98fb12fdfa393152c.tar.gz RSAComb-99b932a358e0fcf5b463c3a98fb12fdfa393152c.zip |
Include built-in rules in RSA check
Diffstat (limited to 'src/main/scala/rsacomb/RDFoxClassExprConverter.scala')
-rw-r--r-- | src/main/scala/rsacomb/RDFoxClassExprConverter.scala | 165 |
1 files changed, 98 insertions, 67 deletions
diff --git a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala index 227c25b..9116be0 100644 --- a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala +++ b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala | |||
@@ -1,12 +1,29 @@ | |||
1 | package rsacomb | 1 | package rsacomb |
2 | 2 | ||
3 | import scala.collection.JavaConverters._ | 3 | import scala.collection.JavaConverters._ |
4 | import java.util.stream.{Stream,Collectors} | 4 | import java.util.stream.{Stream, Collectors} |
5 | 5 | ||
6 | import org.semanticweb.owlapi.model.{OWLClassExpression, OWLClass, OWLObjectSomeValuesFrom, OWLObjectIntersectionOf, OWLObjectOneOf, OWLObjectMaxCardinality} | 6 | import org.semanticweb.owlapi.model.{ |
7 | OWLClassExpression, | ||
8 | OWLClass, | ||
9 | OWLObjectSomeValuesFrom, | ||
10 | OWLObjectIntersectionOf, | ||
11 | OWLObjectOneOf, | ||
12 | OWLObjectMaxCardinality | ||
13 | } | ||
7 | import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx | 14 | import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx |
8 | import tech.oxfordsemantic.jrdfox.logic.{BindAtom, BuiltinFunctionCall, TupleTableName} | 15 | import tech.oxfordsemantic.jrdfox.logic.{ |
9 | import tech.oxfordsemantic.jrdfox.logic.{Atom, Term, Variable, Literal, Datatype} | 16 | BindAtom, |
17 | BuiltinFunctionCall, | ||
18 | TupleTableName | ||
19 | } | ||
20 | import tech.oxfordsemantic.jrdfox.logic.{ | ||
21 | Atom, | ||
22 | Term, | ||
23 | Variable, | ||
24 | Literal, | ||
25 | Datatype | ||
26 | } | ||
10 | 27 | ||
11 | import rsacomb.SkolemStrategy | 28 | import rsacomb.SkolemStrategy |
12 | import rsacomb.RDFoxRuleShards | 29 | import rsacomb.RDFoxRuleShards |
@@ -16,87 +33,100 @@ import org.semanticweb.owlapi.model.OWLObjectProperty | |||
16 | object RDFoxClassExprConverter { | 33 | object RDFoxClassExprConverter { |
17 | 34 | ||
18 | def apply( | 35 | def apply( |
19 | term : Term = Variable.create("x"), | 36 | term: Term = Variable.create("x"), |
20 | skolem : SkolemStrategy = SkolemStrategy.None, | 37 | skolem: SkolemStrategy = SkolemStrategy.None, |
21 | unsafe : List[OWLObjectPropertyExpression] = List() | 38 | unsafe: List[OWLObjectPropertyExpression] = List() |
22 | ) : RDFoxClassExprConverter = | 39 | ): RDFoxClassExprConverter = |
23 | new RDFoxClassExprConverter(term, skolem, unsafe) | 40 | new RDFoxClassExprConverter(term, skolem, unsafe) |
24 | 41 | ||
25 | def merge(rules : List[RDFoxRuleShards]) : RDFoxRuleShards = { | 42 | def merge(rules: List[RDFoxRuleShards]): RDFoxRuleShards = { |
26 | rules.foldLeft(RDFoxRuleShards(List(),List())) { | 43 | rules.foldLeft(RDFoxRuleShards(List(), List())) { (r1, r2) => |
27 | (r1,r2) => | 44 | RDFoxRuleShards( |
28 | RDFoxRuleShards( | 45 | r1.res ++ r2.res, |
29 | r1.res ++ r2.res, | 46 | r1.ext ++ r2.ext |
30 | r1.ext ++ r2.ext | 47 | ) |
31 | ) | ||
32 | } | 48 | } |
33 | } | 49 | } |
34 | 50 | ||
35 | } // object RDFoxClassExprConverter | 51 | } // object RDFoxClassExprConverter |
36 | 52 | ||
37 | class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy, unsafe : List[OWLObjectPropertyExpression]) | 53 | class RDFoxClassExprConverter( |
38 | extends OWLClassExpressionVisitorEx[RDFoxRuleShards] | 54 | term: Term, |
39 | { | 55 | skolem: SkolemStrategy, |
56 | unsafe: List[OWLObjectPropertyExpression] | ||
57 | ) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] { | ||
40 | 58 | ||
41 | // OWLClass | 59 | // OWLClass |
42 | override | 60 | override def visit(expr: OWLClass): RDFoxRuleShards = { |
43 | def visit(expr : OWLClass) : RDFoxRuleShards = { | ||
44 | val name = expr.getIRI.getIRIString | 61 | val name = expr.getIRI.getIRIString |
45 | val atom = List(Atom.create(TupleTableName.create(name), term)) | 62 | val atom = List(Atom.create(TupleTableName.create(name), term)) |
46 | RDFoxRuleShards(atom,List()) | 63 | RDFoxRuleShards(atom, List()) |
47 | } | 64 | } |
48 | 65 | ||
49 | // OWLObjectIntersectionOf | 66 | // OWLObjectIntersectionOf |
50 | override | 67 | override def visit(expr: OWLObjectIntersectionOf): RDFoxRuleShards = { |
51 | def visit(expr : OWLObjectIntersectionOf) : RDFoxRuleShards = { | ||
52 | val visitor = new RDFoxClassExprConverter(term, skolem, unsafe) | 68 | val visitor = new RDFoxClassExprConverter(term, skolem, unsafe) |
53 | // TODO: maybe using `flatMap` instead of `merge` + `map` works as well | 69 | // TODO: maybe using `flatMap` instead of `merge` + `map` works as well |
54 | RDFoxClassExprConverter.merge ( | 70 | RDFoxClassExprConverter.merge( |
55 | expr.asConjunctSet.asScala.toList | 71 | expr.asConjunctSet.asScala.toList |
56 | .map((e : OWLClassExpression) => e.accept(visitor)) | 72 | .map((e: OWLClassExpression) => e.accept(visitor)) |
57 | ) | 73 | ) |
58 | } | 74 | } |
59 | 75 | ||
60 | // OWLObjectOneOf | 76 | // OWLObjectOneOf |
61 | override | 77 | override def visit(expr: OWLObjectOneOf): RDFoxRuleShards = { |
62 | def visit(expr : OWLObjectOneOf) : RDFoxRuleShards = { | 78 | val visitor = RDFoxClassExprConverter(term, skolem) |
63 | val visitor = RDFoxClassExprConverter(term,skolem) | ||
64 | // TODO: review nominal handling. Here we are taking "just" one | 79 | // TODO: review nominal handling. Here we are taking "just" one |
65 | val ind = expr.individuals.collect(Collectors.toList()).asScala | 80 | val ind = expr.individuals |
66 | .filter(_.isOWLNamedIndividual) | 81 | .collect(Collectors.toList()) |
67 | .head // restricts to proper "nominals" | 82 | .asScala |
68 | .asOWLNamedIndividual.getIRI.getIRIString | 83 | .filter(_.isOWLNamedIndividual) |
69 | val atom = List(Atom.create( | 84 | .head // restricts to proper "nominals" |
70 | TupleTableName.create("owl:sameAs"), term, Literal.create(ind, Datatype.IRI_REFERENCE) | 85 | .asOWLNamedIndividual |
71 | )) | 86 | .getIRI |
72 | RDFoxRuleShards(atom,List()) | 87 | .getIRIString |
88 | val atom = List( | ||
89 | Atom.sameAs(term, Literal.create(ind, Datatype.IRI_REFERENCE)) | ||
90 | ) | ||
91 | RDFoxRuleShards(atom, List()) | ||
73 | } | 92 | } |
74 | 93 | ||
75 | // OWLObjectSomeValuesFrom | 94 | // OWLObjectSomeValuesFrom |
76 | override | 95 | override def visit(expr: OWLObjectSomeValuesFrom): RDFoxRuleShards = { |
77 | def visit(expr : OWLObjectSomeValuesFrom) : RDFoxRuleShards = { | ||
78 | // TODO: variables needs to be handled at visitor level. Hardcoding | 96 | // TODO: variables needs to be handled at visitor level. Hardcoding |
79 | // the name of the varibles might lead to errors for complex cases. | 97 | // the name of the varibles might lead to errors for complex cases. |
80 | val y = Variable.create("y") | 98 | val y = Variable.create("y") |
81 | val prop = expr.getProperty() | 99 | val prop = expr.getProperty() |
82 | // Computes the result of rule skolemization. Depending on the used | 100 | // Computes the result of rule skolemization. Depending on the used |
83 | // technique it might involve the introduction of additional atoms, | 101 | // technique it might involve the introduction of additional atoms, |
84 | // and/or fresh constants and variables. | 102 | // and/or fresh constants and variables. |
85 | val (head, body, term1) = skolem match { | 103 | val (head, body, term1) = skolem match { |
86 | case SkolemStrategy.None => (List(), List(), y) | 104 | case SkolemStrategy.None => (List(), List(), y) |
87 | case SkolemStrategy.Constant(c) => (List(), List(), Literal.create(c, Datatype.IRI_REFERENCE)) | 105 | case SkolemStrategy.Constant(c) => |
88 | case SkolemStrategy.ConstantRSA(c) => { | 106 | (List(), List(), Literal.create(c, Datatype.IRI_REFERENCE)) |
89 | val lit = Literal.create(c, Datatype.IRI_REFERENCE) | 107 | case SkolemStrategy.ConstantRSA(c) => { |
90 | if (unsafe.contains(prop)) | 108 | val lit = Literal.create(c, Datatype.IRI_REFERENCE) |
91 | (List(Atom.create(TupleTableName.create("internal:PE"),term,lit), Atom.create(TupleTableName.create("internal:U"),lit)), List(), lit) | 109 | if (unsafe.contains(prop)) |
92 | else | 110 | ( |
93 | (List(), List(), lit) | 111 | List( |
94 | } | 112 | Atom.create(TupleTableName.create("internal:PE"), term, lit), |
95 | case SkolemStrategy.Standard(f) => | 113 | Atom.create(TupleTableName.create("internal:U"), lit) |
96 | // At the time of writing the RDFox library does not have a | 114 | ), |
97 | // particular class for the "SKOLEM" operator and it is instead | 115 | List(), |
98 | // a simple builtin function with a "special" name. | 116 | lit |
99 | (List(),List(BindAtom.create(BuiltinFunctionCall.create("SKOLEM",term),y)),y) | 117 | ) |
118 | else | ||
119 | (List(), List(), lit) | ||
120 | } | ||
121 | case SkolemStrategy.Standard(f) => | ||
122 | // At the time of writing the RDFox library does not have a | ||
123 | // particular class for the "SKOLEM" operator and it is instead | ||
124 | // a simple builtin function with a "special" name. | ||
125 | ( | ||
126 | List(), | ||
127 | List(BindAtom.create(BuiltinFunctionCall.create("SKOLEM", term), y)), | ||
128 | y | ||
129 | ) | ||
100 | } | 130 | } |
101 | val classVisitor = new RDFoxClassExprConverter(term1, skolem, unsafe) | 131 | val classVisitor = new RDFoxClassExprConverter(term1, skolem, unsafe) |
102 | val classResult = expr.getFiller.accept(classVisitor) | 132 | val classResult = expr.getFiller.accept(classVisitor) |
@@ -109,25 +139,26 @@ class RDFoxClassExprConverter(term : Term, skolem : SkolemStrategy, unsafe : Lis | |||
109 | } | 139 | } |
110 | 140 | ||
111 | // OWLObjectMaxCardinality | 141 | // OWLObjectMaxCardinality |
112 | override | 142 | override def visit(expr: OWLObjectMaxCardinality): RDFoxRuleShards = { |
113 | def visit(expr : OWLObjectMaxCardinality) : RDFoxRuleShards = { | ||
114 | // TODO: again, no hardcoded variables | 143 | // TODO: again, no hardcoded variables |
115 | val vars = List(Variable.create("y"),Variable.create("z")) | 144 | val vars = List(Variable.create("y"), Variable.create("z")) |
116 | val classResult = RDFoxClassExprConverter.merge( | 145 | val classResult = RDFoxClassExprConverter.merge( |
117 | vars.map(new RDFoxClassExprConverter(_,skolem, unsafe)) | 146 | vars |
118 | .map(expr.getFiller.accept(_)) | 147 | .map(new RDFoxClassExprConverter(_, skolem, unsafe)) |
148 | .map(expr.getFiller.accept(_)) | ||
119 | ) | 149 | ) |
120 | val propertyResult = | 150 | val propertyResult = |
121 | vars.map(new RDFoxPropertyExprConverter(term,_,skolem)) | 151 | vars |
122 | .map(expr.getProperty.accept(_)) | 152 | .map(new RDFoxPropertyExprConverter(term, _, skolem)) |
123 | .flatten | 153 | .map(expr.getProperty.accept(_)) |
154 | .flatten | ||
124 | RDFoxRuleShards( | 155 | RDFoxRuleShards( |
125 | List(Atom.create(TupleTableName.create("owl:sameAs"),vars(0),vars(1))), | 156 | List(Atom.create(TupleTableName.create("owl:sameAs"), vars(0), vars(1))), |
126 | classResult.res ++ propertyResult | 157 | classResult.res ++ propertyResult |
127 | ) | 158 | ) |
128 | } | 159 | } |
129 | 160 | ||
130 | def doDefault(expr : OWLClassExpression) : RDFoxRuleShards = | 161 | def doDefault(expr: OWLClassExpression): RDFoxRuleShards = |
131 | RDFoxRuleShards(List(),List()) | 162 | RDFoxRuleShards(List(), List()) |
132 | 163 | ||
133 | } // class RDFoxClassExprConverter | 164 | } // class RDFoxClassExprConverter |