# -*- coding: utf-8 -*-
# Owlready2
# Copyright (C) 2013-2019 Jean-Baptiste LAMY
# LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142
# University Paris 13, Sorbonne paris-Cité, Bobigny, France
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from owlready2.namespace import *
from owlready2.entity import *
from owlready2.prop import *
from owlready2.class_construct import *
[docs]
class AllDisjoint(object):
def __init__(self, entities, ontology = None, bnode = None):
#if not CURRENT_NAMESPACES[-1] is None: self.ontology = CURRENT_NAMESPACES[-1].ontology
#else: self.ontology = ontology or entities[0].namespace.ontology
self.ontology = (CURRENT_NAMESPACES.get() and CURRENT_NAMESPACES.get()[-1]) or ontology or entities[0].namespace.ontology
# For AllDisjoint, storid can be either:
# * a blank node, when at least 3 entities are involved
# * a triple, when only 2 entities, e.g. (entity1.storid, owl_disjointwith, entity2.storid)
if isinstance(entities, int):
assert isinstance(bnode, int)
self.storid = bnode
self._list_bnode = entities
elif isinstance(entities, tuple):
self.storid = entities
else:
self.storid = bnode
self._list_bnode = None
self.entities = self.Properties = self.individuals = CallbackList(entities, self, AllDisjoint._callback)
if not LOADING: self._create_triples()
def __getattr__(self, attr):
if attr == "entities":
if isinstance(self.storid, int):
r = self.ontology._parse_list(self._list_bnode)
else:
r = [self.ontology.world._to_python(self.storid[0]), self.ontology.world._to_python(self.storid[2])]
r = CallbackList(r, self, AllDisjoint._callback)
setattr(self, attr,r)
return r
return super().__getattribute__(attr)
def _callback(self, old):
if self.ontology:
self._destroy_triples()
self._create_triples ()
def _destroy_triples(self):
if isinstance(self.storid, int):
self.ontology._del_obj_triple_spo(self.storid, None, None)
self.ontology._del_list(self._list_bnode)
elif isinstance(self.storid, tuple):
self.ontology._del_obj_triple_spo(*self.storid)
def destroy(self): self._destroy_triples()
def _create_triples(self):
for entity in self.entities:
if isinstance(entity, Construct): entity._set_ontology(self.ontology)
if len(self.entities) == 2:
if isinstance(self.entities[0], ThingClass):
self.storid = (self.entities[0].storid, owl_disjointwith, self.entities[1].storid)
self.ontology._add_obj_triple_spo(*self.storid)
return
elif isinstance(self.entities[0], PropertyClass):
self.storid = (self.entities[0].storid, owl_propdisjointwith, self.entities[1].storid)
self.ontology._add_obj_triple_spo(*self.storid)
return
# It seems that there is no 1-1 relation for individuals
# => continue
if len(self.entities) >= 2:
if not isinstance(self.storid, int): self.storid = self.ontology.world.new_blank_node()
if not self._list_bnode: self._list_bnode = self.ontology.world.new_blank_node()
if isinstance(self.entities[0], ThingClass):
self.ontology._add_obj_triple_spo(self.storid, rdf_type, owl_alldisjointclasses)
self.ontology._add_obj_triple_spo(self.storid, owl_members, self._list_bnode)
elif isinstance(self.entities[0], PropertyClass):
self.ontology._add_obj_triple_spo(self.storid, rdf_type, owl_alldisjointproperties)
self.ontology._add_obj_triple_spo(self.storid, owl_members, self._list_bnode)
else: # Individuals
self.ontology._add_obj_triple_spo(self.storid, rdf_type, owl_alldifferent)
self.ontology._add_obj_triple_spo(self.storid, owl_distinctmembers, self._list_bnode)
self.ontology._set_list(self._list_bnode, self.entities)
def __repr__(self):
if self.ontology != self.entities[0].namespace.ontology: onto = ", ontology = %s" % self.ontology
else: onto = ""
return "AllDisjoint([%s]%s)" % (", ".join(repr(Class) for Class in self.entities), onto)
AllDifferent = AllDisjoint
def partition(mother, children):
mother.is_a.append(Or(children))
AllDisjoint(children)
# class DisjointUnion(LogicalClassConstruct):
# _owl_op = owl_disjointunion
# is_a = ()
# def _satisfied_by(self, x):
# for Class in self.Classes:
# if Class._satisfied_by(x): return True
# return False
# def __repr__(self):
# s = []
# for x in self.Classes:
# if isinstance(x, LogicalClassConstruct): s.append("(%s)" % x)
# else: s.append(repr(x))
# return "%s([%s])" % (self.__class__.__name__, ", ".join(s))