From fa1600a776cda29a10c6e122872178236495a977 Mon Sep 17 00:00:00 2001 From: Blaise Bourdin Date: Mon, 19 Oct 2026 11:52:14 -0400 Subject: [PATCH] Fix interval - left_open and right_open were passed by reference to basic_set_interval, which takes them by value, so all intervals were open. - Absent optional arguments were referenced, because .and. does not short circuit. This crashed test_basic when built with fpm. - The initialization of a_left and a_right implied save, so a closed end remained closed in subsequent calls. --- src/sets.f90 | 13 +++++++------ src/symengine_interface.f90 | 2 +- test/test_basic.f90 | 6 ++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/sets.f90 b/src/sets.f90 index 822eef9..cc27480 100644 --- a/src/sets.f90 +++ b/src/sets.f90 @@ -67,15 +67,16 @@ function integers() result(res) function basic_interval(a, b, left_open, right_open) result(res) class(basic), intent(in) :: a, b logical, optional :: left_open, right_open - integer(c_int) :: a_left = 1, a_right = 1 + integer(c_int) :: a_left, a_right integer(c_long) :: exception type(basic) :: res - res = Basic() - if (present(left_open) .and. .not. left_open) then - a_left = 0 + a_left = 1 + a_right = 1 + if (present(left_open)) then + if (.not. left_open) a_left = 0 end if - if (present(right_open) .and. .not. right_open) then - a_right = 0 + if (present(right_open)) then + if (.not. right_open) a_right = 0 end if res = Basic() exception = c_basic_set_interval(res%ptr, a%ptr, b%ptr, a_left, a_right) diff --git a/src/symengine_interface.f90 b/src/symengine_interface.f90 index bddb9c2..25c94d2 100644 --- a/src/symengine_interface.f90 +++ b/src/symengine_interface.f90 @@ -409,7 +409,7 @@ integer(c_long) function c_basic_set_intersection(s, a, b) bind(c, name='basic_s integer(c_long) function c_basic_set_interval(s, start, en, left_open, right_open) bind(c, name='basic_set_interval') import :: c_long, c_int, c_ptr type(c_ptr), value :: s, start, en - integer(c_int) :: left_open, right_open + integer(c_int), value :: left_open, right_open end function integer(c_long) function c_basic_set_finiteset(s, container) bind(c, name='basic_set_finiteset') import :: c_long, c_ptr diff --git a/test/test_basic.f90 b/test/test_basic.f90 index 0804e3c..abb61b1 100644 --- a/test/test_basic.f90 +++ b/test/test_basic.f90 @@ -704,7 +704,13 @@ subroutine test2() a = SymInteger(1) b = SymInteger(2) c = interval(a, b) + call assert(c%str() == '(1, 2)') c = interval(1, 2, left_open=.true., right_open=.false.) + call assert(c%str() == '(1, 2]') + c = interval(1, 2, left_open=.false.) + call assert(c%str() == '[1, 2)') + c = interval(1, 2, right_open=.true.) + call assert(c%str() == '(1, 2)') c = interval(1, 2_int64) c = interval(1_int64, 2) c = interval(1_int64, 2_int64)