Skip to content

Commit

Permalink
Update JS bridge to match Java. (#258)
Browse files Browse the repository at this point in the history
  • Loading branch information
balhoff authored Nov 1, 2024
1 parent 2c84ae8 commit 6186eaa
Showing 1 changed file with 104 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.geneontology.whelk.archimedes

import org.geneontology.archimedes.owl.OWLVocabulary._
import org.geneontology.archimedes.owl.{Atom => SWRLAtom, Axiom => OWLAxiom, DataHasValue => OWLDataHasValue, NamedIndividual => OWLNamedIndividual, Variable => OWLVariable, _}
import org.geneontology.archimedes.owl.{Atom => SWRLAtom, Axiom => OWLAxiom, DataHasValue => OWLDataHasValue, NamedIndividual => OWLNamedIndividual, Variable => OWLVariable, DifferentIndividualsAtom => SWRLDifferentIndividualsAtom, _}
import org.geneontology.archimedes.util.Lists.PluralList
import org.geneontology.whelk.BuiltIn._
import org.geneontology.whelk.Role.CompositionRolePrefix
Expand All @@ -24,7 +24,7 @@ object Bridge {
case first :: second :: Nil => Set(ConceptInclusion(first, second), ConceptInclusion(second, first))
case _ => Set.empty //impossible
}.toSet
case DisjointClasses(operands, _) if operands.items.size == 2 => //FIXME handle >2
case DisjointClasses(operands, _) =>
val converted = operands.items.map(convertExpression).toList.collect { case Some(concept) => concept }
converted.combinations(2).flatMap {
case first :: second :: Nil => Set(ConceptInclusion(Conjunction(first, second), Bottom))
Expand All @@ -39,7 +39,15 @@ object Bridge {
case EquivalentObjectProperties(propertyExpressions, _) =>
val properties = propertyExpressions.items.collect { case p @ ObjectProperty(_) => p }.toList
properties.combinations(2).flatMap {
case ObjectProperty(first) :: ObjectProperty(second) :: Nil => Set(RoleInclusion(Role(first.id), Role(second.id)))
case ObjectProperty(first) :: ObjectProperty(second) :: Nil =>
val role1 = Role(first.id)
val role2 = Role(second.id)
Set(
RoleInclusion(role1, role2),
RoleInclusion(role2, role1),
Rule(body = List(RoleAtom(role1, Variable("x"), Variable("y"))), head = List(RoleAtom(role2, Variable("x"), Variable("y")))),
Rule(body = List(RoleAtom(role2, Variable("x"), Variable("y"))), head = List(RoleAtom(role1, Variable("x"), Variable("y"))))
)
case _ => Set.empty //impossible
}.toSet
case SubObjectPropertyOf(ObjectProperty(subproperty), ObjectProperty(superproperty), _) =>
Expand Down Expand Up @@ -67,6 +75,22 @@ object Bridge {
val compositionProperty = ObjectProperty(IRI(s"$CompositionRolePrefix${first.iri.id}${second.iri.id}"))
convertAxiom(SubObjectPropertyOf(ObjectPropertyChain(PluralList(first, second, Nil)), compositionProperty)) ++
convertAxiom(SubObjectPropertyOf(ObjectPropertyChain(PluralList(compositionProperty, third, rest)), superproperty))
case DisjointObjectProperties(properties, _) =>
properties.items.toList.combinations(2).flatMap {
case first :: second :: Nil =>
val firstRoleAtom = first match {
case ObjectProperty(iri) => RoleAtom(Role(iri.id), Variable("x"), Variable("y"))
case ObjectInverseOf(ObjectProperty(iri)) => RoleAtom(Role(iri.id), Variable("y"), Variable("x"))
}
val secondRoleAtom = second match {
case ObjectProperty(iri) => RoleAtom(Role(iri.id), Variable("x"), Variable("y"))
case ObjectInverseOf(ObjectProperty(iri)) => RoleAtom(Role(iri.id), Variable("y"), Variable("x"))
}
Set(
Rule(body = List(firstRoleAtom, secondRoleAtom), head = List(ConceptAtom(Bottom, Variable("x")), ConceptAtom(Bottom, Variable("y"))))
)
case _ => ??? //impossible
}.toSet
case TransitiveObjectProperty(ObjectProperty(property), _) =>
val role = Role(property.id)
Set(
Expand All @@ -75,17 +99,69 @@ object Bridge {
case ReflexiveObjectProperty(ObjectProperty(property), _) => Set(
ConceptInclusion(Top, SelfRestriction(Role(property.id)))
)
case ObjectPropertyDomain(ObjectProperty(property), ce, _) => convertExpression(ce).map(concept =>
ConceptInclusion(ExistentialRestriction(Role(property.id), Top), concept)).toSet
case ObjectPropertyRange(ObjectProperty(property), ce, _) => convertExpression(ce).map(concept =>
//TODO only supporting in rules for now
Rule(body = List(RoleAtom(Role(property.id), Variable("x1"), Variable("x2"))), head = List(ConceptAtom(concept, Variable("x2"))))).toSet
case FunctionalObjectProperty(ObjectProperty(property), _) =>
val role = Role(property.id)
Set(
Rule(body = List(RoleAtom(role, Variable("x"), Variable("y1")), RoleAtom(role, Variable("x"), Variable("y2"))), head = List(SameIndividualsAtom(Variable("y1"), Variable("y2"))))
)
case InverseFunctionalObjectProperty(ObjectProperty(property), _) =>
val role = Role(property.id)
Set(
Rule(body = List(RoleAtom(role, Variable("x1"), Variable("y")), RoleAtom(role, Variable("x2"), Variable("y"))), head = List(SameIndividualsAtom(Variable("x1"), Variable("x2"))))
)
case IrreflexiveObjectProperty(ObjectProperty(property), _) =>
val role = Role(property.id)
Set(
Rule(body = List(RoleAtom(role, Variable("x"), Variable("x"))), head = List(ConceptAtom(BuiltIn.Bottom, Variable("x"))))
)
case SymmetricObjectProperty(ObjectProperty(property), _) =>
val role = Role(property.id)
Set(
Rule(body = List(RoleAtom(role, Variable("x"), Variable("y"))), head = List(RoleAtom(role, Variable("y"), Variable("x"))))
)
case AsymmetricObjectProperty(ObjectProperty(property), _) =>
val role = Role(property.id)
Set(
Rule(body = List(RoleAtom(role, Variable("x"), Variable("y")), RoleAtom(role, Variable("y"), Variable("x"))), head = List(ConceptAtom(BuiltIn.Bottom, Variable("x")), ConceptAtom(BuiltIn.Bottom, Variable("y"))))
)
case ObjectPropertyDomain(ObjectProperty(property), ce, _) =>
convertExpression(ce).map(concept =>
ConceptInclusion(ExistentialRestriction(Role(property.id), Top), concept)).toSet
case ObjectPropertyRange(ObjectProperty(property), ce, _) =>
convertExpression(ce).to(Set).flatMap { concept =>
val role = Role(property.id)
Set(
RoleHasRange(role, concept),
Rule(body = List(RoleAtom(role, Variable("x1"), Variable("x2"))), head = List(ConceptAtom(concept, Variable("x2"))))
)
}
case InverseObjectProperties(ObjectProperty(p), ObjectProperty(q), _) =>
val (roleP, roleQ) = (Role(p.id), Role(q.id))
val (x1, x2) = (Variable("x1"), Variable("x2"))
Set(
Rule(body = List(RoleAtom(roleP, x1, x2)), head = List(RoleAtom(roleQ, x2, x1))),
Rule(body = List(RoleAtom(roleQ, x1, x2)), head = List(RoleAtom(roleP, x2, x1))))
case NegativeObjectPropertyAssertion(ObjectProperty(p), OWLNamedIndividual(x), OWLNamedIndividual(y), _) =>
val xInd = Individual(x.id)
val yInd = Individual(y.id)
Set(
Rule(body = List(RoleAtom(Role(p.id), xInd, yInd)), head = List(ConceptAtom(Bottom, xInd), ConceptAtom(Bottom, yInd)))
)
case SameIndividual(individuals, _) =>
individuals.items.toList.combinations(2).flatMap {
case OWLNamedIndividual(first) :: OWLNamedIndividual(second) :: Nil => Set(
ConceptInclusion(Nominal(Individual(first.id)), Nominal(Individual(second.id))),
ConceptInclusion(Nominal(Individual(second.id)), Nominal(Individual(first.id)))
)
case _ => ??? //impossible
}.toSet
case DifferentIndividuals(individuals, _) =>
individuals.items.toList.combinations(2).flatMap {
case OWLNamedIndividual(first) :: OWLNamedIndividual(second) :: Nil => Set(
ConceptInclusion(Conjunction(Nominal(Individual(first.id)), Nominal(Individual(second.id))), Bottom),
)
case _ => ??? //impossible
}.toSet
case DLSafeRule(body, head, _) => (for {
bodyAtoms <- convertAtomSet(body)
headAtoms <- convertAtomSet(head)
Expand All @@ -101,6 +177,9 @@ object Bridge {
case OWLNothing => Some(Bottom)
case Class(iri) => Some(AtomicConcept(iri.id))
case ObjectSomeValuesFrom(ObjectProperty(prop), filler) => convertExpression(filler).map(ExistentialRestriction(Role(prop.id), _))
case ObjectAllValuesFrom(ObjectProperty(prop), filler) => convertExpression(filler).map(UniversalRestriction(Role(prop.id), _))
case ObjectMaxCardinality(0, ObjectProperty(prop), filler) => convertExpression(filler).map(c => Complement(ExistentialRestriction(Role(prop.id), c)))
case ObjectMaxCardinality(1, ObjectProperty(prop), filler) => convertExpression(filler).map(MaxCardinalityRestriction(Role(prop.id), _, 1))
case ObjectHasSelf(ObjectProperty(prop)) => Some(SelfRestriction(Role(prop.id)))
case ObjectIntersectionOf(operands) =>
def convert(items: List[Concept]): Option[Concept] = items match {
Expand All @@ -114,7 +193,13 @@ object Bridge {
case ObjectUnionOf(operands) =>
operands.items.toList.map(convertExpression).sequence.map(_.toSet).map(Disjunction)
case ObjectComplementOf(concept) => convertExpression(concept).map(Complement)
case ObjectOneOf(individuals) if individuals.items.size == 1 => individuals.items.collectFirst { case OWLNamedIndividual(iri) => Nominal(Individual(iri.id)) }
case ObjectOneOf(individuals) =>
val operands = individuals.items.collect {
case OWLNamedIndividual(iri) => Nominal(Individual(iri.id))
}
if (operands.isEmpty) None
else if (operands.size == 1) operands.headOption
else Some(Disjunction(operands.toSet[Concept]))
case ObjectHasValue(ObjectProperty(prop), OWLNamedIndividual(ind)) => Some(ExistentialRestriction(Role(prop.id), Nominal(Individual(ind.id))))
case DataSomeValuesFrom(DataProperty(prop), range) => Some(DataRestriction(DataRole(prop.id), DataRange(range)))
case OWLDataHasValue(prop, literal) => Some(DataHasValue(DataRole(prop.iri.id), literal))
Expand All @@ -134,7 +219,16 @@ object Bridge {
subject <- convertAtomArg(subj)
target <- convertAtomArg(obj)
} yield RoleAtom(Role(iri.id), subject, target)
case ObjectPropertyAtom(ObjectInverseOf(prop @ ObjectProperty(_)), subj, obj) => convertRuleAtom(ObjectPropertyAtom(prop, obj, subj))
case ObjectPropertyAtom(ObjectInverseOf(prop @ ObjectProperty(_)), subj, obj) =>
convertRuleAtom(ObjectPropertyAtom(prop, obj, subj))
case SameIndividualAtom(left, right) => for {
subject <- convertAtomArg(left)
target <- convertAtomArg(right)
} yield RoleAtom(SameAs, subject, target)
case SWRLDifferentIndividualsAtom(left, right) => for {
subject <- convertAtomArg(left)
target <- convertAtomArg(right)
} yield RoleAtom(DifferentFrom, subject, target)
case _ => None
}

Expand Down

0 comments on commit 6186eaa

Please sign in to comment.