Skip to content

Commit 9c7717b

Browse files
committed
Separate class into two files
1 parent 9d20a70 commit 9c7717b

File tree

2 files changed

+113
-90
lines changed

2 files changed

+113
-90
lines changed

concepts/lazy_lattice_members.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import typing
2+
3+
from .algorithms import lindig
4+
from .lattice_members import OrderableMixin
5+
6+
7+
class LazyPair:
8+
def __init__(self,
9+
lattice,
10+
extent,
11+
intent,
12+
upper=None,
13+
lower=None) -> None:
14+
self.lattice = lattice
15+
self._extent = extent
16+
self._intent = intent
17+
self._upper_neighbors = upper
18+
self._lower_neighbors = lower
19+
20+
@property
21+
def upper_neighbors(self):
22+
if self._upper_neighbors is None:
23+
neighbors = lindig.neighbors(self._extent, Objects=self.lattice._context._Objects)
24+
25+
shortlex = self.lattice._shortlex
26+
27+
upper = (self.lattice[extent.members()] for extent, _ in neighbors)
28+
self._upper_neighbors = tuple(sorted(upper, key=shortlex))
29+
30+
return self._upper_neighbors
31+
32+
@property
33+
def lower_neighbors(self):
34+
if self._lower_neighbors is None:
35+
neighbors = lindig.neighbors(self._intent, Objects=self.lattice._context._Properties)
36+
37+
longlex = self.lattice._longlex
38+
39+
lower = (self.lattice[intent.members()] for intent, _ in neighbors)
40+
self._lower_neighbors = tuple(sorted(lower, key=longlex))
41+
42+
return self._lower_neighbors
43+
44+
def _eq(self, other):
45+
if not isinstance(other, LazyConcept):
46+
return NotImplemented
47+
48+
if (other._extent.members() != self._extent.members()
49+
or other._intent.members() != self._intent.members()):
50+
return False
51+
52+
return True
53+
54+
55+
class LazyRelationsMixin:
56+
def incompatible_with(self, other: 'LazyConcept') -> bool:
57+
return not self._extent & other._extent
58+
59+
60+
class LazyTransformableMixin:
61+
def join(self, other: 'LazyConcept') -> 'LazyConcept':
62+
common = self._extent | other._extent
63+
extent = self.lattice._context._extents.double(common)
64+
return self.lattice[extent.members()]
65+
66+
__or__ = join
67+
68+
def meet(self, other: 'LazyConcept') -> 'LazyConcept':
69+
common = self._extent & other._extent
70+
extent = self.lattice._context._extents.double(common)
71+
return self.lattice[extent.members()]
72+
73+
__and__ = meet
74+
75+
76+
class LazyFormattingMixin:
77+
def __str__(self) -> str:
78+
extent = ', '.join(self._extent.members())
79+
intent = ' '.join(self._intent.members())
80+
return f'{{{extent}}} <-> [{intent}]'
81+
82+
def __repr__(self) -> str:
83+
return f'<{self.__class__.__name__} {self}>'
84+
85+
86+
class LazyConcept(LazyRelationsMixin, OrderableMixin, LazyFormattingMixin, LazyPair):
87+
def minimal(self) -> typing.Tuple[str, ...]:
88+
return self.lattice._context._minimal(self._extent,
89+
self._intent).members()
90+
91+
def attributes(self) -> typing.Iterator[typing.Tuple[str]]:
92+
minimize = self.lattice._context._minimize(self._extent, self._intent)
93+
return (i.members() for i in minimize)

concepts/lazy_lattices.py

Lines changed: 20 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,21 @@
11
import typing
22

