diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-09-07 13:08:31 +0200 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2020-09-07 13:08:31 +0200 |
| commit | 2b661f3ac6fdb5156168b6775ede24e4c7b53758 (patch) | |
| tree | 0e3514c38fedf41febff82e9bf93aea2ab4d7a7f /src/main/scala/rsacomb/RSAAxiom.scala | |
| parent | 7e126824e9a6cb456295d2f1535aef975bb63237 (diff) | |
| download | RSAComb-2b661f3ac6fdb5156168b6775ede24e4c7b53758.tar.gz RSAComb-2b661f3ac6fdb5156168b6775ede24e4c7b53758.zip | |
Add setup code to compute the RSA filtering program
Not all rules of the filtering program have been implemented, but the
code for the generation and reification of the rules seems to work.
Diffstat (limited to 'src/main/scala/rsacomb/RSAAxiom.scala')
| -rw-r--r-- | src/main/scala/rsacomb/RSAAxiom.scala | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/src/main/scala/rsacomb/RSAAxiom.scala b/src/main/scala/rsacomb/RSAAxiom.scala index 9e9a016..50dc37e 100644 --- a/src/main/scala/rsacomb/RSAAxiom.scala +++ b/src/main/scala/rsacomb/RSAAxiom.scala | |||
| @@ -1,10 +1,23 @@ | |||
| 1 | package rsacomb | 1 | package rsacomb |
| 2 | 2 | ||
| 3 | /* Java imports */ | 3 | /* Java imports */ |
| 4 | import org.semanticweb.owlapi.model.{OWLAxiom,OWLSubClassOfAxiom, OWLEquivalentClassesAxiom} | 4 | import org.semanticweb.owlapi.model.{ |
| 5 | import org.semanticweb.owlapi.model.{OWLObjectPropertyExpression,OWLClass,OWLClassExpression,OWLObjectSomeValuesFrom,OWLObjectMaxCardinality} | 5 | OWLAxiom, |
| 6 | OWLSubClassOfAxiom, | ||
| 7 | OWLEquivalentClassesAxiom | ||
| 8 | } | ||
| 9 | import org.semanticweb.owlapi.model.{ | ||
| 10 | OWLObjectPropertyExpression, | ||
| 11 | OWLClass, | ||
| 12 | OWLClassExpression, | ||
| 13 | OWLObjectSomeValuesFrom, | ||
| 14 | OWLObjectMaxCardinality | ||
| 15 | } | ||
| 6 | import org.semanticweb.owlapi.model.ClassExpressionType | 16 | import org.semanticweb.owlapi.model.ClassExpressionType |
| 7 | import org.semanticweb.owlapi.model.{OWLAxiomVisitorEx,OWLClassExpressionVisitorEx} | 17 | import org.semanticweb.owlapi.model.{ |
| 18 | OWLAxiomVisitorEx, | ||
| 19 | OWLClassExpressionVisitorEx | ||
| 20 | } | ||
| 8 | 21 | ||
| 9 | /* Wrapper trait for the implicit class `RSAAxiom`. | 22 | /* Wrapper trait for the implicit class `RSAAxiom`. |
| 10 | */ | 23 | */ |
| @@ -16,10 +29,10 @@ trait RSAAxiom { | |||
| 16 | */ | 29 | */ |
| 17 | private sealed trait RSAAxiomType | 30 | private sealed trait RSAAxiomType |
| 18 | private object RSAAxiomType { | 31 | private object RSAAxiomType { |
| 19 | case object T3 extends RSAAxiomType // ∃R.A ⊑ B | 32 | case object T3 extends RSAAxiomType // ∃R.A ⊑ B |
| 20 | case object T3top extends RSAAxiomType // ∃R.⊤ ⊑ B | 33 | case object T3top extends RSAAxiomType // ∃R.⊤ ⊑ B |
| 21 | case object T4 extends RSAAxiomType // A ⊑ ≤1R.B | 34 | case object T4 extends RSAAxiomType // A ⊑ ≤1R.B |
| 22 | case object T5 extends RSAAxiomType // A ⊑ ∃R.B | 35 | case object T5 extends RSAAxiomType // A ⊑ ∃R.B |
| 23 | } | 36 | } |
| 24 | 37 | ||
| 25 | /* Implements additional features on top of `OWLAxiom` from | 38 | /* Implements additional features on top of `OWLAxiom` from |
| @@ -32,20 +45,22 @@ trait RSAAxiom { | |||
| 32 | * In order to reason about role unsafety in Horn-ALCHOIQ | 45 | * In order to reason about role unsafety in Horn-ALCHOIQ |
| 33 | * ontologies we need to detect and filter axioms by their | 46 | * ontologies we need to detect and filter axioms by their |
| 34 | * "type". | 47 | * "type". |
| 35 | * | 48 | * |
| 36 | * This is a simple implementation following the Visitor | 49 | * This is a simple implementation following the Visitor |
| 37 | * pattern imposed by the OWLAPI. | 50 | * pattern imposed by the OWLAPI. |
| 38 | */ | 51 | */ |
| 39 | private class RSAAxiomTypeDetector(t: RSAAxiomType) | 52 | private class RSAAxiomTypeDetector(t: RSAAxiomType) |
| 40 | extends OWLAxiomVisitorEx[Boolean] | 53 | extends OWLAxiomVisitorEx[Boolean] { |
| 41 | { | 54 | override def visit(axiom: OWLSubClassOfAxiom): Boolean = { |
| 42 | override | ||
| 43 | def visit(axiom: OWLSubClassOfAxiom): Boolean = { | ||
| 44 | val sub = axiom.getSubClass().getClassExpressionType() | 55 | val sub = axiom.getSubClass().getClassExpressionType() |
| 45 | val sup = axiom.getSuperClass().getClassExpressionType() | 56 | val sup = axiom.getSuperClass().getClassExpressionType() |
| 46 | t match { | 57 | t match { |
| 47 | case RSAAxiomType.T3top => // ∃R.⊤ ⊑ B | 58 | case RSAAxiomType.T3top => // ∃R.⊤ ⊑ B |
| 48 | axiom.isT5 && axiom.getSubClass().asInstanceOf[OWLObjectSomeValuesFrom].getFiller.isOWLThing | 59 | axiom.isT3 && axiom |
| 60 | .getSubClass() | ||
| 61 | .asInstanceOf[OWLObjectSomeValuesFrom] | ||
| 62 | .getFiller | ||
| 63 | .isOWLThing | ||
| 49 | case RSAAxiomType.T3 => // ∃R.A ⊑ B | 64 | case RSAAxiomType.T3 => // ∃R.A ⊑ B |
| 50 | sub == ClassExpressionType.OBJECT_SOME_VALUES_FROM && sup == ClassExpressionType.OWL_CLASS | 65 | sub == ClassExpressionType.OBJECT_SOME_VALUES_FROM && sup == ClassExpressionType.OWL_CLASS |
| 51 | case RSAAxiomType.T4 => // A ⊑ ≤1R.B | 66 | case RSAAxiomType.T4 => // A ⊑ ≤1R.B |
| @@ -55,13 +70,12 @@ trait RSAAxiom { | |||
| 55 | } | 70 | } |
| 56 | } | 71 | } |
| 57 | 72 | ||
| 58 | override | 73 | override def visit(axiom: OWLEquivalentClassesAxiom): Boolean = { |
| 59 | def visit(axiom: OWLEquivalentClassesAxiom): Boolean = { | ||
| 60 | // TODO | 74 | // TODO |
| 61 | false | 75 | false |
| 62 | } | 76 | } |
| 63 | 77 | ||
| 64 | def doDefault(axiom : OWLAxiom): Boolean = false | 78 | def doDefault(axiom: OWLAxiom): Boolean = false |
| 65 | } | 79 | } |
| 66 | 80 | ||
| 67 | private def isOfType(t: RSAAxiomType): Boolean = { | 81 | private def isOfType(t: RSAAxiomType): Boolean = { |
| @@ -74,13 +88,13 @@ trait RSAAxiom { | |||
| 74 | def isT3: Boolean = isOfType(RSAAxiomType.T3) | 88 | def isT3: Boolean = isOfType(RSAAxiomType.T3) |
| 75 | def isT4: Boolean = isOfType(RSAAxiomType.T4) | 89 | def isT4: Boolean = isOfType(RSAAxiomType.T4) |
| 76 | def isT5: Boolean = isOfType(RSAAxiomType.T5) | 90 | def isT5: Boolean = isOfType(RSAAxiomType.T5) |
| 77 | 91 | ||
| 78 | /* Extracting ObjectPropertyExpressions from axioms | 92 | /* Extracting ObjectPropertyExpressions from axioms |
| 79 | * | 93 | * |
| 80 | * This extracts all ObjectPropertyExpressions from a given | 94 | * This extracts all ObjectPropertyExpressions from a given |
| 81 | * axiom. While the implementation is generic we use it on axioms | 95 | * axiom. While the implementation is generic we use it on axioms |
| 82 | * of specific types (see above). | 96 | * of specific types (see above). |
| 83 | * | 97 | * |
| 84 | * NOTE: it is not possible to use the `objectPropertyInSignature` | 98 | * NOTE: it is not possible to use the `objectPropertyInSignature` |
| 85 | * method of `OWLAxiom` because it returns all "role names" involved | 99 | * method of `OWLAxiom` because it returns all "role names" involved |
| 86 | * in the signature of an axiom. In particular we won't get the inverse | 100 | * in the signature of an axiom. In particular we won't get the inverse |
| @@ -88,55 +102,61 @@ trait RSAAxiom { | |||
| 88 | * itself instead). | 102 | * itself instead). |
| 89 | */ | 103 | */ |
| 90 | private class RSAAxiomRoleExtractor() | 104 | private class RSAAxiomRoleExtractor() |
| 91 | extends OWLAxiomVisitorEx[List[OWLObjectPropertyExpression]] | 105 | extends OWLAxiomVisitorEx[List[OWLObjectPropertyExpression]] { |
| 92 | { | ||
| 93 | 106 | ||
| 94 | private class RSAExprRoleExtractor() | 107 | private class RSAExprRoleExtractor() |
| 95 | extends OWLClassExpressionVisitorEx[List[OWLObjectPropertyExpression]] | 108 | extends OWLClassExpressionVisitorEx[ |
| 96 | { | 109 | List[OWLObjectPropertyExpression] |
| 97 | override | 110 | ] { |
| 98 | def visit(expr: OWLObjectSomeValuesFrom): List[OWLObjectPropertyExpression] = | 111 | override def visit( |
| 112 | expr: OWLObjectSomeValuesFrom | ||
| 113 | ): List[OWLObjectPropertyExpression] = | ||
| 99 | List(expr.getProperty) | 114 | List(expr.getProperty) |
| 100 | 115 | ||
| 101 | override | 116 | override def visit( |
| 102 | def visit(expr: OWLObjectMaxCardinality): List[OWLObjectPropertyExpression] = | 117 | expr: OWLObjectMaxCardinality |
| 118 | ): List[OWLObjectPropertyExpression] = | ||
| 103 | List(expr.getProperty) | 119 | List(expr.getProperty) |
| 104 | 120 | ||
| 105 | /* NOTE: this instance of `visit` for `OWLClass` shouldn't be necessary. However | 121 | /* NOTE: this instance of `visit` for `OWLClass` shouldn't be necessary. However |
| 106 | * if missing, the code throws a `NullPointerException`. It seems like, for some | 122 | * if missing, the code throws a `NullPointerException`. It seems like, for some |
| 107 | * reason, `OWLClass` is not really a subinterface of `OWLClassExpression`, as | 123 | * reason, `OWLClass` is not really a subinterface of `OWLClassExpression`, as |
| 108 | * stated in the JavaDocs. | 124 | * stated in the JavaDocs. |
| 109 | */ | 125 | */ |
| 110 | override | 126 | override def visit(expr: OWLClass): List[OWLObjectPropertyExpression] = |
| 111 | def visit(expr: OWLClass): List[OWLObjectPropertyExpression] = | ||
| 112 | List() | 127 | List() |
| 113 | 128 | ||
| 114 | def doDefault(expr: OWLClassExpression): List[OWLObjectPropertyExpression] = | 129 | def doDefault( |
| 130 | expr: OWLClassExpression | ||
| 131 | ): List[OWLObjectPropertyExpression] = | ||
| 115 | List() | 132 | List() |
| 116 | } | 133 | } |
| 117 | 134 | ||
| 118 | override | 135 | override def visit( |
| 119 | def visit(axiom: OWLSubClassOfAxiom): List[OWLObjectPropertyExpression] = { | 136 | axiom: OWLSubClassOfAxiom |
| 137 | ): List[OWLObjectPropertyExpression] = { | ||
| 120 | val visitor = new RSAExprRoleExtractor() | 138 | val visitor = new RSAExprRoleExtractor() |
| 121 | val sub = axiom.getSubClass.accept(visitor) | 139 | val sub = axiom.getSubClass.accept(visitor) |
| 122 | val sup = axiom.getSuperClass.accept(visitor) | 140 | val sup = axiom.getSuperClass.accept(visitor) |
| 123 | sub ++ sup | 141 | sub ++ sup |
| 124 | } | 142 | } |
| 125 | 143 | ||
| 126 | override | 144 | override def visit( |
| 127 | def visit(axiom: OWLEquivalentClassesAxiom): List[OWLObjectPropertyExpression] = { | 145 | axiom: OWLEquivalentClassesAxiom |
| 146 | ): List[OWLObjectPropertyExpression] = { | ||
| 128 | // TODO | 147 | // TODO |
| 129 | List() | 148 | List() |
| 130 | } | 149 | } |
| 131 | 150 | ||
| 132 | def doDefault(axiom : OWLAxiom): List[OWLObjectPropertyExpression] = List() | 151 | def doDefault(axiom: OWLAxiom): List[OWLObjectPropertyExpression] = List() |
| 133 | } | 152 | } |
| 134 | 153 | ||
| 135 | /* Exposed methods */ | 154 | /* Exposed methods */ |
| 136 | def objectPropertyExpressionsInSignature: List[OWLObjectPropertyExpression] = { | 155 | def objectPropertyExpressionsInSignature |
| 156 | : List[OWLObjectPropertyExpression] = { | ||
| 137 | val visitor = new RSAAxiomRoleExtractor() | 157 | val visitor = new RSAAxiomRoleExtractor() |
| 138 | axiom.accept(visitor) | 158 | axiom.accept(visitor) |
| 139 | } | 159 | } |
| 140 | } | 160 | } |
| 141 | 161 | ||
| 142 | } // trait RSAAxiom \ No newline at end of file | 162 | } // trait RSAAxiom |
