1
1
import typing
2
2
3
- from . import lattices
4
3
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
+
78
6
79
7
class LazyFormattingMixin :
80
8
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 } '
84
11
85
12
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} >' )
88
16
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 ()
93
17
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 ):
100
19
@staticmethod
101
20
def _longlex (concept ):
102
21
return concept ._extent .longlex ()
@@ -121,12 +40,23 @@ def __getitem__(self, key: typing.Tuple[str, ...]) -> LazyConcept:
121
40
122
41
extent , intent = self ._context .__getitem__ (key , raw = True )
123
42
124
- if extent not in self :
43
+ if extent not in self . _mapping :
125
44
new_concept = LazyConcept (self , extent , intent )
126
45
self ._mapping [extent ] = new_concept
127
46
self ._concepts .append (new_concept )
47
+ self ._concepts .sort (key = self ._shortlex )
128
48
129
49
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
+
130
60
131
61
132
62
0 commit comments