forked from pwin/owlready2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
disjoint.py
135 lines (107 loc) · 5.49 KB
/
disjoint.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# -*- 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 *
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))