a34b75bee096713d17ed35e30238042b415a897e
3 from . import islhelper
5 from .islhelper
import mainctx
, libisl
, isl_set_basic_sets
14 @functools.total_ordering
23 def __new__(cls
, *polyhedra
):
24 from .polyhedra
import Polyhedron
25 if len(polyhedra
) == 1:
26 polyhedron
= polyhedra
[0]
27 if isinstance(polyhedron
, str):
28 return cls
.fromstring(polyhedron
)
29 elif isinstance(polyhedron
, Polyhedron
):
32 raise TypeError('argument must be a string '
33 'or a Polyhedron instance')
35 for polyhedron
in polyhedra
:
36 if not isinstance(polyhedron
, Polyhedron
):
37 raise TypeError('arguments must be Polyhedron instances')
38 symbols
= cls
._xsymbols
(polyhedra
)
39 islset
= cls
._toislset
(polyhedra
, symbols
)
40 return cls
._fromislset
(islset
, symbols
)
43 def _xsymbols(cls
, iterator
):
45 Return the ordered tuple of symbols present in iterator.
49 symbols
.update(item
.symbols
)
50 return tuple(sorted(symbols
))
54 return self
._polyhedra
62 return self
._dimension
65 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
66 islset
= libisl
.isl_set_make_disjoint(mainctx
, islset
)
67 return self
._fromislset
(islset
, self
.symbols
)
70 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
71 empty
= bool(libisl
.isl_set_is_empty(islset
))
72 libisl
.isl_set_free(islset
)
76 return not self
.isempty()
79 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
80 universe
= bool(libisl
.isl_set_plain_is_universe(islset
))
81 libisl
.isl_set_free(islset
)
85 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
86 bounded
= bool(libisl
.isl_set_is_bounded(islset
))
87 libisl
.isl_set_free(islset
)
90 def __eq__(self
, other
):
91 symbols
= self
._xsymbols
([self
, other
])
92 islset1
= self
._toislset
(self
.polyhedra
, symbols
)
93 islset2
= other
._toislset
(other
.polyhedra
, symbols
)
94 equal
= bool(libisl
.isl_set_is_equal(islset1
, islset2
))
95 libisl
.isl_set_free(islset1
)
96 libisl
.isl_set_free(islset2
)
99 def isdisjoint(self
, other
):
100 symbols
= self
._xsymbols
([self
, other
])
101 islset1
= self
._toislset
(self
.polyhedra
, symbols
)
102 islset2
= self
._toislset
(other
.polyhedra
, symbols
)
103 equal
= bool(libisl
.isl_set_is_disjoint(islset1
, islset2
))
104 libisl
.isl_set_free(islset1
)
105 libisl
.isl_set_free(islset2
)
108 def issubset(self
, other
):
109 symbols
= self
._xsymbols
([self
, other
])
110 islset1
= self
._toislset
(self
.polyhedra
, symbols
)
111 islset2
= self
._toislset
(other
.polyhedra
, symbols
)
112 equal
= bool(libisl
.isl_set_is_subset(islset1
, islset2
))
113 libisl
.isl_set_free(islset1
)
114 libisl
.isl_set_free(islset2
)
117 def __le__(self
, other
):
118 return self
.issubset(other
)
120 def __lt__(self
, other
):
121 symbols
= self
._xsymbols
([self
, other
])
122 islset1
= self
._toislset
(self
.polyhedra
, symbols
)
123 islset2
= self
._toislset
(other
.polyhedra
, symbols
)
124 equal
= bool(libisl
.isl_set_is_strict_subset(islset1
, islset2
))
125 libisl
.isl_set_free(islset1
)
126 libisl
.isl_set_free(islset2
)
129 def complement(self
):
130 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
131 islset
= libisl
.isl_set_complement(islset
)
132 return self
._fromislset
(islset
, self
.symbols
)
134 def __invert__(self
):
135 return self
.complement()
138 # see isl_set_coalesce, isl_set_detect_equalities,
139 # isl_set_remove_redundancies
140 # which ones? in which order?
141 raise NotImplementedError
143 def polyhedral_hull(self
):
144 # several types of hull are available
145 # polyhedral seems to be the more appropriate, to be checked
146 from .polyhedra
import Polyhedron
147 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
148 islbset
= libisl
.isl_set_polyhedral_hull(islset
)
149 return Polyhedron
._fromislbasicset
(islbset
, self
.symbols
)
151 def project(self
, symbols
):
152 # not sure what isl_set_project_out actually does…
153 # use isl_set_drop_constraints_involving_dims instead?
154 raise NotImplementedError
157 from .polyhedra
import Polyhedron
158 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
159 islbset
= libisl
.isl_set_sample(islset
)
160 return Polyhedron
._fromislbasicset
(islbset
, self
.symbols
)
162 def intersection(self
, *others
):
165 symbols
= self
._xsymbols
((self
,) + others
)
166 islset1
= self
._toislset
(self
.polyhedra
, symbols
)
168 islset2
= other
._toislset
(other
.polyhedra
, symbols
)
169 islset1
= libisl
.isl_set_intersect(islset1
, islset2
)
170 return self
._fromislset
(islset1
, symbols
)
172 def __and__(self
, other
):
173 return self
.intersection(other
)
175 def union(self
, *others
):
178 symbols
= self
._xsymbols
((self
,) + others
)
179 islset1
= self
._toislset
(self
.polyhedra
, symbols
)
181 islset2
= other
._toislset
(other
.polyhedra
, symbols
)
182 islset1
= libisl
.isl_set_union(islset1
, islset2
)
183 return self
._fromislset
(islset1
, symbols
)
185 def __or__(self
, other
):
186 return self
.union(other
)
188 def __add__(self
, other
):
189 return self
.union(other
)
191 def difference(self
, other
):
192 symbols
= self
._xsymbols
([self
, other
])
193 islset1
= self
._toislset
(self
.polyhedra
, symbols
)
194 islset2
= other
._toislset
(other
.polyhedra
, symbols
)
195 islset
= libisl
.isl_set_subtract(islset1
, islset2
)
196 return self
._fromislset
(islset
, symbols
)
198 def __sub__(self
, other
):
199 return self
.difference(other
)
202 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
203 islset
= libisl
.isl_set_lexmin(islset
)
204 return self
._fromislset
(islset
, self
.symbols
)
207 islset
= self
._toislset
(self
.polyhedra
, self
.symbols
)
208 islset
= libisl
.isl_set_lexmax(islset
)
209 return self
._fromislset
(islset
, self
.symbols
)
212 def _fromislset(cls
, islset
, symbols
):
213 from .polyhedra
import Polyhedron
214 islset
= libisl
.isl_set_remove_divs(islset
)
215 islbsets
= isl_set_basic_sets(islset
)
216 libisl
.isl_set_free(islset
)
218 for islbset
in islbsets
:
219 polyhedron
= Polyhedron
._fromislbasicset
(islbset
, symbols
)
220 polyhedra
.append(polyhedron
)
221 if len(polyhedra
) == 0:
222 from .polyhedra
import Empty
224 elif len(polyhedra
) == 1:
227 self
= object().__new
__(Domain
)
228 self
._polyhedra
= tuple(polyhedra
)
229 self
._symbols
= cls
._xsymbols
(polyhedra
)
230 self
._dimension
= len(self
._symbols
)
233 def _toislset(cls
, polyhedra
, symbols
):
234 polyhedron
= polyhedra
[0]
235 islbset
= polyhedron
._toislbasicset
(polyhedron
.equalities
,
236 polyhedron
.inequalities
, symbols
)
237 islset1
= libisl
.isl_set_from_basic_set(islbset
)
238 for polyhedron
in polyhedra
[1:]:
239 islbset
= polyhedron
._toislbasicset
(polyhedron
.equalities
,
240 polyhedron
.inequalities
, symbols
)
241 islset2
= libisl
.isl_set_from_basic_set(islbset
)
242 islset1
= libisl
.isl_set_union(islset1
, islset2
)
246 def fromstring(cls
, string
):
247 raise NotImplementedError
250 assert len(self
.polyhedra
) >= 2
251 strings
= [repr(polyhedron
) for polyhedron
in self
.polyhedra
]
252 return 'Or({})'.format(', '.join(strings
))
255 def fromsympy(cls
, expr
):
256 raise NotImplementedError
259 raise NotImplementedError
263 if len(domains
) == 0:
264 from .polyhedra
import Universe
267 return domains
[0].intersection(*domains
[1:])
270 if len(domains
) == 0:
271 from .polyhedra
import Empty
274 return domains
[0].union(*domains
[1:])