def __call__(self, source, edge, target): if edge.type() is Item.InclusionEdge: # We need to provide rules for OWL 2 RL concept inclusion. Value-Domain inclusions # are already forbidden by OWL 2 rules, so here we just consider the case where we # are connecting endpoints that either both Neutral, or at least one of the 2 is # identified as a Concept expression. if not {Identity.Role, Identity.Attribute, Identity.Unknown} & {source.identity(), target.identity()}: ############################################# # EVALUATE INCLUSION SOURCE ################################# # TOP concept cannot be source of concept inclusion in OWL 2 RL. if source.type() is Item.ConceptNode: if Special.forValue(source.text()) is Special.Top: raise ProfileError('Inclusion with a TOP concept as source is forbidden in OWL 2 RL') # Complement nodes cannot be source of concept inclusion in OWL 2 RL. elif source.type() is Item.ComplementNode: raise ProfileError('Inclusion with a concept complement as source is forbidden in OWL 2 RL') # OWL 2 RL admits only existential restriction as source for inclusion. elif source.type() in {Item.DomainRestrictionNode, Item.RangeRestrictionNode}: if source.restriction() is not Restriction.Exists: r = source.restriction() raise ProfileError('Inclusion with a {} {} as source is forbidden in OWL 2 RL'.format(r.shortName, source.shortName)) ############################################# # EVALUATE INCLUSION TARGET ################################# # TOP concept cannot be target of concept inclusion in OWL 2 RL. if target.type() is Item.ConceptNode: if Special.forValue(target.text()) is Special.Top: raise ProfileError('Inclusion with a TOP concept as target is forbidden in OWL 2 RL') # Enumeration nodes cannot be target of concept inclusion in OWL 2 RL. elif target.type() is Item.EnumerationNode: raise ProfileError('Inclusion with an enumeration of individuals as target is forbidden in OWL 2 RL') # Union of concept expressions cannot be target of concept inclusion in OWL 2 RL. elif target.type() is Item.EnumerationNode: raise ProfileError('Inclusion with a union of concept expressions as target is forbidden in OWL 2 RL') # Existential domain/range restriction and cardinality check. elif target.type() in {Item.DomainRestrictionNode, Item.RangeRestrictionNode}: if target.restriction() is Restriction.Exists: # We need to check for the restriction to have a an Enumeration as filler. f1 = lambda x: x.type() is Item.InputEdge f2 = lambda x: x.type() is Item.EnumerationNode if not target.incomingNodes(filter_on_edges=f1, filter_on_nodes=f2): raise ProfileError('Existential {} must specify an Enumeration as filler when acting as ' 'target for a concept expression inclusion in OWL 2 RL'.format(target.shortName)) elif target.restriction() is Restriction.Cardinality: if target.cardinality('max') not in (0, 1): raise ProfileError('Cardinality {} must specify a max cardinality of 0 or 1 when acting as ' 'target for a concept expression inclusion in OWL 2 RL'.format(target.shortName))
def __call__(self, source, edge, target): if edge.type() is Item.InclusionEdge: # Similarily as for the Inclusion edge, we provide rules for OWL 2 RL concept expressions equivalence. # Because equivalence express a double inclusion we treat each of the endpoints in the same way. if not {Identity.Role, Identity.Attribute, Identity.Unknown} & {source.identity(), target.identity()}: for node in (source, target): # TOP concept cannot be part of concept equivalence in OWL 2 RL. if node.type() is Item.ConceptNode: if Special.forValue(node.text()) is Special.Top: raise ProfileError('Equivalence in presence of a TOP concept is forbidden in OWL 2 RL') # Complement nodes cannot be part of concept equivalence in OWL 2 RL. elif node.type() is Item.ComplementNode: raise ProfileError('Equivalence in presence of a concept complement is forbidden in OWL 2 RL') # Enumeration nodes cannot be part of concept equivalence in OWL 2 RL. elif node.type() is Item.EnumerationNode: raise ProfileError('Equivalence in presence of an enumeration of individuals is forbidden in OWL 2 RL') # Union of concept expressions cannot be part of concept equivalence in OWL 2 RL. elif node.type() is Item.EnumerationNode: raise ProfileError('Equivalence in presence of a union of concept expressions is forbidden in OWL 2 RL') # Domain/range restriction cannot be part of concept equivalence in OWL 2 RL. elif node.type() in {Item.DomainRestrictionNode, Item.RangeRestrictionNode}: f1 = lambda x: x.type() is Item.InputEdge f2 = lambda x: x.type() is Item.EnumerationNode if not node.incomingNodes(filter_on_edges=f1, filter_on_nodes=f2): raise ProfileError('Existential {} must specify an Enumeration as filler when involved ' 'in an equivalence between concept expressions in OWL 2 RL'.format(target.shortName))
def isRestrictionQualified(self): """ Returna True if this node expresses a qualified restriction (exists R.C), False otherwise. :rtype: bool """ f1 = lambda x: x.type() is Item.InputEdge f2 = lambda x: x.identity() in {Identity.Concept, Identity.Role} f3 = lambda x: x.identity() in {Identity.Attribute, Identity.ValueDomain} f4 = lambda x: x.identity() is Identity.Concept if self.restriction() in {Restriction.Cardinality, Restriction.Exists, Restriction.Forall}: # CHECK FOR ROLE QUALIFIED RESTRICTION collection = self.incomingNodes(filter_on_edges=f1, filter_on_nodes=f2) if len(collection) >= 2: node = first(collection, filter_on_item=f4) if node and Special.forValue(node.text()) is not Special.Top: return True # CHECK FOR ATTRIBUTE QUALIFIED RESTRICTION return len(self.incomingNodes(filter_on_edges=f1, filter_on_nodes=f3)) >= 2 return False
def __call__(self, source, edge, target): if edge.type() is Item.InputEdge: if target.type() in {Item.DomainRestrictionNode, Item.RangeRestrictionNode}: # OWL 2 QL admits only atomic concepts for role qualified restriction. if source.identity() is Identity.Concept: if source.type() is not Item.ConceptNode: raise ProfileError('OWL 2 QL admits only an atomic concept as filler for a qualified {}'.format(target.shortName)) # Given the fact that we are connecting an atomic concept in input to this # restriction node, we need to see if the node is currently being used # as source for a concept expression inclusion, and if so, deny the connection # because OWL 2 QL admits concept inclusion sourcing only from unqualified role # restrictions (we need to skip TOP though, since it won't be qualified then). if Special.forValue(source.text()) is not Special.Top: # We found an outgoing inclusion edge and our restriction filler is not TOP. if target.outgoingNodes(filter_on_edges=lambda x: x.type() is Item.InclusionEdge): raise ProfileError('Inclusion with a qualified {} as source is forbidden in OWL 2 QL'.format(target.shortName)) # Similarly we block the input in case of equivalence edges attached to the restriction node. if target.adjacentNodes(filter_on_edges=lambda x: x.type() is Item.EquivalenceEdge): raise ProfileError('Equivalence in presence of qualified {} is forbidden in OWL 2 QL'.format(target.shortName))
def __call__(self, node): if node.type() in {Item.AttributeNode, Item.RoleNode}: if Special.forValue(node.text()) is not None: raise ProfileError('Usage of {} {} is forbidden in OWL 2 RL'.format(node.text(), node.shortName))
def special(self): """ Returns the special type of this node. :rtype: Special """ return Special.forValue(self.text())