3-
from . import lattices
43
from . import contexts
5-
from .algorithms import lindig
6-
7-
from .lattice_members import OrderableMixin
8-
9-
10-
class LazyPair:
11-
def __init__(self,
12-
lattice,
13-
extent,
14-
intent,
15-
upper=None,
16-
lower=None) -> None:
17-
self.lattice = lattice
18-
self._extent = extent
19-
self._intent = intent
20-
self._upper_neighbors = upper
21-
self._lower_neighbors = lower
22-
23-
@property
24-
def upper_neighbors(self):
25-
if self._upper_neighbors is None:
26-
neighbors = lindig.neighbors(self._extent, Objects=self.lattice._context._Objects)
27-
28-
shortlex = self.lattice._shortlex
29-
30-
upper = (self.lattice[extent.members()] for extent, _ in neighbors)
31-
self._upper_neighbors = tuple(sorted(upper, key=shortlex))
32-
33-
return self._upper_neighbors
34-
35-
@property
36-
def lower_neighbors(self):
37-
if self._lower_neighbors is None:
38-
neighbors = lindig.neighbors(self._intent, Objects=self.lattice._context._Properties)
39-
40-
longlex = self.lattice._longlex
41-
42-
lower = (self.lattice[extent.members()] for _, extent in neighbors)
43-
self._lower_neighbors = tuple(sorted(lower, key=longlex))
44-
45-
return self._lower_neighbors
46-
47-
def _eq(self, other):
48-
if not isinstance(other, LazyConcept):
49-
return NotImplemented
50-
51-
if (other._extent.members() != self._extent.members()
52-
or other._intent.members() != self._intent.members()):
53-
return False
54-
55-
return True
56-
57-
58-
class LazyRelationsMixin:
59-
def incompatible_with(self, other: 'LazyConcept') -> bool:
60-
return not self._extent & other._extent
61-
62-
63-
class LazyTransformableMixin:
64-
def join(self, other: 'LazyConcept') -> 'LazyConcept':
65-
common = self._extent | other._extent
66-
extent = self.lattice._context._extents.double(common)
67-
return self.lattice[extent.members()]
68-
69-
__or__ = join
70-
71-
def meet(self, other: 'LazyConcept') -> 'LazyConcept':
72-
common = self._extent & other._extent
73-
extent = self.lattice._context._extents.double(common)
74-
return self.lattice[extent.members()]
75-
76-
__and__ = meet
77-
4+
from .lazy_lattice_members import LazyConcept
5+
786

797
class LazyFormattingMixin:
808
def __str__(self) -> str:
81-
extent = ', '.join(self._extent.members())
82-
intent = ' '.join(self._intent.members())
83-
return f'{{{extent}}} <-> [{intent}]'
9+
concepts = '\n'.join(f' {c}' for c in self._concepts)
10+
return f'{self!r}\n{concepts}'
8411

8512
def __repr__(self) -> str:
86-
return f'<{self.__class__.__name__} {self}>'
87-
13+
return (f'<{self.__class__.__name__} object'
14+
f' {len(self)} concepts'
15+
f' at {id(self):#x}>')
8816

89-
class LazyConcept(LazyRelationsMixin, OrderableMixin, LazyFormattingMixin, LazyPair):
90-
def minimal(self) -> typing.Tuple[str, ...]:
91-
return self.lattice._context._minimal(self._extent,
92-
self._intent).members()
9317

94-
def attributes(self) -> typing.Iterator[typing.Tuple[str]]:
95-
minimize = self.lattice._context._minimize(self._extent, self._intent)
96-
return (i.members() for i in minimize)
97-
98-
99-
class LazyLattice(lattices.CollectionMixin, lattices.FormattingMixin):
18+
class LazyLattice(LazyFormattingMixin):
10019
@staticmethod
10120
def _longlex(concept):
10221
return concept._extent.longlex()
@@ -121,12 +40,23 @@ def __getitem__(self, key: typing.Tuple[str, ...]) -> LazyConcept:
12140

12241
extent, intent = self._context.__getitem__(key, raw=True)
12342

124-
if extent not in self:
43+
if extent not in self._mapping:
12544
new_concept = LazyConcept(self, extent, intent)
12645
self._mapping[extent] = new_concept
12746
self._concepts.append(new_concept)
47+
self._concepts.sort(key=self._shortlex)
12848

12949
return self._mapping[extent]
50+
51+
def __iter__(self) -> typing.Iterator[LazyConcept]:
52+
return iter(self._concepts)
53+
54+
def __len__(self) -> int:
55+
return len(self._concepts)
56+
57+
58+
59+
13060

13161

13262

0 commit comments

Comments
 (0)