From c14177470b51a8e9f4ac80819ce7172b8eb50456 Mon Sep 17 00:00:00 2001 From: Addison Date: Tue, 18 Aug 2026 10:59:24 -0500 Subject: [PATCH 1/3] add map function property queries --- namedisl/set_like.py | 10 +++++++++- namedisl/test/test_set_like.py | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/namedisl/set_like.py b/namedisl/set_like.py index 0fee3a3..1111792 100644 --- a/namedisl/set_like.py +++ b/namedisl/set_like.py @@ -738,6 +738,8 @@ def make_map_from_domain_and_range( class Map(_NamedIslMapLike[isl.Map], _NamedIslUnbasic[isl.Map]): """ .. automethod:: is_bijective + .. automethod:: is_injective + .. automethod:: is_single_valued .. automethod:: complement .. automethod:: simple_hull .. automethod:: convex_hull @@ -756,9 +758,15 @@ class Map(_NamedIslMapLike[isl.Map], _NamedIslUnbasic[isl.Map]): _isl_type: ClassVar[type[IslObject]] = isl.Map - def is_bijective(self): + def is_bijective(self) -> bool: return self._obj.is_bijective() + def is_injective(self) -> bool: + return self._obj.is_injective() + + def is_single_valued(self) -> bool: + return self._obj.is_single_valued() + def complement(self) -> Map: return Map(self._obj.complement(), self.space) diff --git a/namedisl/test/test_set_like.py b/namedisl/test/test_set_like.py index a4cabea..7a4461d 100644 --- a/namedisl/test/test_set_like.py +++ b/namedisl/test/test_set_like.py @@ -315,6 +315,24 @@ def test_map_coalesce() -> None: assert len(map_.coalesce().basic_maps()) == 1 +def test_map_function_properties() -> None: + bijective = nisl.make_map("{ [i] -> [j = i] : 0 <= i < 2 }") + many_to_one = nisl.make_map("{ [i] -> [j = 0] : 0 <= i < 2 }") + one_to_many = nisl.make_map("{ [i = 0] -> [j] : 0 <= j < 2 }") + + assert bijective.is_bijective() + assert bijective.is_injective() + assert bijective.is_single_valued() + + assert not many_to_one.is_bijective() + assert not many_to_one.is_injective() + assert many_to_one.is_single_valued() + + assert not one_to_many.is_bijective() + assert one_to_many.is_injective() + assert not one_to_many.is_single_valued() + + @pytest.mark.parametrize("ndims_domain", [2, 3, 4, 5]) @pytest.mark.parametrize("ndims_range", [2, 3, 4, 5]) @pytest.mark.parametrize("has_params", [True, False]) From 8b3b3810a924a9857331ffd583e65651a6d25438 Mon Sep 17 00:00:00 2001 From: Addison Date: Tue, 18 Aug 2026 11:22:46 -0500 Subject: [PATCH 2/3] add map lexmin --- namedisl/set_like.py | 4 ++++ namedisl/test/test_set_like.py | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/namedisl/set_like.py b/namedisl/set_like.py index 1111792..37df6b1 100644 --- a/namedisl/set_like.py +++ b/namedisl/set_like.py @@ -740,6 +740,7 @@ class Map(_NamedIslMapLike[isl.Map], _NamedIslUnbasic[isl.Map]): .. automethod:: is_bijective .. automethod:: is_injective .. automethod:: is_single_valued + .. automethod:: lexmin .. automethod:: complement .. automethod:: simple_hull .. automethod:: convex_hull @@ -767,6 +768,9 @@ def is_injective(self) -> bool: def is_single_valued(self) -> bool: return self._obj.is_single_valued() + def lexmin(self) -> Map: + return Map(self._obj.lexmin(), self.space) + def complement(self) -> Map: return Map(self._obj.complement(), self.space) diff --git a/namedisl/test/test_set_like.py b/namedisl/test/test_set_like.py index 7a4461d..7d64c45 100644 --- a/namedisl/test/test_set_like.py +++ b/namedisl/test/test_set_like.py @@ -333,6 +333,14 @@ def test_map_function_properties() -> None: assert not one_to_many.is_single_valued() +def test_map_lexmin_preserves_named_space() -> None: + map_ = nisl.make_map( + "{ [target] -> [source] : target = 0 and 1 <= source <= 2 }" + ) + + assert map_.lexmin() == nisl.make_map("{ [target = 0] -> [source = 1] }") + + @pytest.mark.parametrize("ndims_domain", [2, 3, 4, 5]) @pytest.mark.parametrize("ndims_range", [2, 3, 4, 5]) @pytest.mark.parametrize("has_params", [True, False]) From 30aedce0c6322a6ab7763a17baf9eaee07a2d226 Mon Sep 17 00:00:00 2001 From: Addison Date: Fri, 28 Aug 2026 18:49:28 -0500 Subject: [PATCH 3/3] add detect_equalities to set-like objects --- namedisl/set_like.py | 7 +++++++ namedisl/test/test_set_like.py | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/namedisl/set_like.py b/namedisl/set_like.py index 37df6b1..07e25b3 100644 --- a/namedisl/set_like.py +++ b/namedisl/set_like.py @@ -189,6 +189,7 @@ class _NamedIslSetOrMapLike(NamedIslObject[IslSetOrMapLikeT_co]): .. automethod:: project_out .. automethod:: project_out_except .. automethod:: gist + .. automethod:: detect_equalities .. automethod:: remove_divs .. automethod:: compute_divs .. automethod:: __and__ @@ -312,6 +313,12 @@ def gist(self, context: Self) -> Self: self_aligned.space, ) + def detect_equalities(self) -> Self: + return type(self)( + cast("IslSetOrMapLikeT_co", self._obj.detect_equalities()), + self.space, + ) + def compute_divs(self) -> Self: return type(self)( cast("IslSetOrMapLikeT_co", self._obj.compute_divs()), diff --git a/namedisl/test/test_set_like.py b/namedisl/test/test_set_like.py index 7d64c45..83b4df7 100644 --- a/namedisl/test/test_set_like.py +++ b/namedisl/test/test_set_like.py @@ -315,6 +315,15 @@ def test_map_coalesce() -> None: assert len(map_.coalesce().basic_maps()) == 1 +def test_map_detect_equalities() -> None: + map_ = nisl.make_map("{ [i] -> [j] : 0 <= i <= j < 5 }") + detected = map_.detect_equalities() + + assert isinstance(detected, nisl.Map) + assert detected.space == map_.space + assert detected.equals(map_) + + def test_map_function_properties() -> None: bijective = nisl.make_map("{ [i] -> [j = i] : 0 <= i < 2 }") many_to_one = nisl.make_map("{ [i] -> [j = 0] : 0 <= i < 2 }")