[m-rev.] for review: re-order the interface of the ranges module
Julien Fischer
jfischer at opturion.com
Sun Mar 31 01:54:46 AEDT 2024
For review by anyone.
The main thing that needs to be reviewed here are the section headings.
There are no changes to any code.
-------------------------------------
Re-order the interface of the ranges module.
Make the interface of the ranges module consistent with that of the other set
modules.
library/ranges.m:
As above.
Note some inconsistencies between the names used in this module
and those used elsewhere.
Julien.
diff --git a/library/ranges.m b/library/ranges.m
index 4b250d3..2bd8d97 100644
--- a/library/ranges.m
+++ b/library/ranges.m
@@ -30,18 +30,15 @@
%
:- type ranges.
+%---------------------------------------------------------------------------%
+%
+% Initial creation of sets.
+%
+
% empty returns the empty set.
%
:- func empty = ranges.
- % is_empty(Set) is true iff Set is the an empty set.
- %
-:- pred is_empty(ranges::in) is semidet.
-
- % is_non_empty(Set) is true iff Set is not an empty set.
- %
-:- pred is_non_empty(ranges::in) is semidet.
-
% universe returns the largest set that can be handled by this module.
% This is the set of integers (min_int + 1)..max_int. Note that min_int
% cannot be represented in any set.
@@ -52,17 +49,46 @@
%
:- func range(int, int) = ranges.
- % split(Set, Lo, Hi, Rest) is true iff Lo..Hi is the first range (i.e. the
- % range containing the smallest integers) in Set, and Rest is the set Set
- % with this range removed.
+%---------------------------------------------------------------------------%
+%
+% Emptiness and other tests.
+%
+
+ % is_empty(Set) is true iff Set is the an empty set.
%
-:- pred split(ranges::in, int::out, int::out, ranges::out) is semidet.
+:- pred is_empty(ranges::in) is semidet.
+
+ % is_non_empty(Set) is true iff Set is not an empty set.
+ %
+:- pred is_non_empty(ranges::in) is semidet.
% is_contiguous(Set, Lo, Hi) is true iff Set is the set of all
% integers from Lo to Hi, both inclusive.
%
:- pred is_contiguous(ranges::in, int::out, int::out) is semidet.
+%---------------------------------------------------------------------------%
+%
+% Membership tests.
+%
+
+ % member(X, Set) is true iff X is a member of Set.
+ %
+:- pred member(int::in, ranges::in) is semidet.
+
+ % Nondeterministically produce each range.
+ %
+:- pred range_member(int::out, int::out, ranges::in) is nondet.
+
+ % Nondeterministically produce each element in the set.
+ %
+:- pred nondet_member(int::out, ranges::in) is nondet.
+
+%---------------------------------------------------------------------------%
+%
+% Insertions and deletions.
+%
+
% insert(X, Set0, Set) is true iff Set is the union of Set0 and the set
% containing only X.
%
@@ -75,12 +101,110 @@
% except X.
%
:- func delete(int, ranges) = ranges.
+% NOTE_TO_IMPLEMENTORS XXX add predicate version of delete.
+
+%---------------------------------------------------------------------------%
+%
+% Comparisons between sets.
+%
+
+ % subset(SetA, SetB) is true iff every value in SetA is in SetB.
+ %
+:- pred subset(ranges::in, ranges::in) is semidet.
+
+ % disjoint(SetA, SetB) is true iff SetA and SetB have no values in common.
+ %
+:- pred disjoint(ranges::in, ranges::in) is semidet.
+
+ % Compare the sets of integers given by the two ranges using lexicographic
+ % ordering on the sorted set form.
+ %
+:- pred compare_lex(comparison_result::uo, ranges::in, ranges::in) is det.
+
+%---------------------------------------------------------------------------%
+%
+% Operations on two or more sets.
+%
+
+ % union(SetA, SetB): return the set that contains all the integers in SetA
+ % and SetB.
+ %
+:- func union(ranges, ranges) = ranges.
+
+ % intersection(SetA, SetB): return the set that contains all the integers
+ % in both SetA and SetB.
+ % NOTE_TO_IMPLEMENTORS XXX this is called intersect elsewhere.
+:- func intersection(ranges, ranges) = ranges.
+
+ % difference(SetA, SetB): return the set that contains all of the integers
+ % that are in SetA but not in SetB.
+ %
+:- func difference(ranges, ranges) = ranges.
+
+%---------------------------------------------------------------------------%
+%
+% Operations that divide a set into two parts.
+%
+
+ % split(Set, Lo, Hi, Rest) is true iff Lo..Hi is the first range (i.e. the
+ % range containing the smallest integers) in Set, and Rest is the set Set
+ % with this range removed.
+ %
+:- pred split(ranges::in, int::out, int::out, ranges::out) is semidet.
+
+ % prune_to_next_non_member(Set0, Set, X0, X):
+ %
+ % Set X to the smallest integer greater than or equal to X0 that is not in
+ % Set0 and Set to the set of integers in Set0 that are greater than X.
+ %
+:- pred prune_to_next_non_member(ranges::in, ranges::out,
+ int::in, int::out) is det.
+
+ % prune_to_prev_non_member(Set0, Set, X0, X):
+ %
+ % Set X to the largest integer less than or equal to X0 that is not in Set0
+ % and Set to the set of integers in Set0 that are less than X.
+ %
+:- pred prune_to_prev_non_member(ranges::in, ranges::out,
+ int::in, int::out) is det.
+
+%---------------------------------------------------------------------------%
+%
+% Converting lists and sets to ranges.
+%
+
+ % Convert from a list of integers.
+ %
+:- func from_list(list(int)) = ranges.
+
+ % Convert from a set of integers.
+ %
+:- func from_set(set(int)) = ranges.
+
+%---------------------------------------------------------------------------%
+%
+% Converting sets to lists.
+%
+
+ % Convert to a sorted list of integers.
+ %
+:- func to_sorted_list(ranges) = list(int).
+
+%---------------------------------------------------------------------------%
+%
+% Counting.
+%
% Return the number of distinct integers that are in the set
% (as opposed to the number of ranges).
- %
+ % NOTE_TO_IMPLEMENTORS XXX this is called count in the other set modules.
:- func size(ranges) = int.
+%---------------------------------------------------------------------------%
+%
+% Selecting individual elements from a set.
+%
+
% Returns the median value of the set. In the case of a tie, return the
% lower of the two options.
%
@@ -101,18 +225,6 @@
%
:- pred next(ranges::in, int::in, int::out) is semidet.
- % member(X, Set) is true iff X is a member of Set.
- %
-:- pred member(int::in, ranges::in) is semidet.
-
- % Nondeterministically produce each range.
- %
-:- pred range_member(int::out, int::out, ranges::in) is nondet.
-
- % Nondeterministically produce each element in the set.
- %
-:- pred nondet_member(int::out, ranges::in) is nondet.
-
% search_range(X, Set, Lo, Hi):
%
% If X is in Set, then succeed, setting Lo and Hi to the endpoints
@@ -120,28 +232,10 @@
%
:- pred search_range(int::in, ranges::in, int::out, int::out) is semidet.
- % subset(SetA, SetB) is true iff every value in SetA is in SetB.
- %
-:- pred subset(ranges::in, ranges::in) is semidet.
-
- % disjoint(SetA, SetB) is true iff SetA and SetB have no values in common.
- %
-:- pred disjoint(ranges::in, ranges::in) is semidet.
-
- % union(SetA, SetB): return the set that contains all the integers in SetA
- % and SetB.
- %
-:- func union(ranges, ranges) = ranges.
-
- % intersection(SetA, SetB): return the set that contains all the integers
- % in both SetA and SetB.
- %
-:- func intersection(ranges, ranges) = ranges.
-
- % difference(SetA, SetB): return the set that contains all of the integers
- % that are in SetA but not in SetB.
- %
-:- func difference(ranges, ranges) = ranges.
+%---------------------------------------------------------------------------%
+%
+% Filtering elements in a set.
+%
% restrict_min(Min, Set): return the set that contains all of the integers
% in Set that are greater than or equal to Min.
@@ -158,21 +252,10 @@
%
:- func restrict_range(int, int, ranges) = ranges.
- % prune_to_next_non_member(Set0, Set, X0, X):
- %
- % Set X to the smallest integer greater than or equal to X0 that is not in
- % Set0 and Set to the set of integers in Set0 that are greater than X.
- %
-:- pred prune_to_next_non_member(ranges::in, ranges::out,
- int::in, int::out) is det.
-
- % prune_to_prev_non_member(Set0, Set, X0, X):
- %
- % Set X to the largest integer less than or equal to X0 that is not in Set0
- % and Set to the set of integers in Set0 that are less than X.
- %
-:- pred prune_to_prev_non_member(ranges::in, ranges::out,
- int::in, int::out) is det.
+%---------------------------------------------------------------------------%
+%
+% Transformations of a set.
+%
% Negate all numbers: X in Set <=> -X in negate(Set)
%
@@ -195,27 +278,9 @@
:- func contraction(ranges, int) = ranges.
%---------------------------------------------------------------------------%
-
- % Convert to a sorted list of integers.
- %
-:- func to_sorted_list(ranges) = list(int).
-
- % Convert from a list of integers.
- %
-:- func from_list(list(int)) = ranges.
-
- % Convert from a set of integers.
- %
-:- func from_set(set(int)) = ranges.
-
-%---------------------------------------------------------------------------%
-
- % Compare the sets of integers given by the two ranges using lexicographic
- % ordering on the sorted set form.
- %
-:- pred compare_lex(comparison_result::uo, ranges::in, ranges::in) is det.
-
-%---------------------------------------------------------------------------%
+%
+% Standard higher-order functions on elements in a set.
+%
:- pred foldl(pred(int, A, A), ranges, A, A).
:- mode foldl(in(pred(in, in, out) is det), in, in, out) is det.
@@ -258,6 +323,9 @@
:- mode foldr(in(pred(in, di, uo) is semidet), in, di, uo) is semidet.
%---------------------------------------------------------------------------%
+%
+% Standard higher-order functions on range endpoint pairs in set.
+%
% For each range, call the predicate, passing it the lower and
% upper bound and threading through an accumulator.
@@ -414,25 +482,18 @@
---> nil
; range(int, int, ranges).
-%---------------------------------------------------------------------------%
-
:- pragma foreign_decl("C",
"
typedef MR_Word ML_Ranges;
").
+%---------------------------------------------------------------------------%
+
:- pragma foreign_export("C", ranges.empty = out, "ML_ranges_empty").
:- pragma foreign_export("Java", ranges.empty = out, "empty").
empty = nil.
-:- pragma foreign_export("C", ranges.is_empty(in), "ML_ranges_is_empty").
-:- pragma foreign_export("Java", ranges.is_empty(in), "is_empty").
-
-is_empty(nil).
-
-is_non_empty(range(_, _, _)).
-
:- pragma foreign_export("C", universe = out, "ML_ranges_universe").
:- pragma foreign_export("Java", universe = out, "universe").
@@ -450,75 +511,17 @@ range(Min, Max) = Ranges :-
Ranges = range(Min - 1, Max, nil)
).
-:- pragma foreign_export("C", ranges.split(in, out, out, out),
- "ML_ranges_split").
-:- pragma foreign_export("Java", ranges.split(in, out, out, out),
- "split").
-
-split(range(Min1, Max, Rest), Min1 + 1, Max, Rest).
-
-is_contiguous(Range, Min + 1, Max) :-
- Range = range(Min, Max, nil).
-
-:- pragma foreign_export("C", ranges.insert(in, in) = out, "ML_ranges_insert").
-:- pragma foreign_export("Java", ranges.insert(in, in) = out, "insert").
-
-insert(N, As) = union(As, range(N, N)).
-insert(N, As, Bs) :- Bs = insert(N, As).
-
-delete(N, As) = difference(As, range(N, N)).
-
%---------------------------------------------------------------------------%
-:- pragma foreign_export("C", size(in) = out, "ML_ranges_size").
-:- pragma foreign_export("Java", size(in) = out, "size").
-
-size(nil) = 0.
-size(range(L, U, Rest)) = (U - L) + size(Rest).
-
-median(As) = N :-
- Size = size(As),
- ( if Size > 0 then
- MiddleIndex = (Size + 1) / 2
- else
- error($pred, "empty set")
- ),
- N = element_index(As, MiddleIndex).
-
- % element_index(Intervals, I) returns the I'th largest value in the set
- % represented by Intervals (the least item in the set having index 1).
- %
-:- func element_index(ranges, int) = int.
-
-element_index(nil, _) =
- func_error($pred, "index out of range").
-element_index(range(L, U, Rest), I) = N :-
- N0 = L + I,
- ( if N0 =< U then
- N = N0
- else
- N = element_index(Rest, N0 - U)
- ).
-
-%---------------------------------------------------------------------------%
-
-least(range(L, _, _), L + 1).
-
-greatest(range(_, U0, As), U) :-
- greatest_2(U0, As, U).
+:- pragma foreign_export("C", ranges.is_empty(in), "ML_ranges_is_empty").
+:- pragma foreign_export("Java", ranges.is_empty(in), "is_empty").
-:- pred greatest_2(int::in, ranges::in, int::out) is det.
+is_empty(nil).
-greatest_2(U, nil, U).
-greatest_2(_, range(_, U0, As), U) :-
- greatest_2(U0, As, U).
+is_non_empty(range(_, _, _)).
-next(range(L, U, As), N0, N) :-
- ( if N0 < U then
- N = int.max(L, N0) + 1
- else
- ranges.next(As, N0, N)
- ).
+is_contiguous(Range, Min + 1, Max) :-
+ Range = range(Min, Max, nil).
%---------------------------------------------------------------------------%
@@ -538,24 +541,19 @@ range_member(L, U, range(A0, A1, As)) :-
range_member(L, U, As)
).
-%---------------------------------------------------------------------------%
-
nondet_member(N, As) :-
range_member(L, U, As),
int.nondet_int_in_range(L, U, N).
%---------------------------------------------------------------------------%
-search_range(N, range(Lo0, Hi0, Rest), Lo, Hi) :-
- ( if
- N > Lo0,
- N =< Hi0
- then
- Lo = Lo0 + 1,
- Hi = Hi0
- else
- search_range(N, Rest, Lo, Hi)
- ).
+:- pragma foreign_export("C", ranges.insert(in, in) = out, "ML_ranges_insert").
+:- pragma foreign_export("Java", ranges.insert(in, in) = out, "insert").
+
+insert(N, As) = union(As, range(N, N)).
+insert(N, As, Bs) :- Bs = insert(N, As).
+
+delete(N, As) = difference(As, range(N, N)).
%---------------------------------------------------------------------------%
@@ -569,6 +567,92 @@ disjoint(A, B) :-
%---------------------------------------------------------------------------%
+compare_lex(Result, A, B) :-
+ (
+ A = nil,
+ B = nil,
+ Result = (=)
+ ;
+ A = nil,
+ B = range(_, _, _),
+ Result = (<)
+ ;
+ A = range(_, _, _),
+ B = nil,
+ Result = (>)
+ ;
+ A = range(LBA, UBA, APrime),
+ B = range(LBB, UBB, BPrime),
+ % NOTE: when we unpack a range/3 constructor we must add one
+ % to the first argument since that is the lowest value in that
+ % subset.
+ compare_lex_2(Result, LBA + 1, UBA, LBB + 1, UBB, APrime, BPrime)
+ ).
+
+:- pred compare_lex_2(comparison_result::uo, int::in, int::in,
+ int::in, int::in, ranges::in, ranges::in) is det.
+
+compare_lex_2(Result, !.LBA, !.UBA, !.LBB, !.UBB, !.NextA, !.NextB) :-
+ compare(LBResult, !.LBA, !.LBB),
+ (
+ ( LBResult = (<)
+ ; LBResult = (>)
+ ),
+ Result = LBResult
+ ;
+ LBResult = (=),
+ compare(UBResult, !.UBA, !.UBB),
+ (
+ UBResult = (=),
+ compare_lex(Result, !.NextA, !.NextB)
+ ;
+ ( UBResult = (<)
+ ; UBResult = (>)
+ ),
+ ( if
+ !.LBA = !.UBA,
+ !.LBB = !.UBB
+ then
+ compare_lex(Result, !.NextA, !.NextB)
+ else if
+ !.LBA < !.UBA,
+ !.LBB = !.UBB
+ then
+ !:LBA = !.LBA + 1,
+ (
+ !.NextB = nil,
+ Result = (>)
+ ;
+ !.NextB = range(!:LBB, !:UBB, !:NextB),
+ compare_lex_2(Result, !.LBA, !.UBA, !.LBB + 1, !.UBB,
+ !.NextA, !.NextB)
+ )
+ else if
+ !.LBA = !.UBA,
+ !.LBB < !.UBB
+ then
+ !:LBB = !.LBB + 1,
+ (
+ !.NextA = nil,
+ Result = (<)
+ ;
+ !.NextA = range(!:LBA, !:UBA, !:NextA),
+ compare_lex_2(Result, !.LBA + 1, !.UBA, !.LBB, !.UBB,
+ !.NextA, !.NextB)
+ )
+ else
+ !:LBA = !.LBA + 1,
+ !:LBB = !.LBB + 1,
+ disable_warning [suspicious_recursion] (
+ compare_lex_2(Result, !.LBA, !.UBA, !.LBB, !.UBB,
+ !.NextA, !.NextB)
+ )
+ )
+ )
+ ).
+
+%---------------------------------------------------------------------------%
+
% union(A, B) = A \/ B
%
union(nil, Bs) = Bs.
@@ -648,6 +732,8 @@ n_union_na_nb(L, UA, As0, UB, Bs0) = Result :-
Result = range(L, UB, diff_a_nb(Bs0, UA, As0))
).
+%---------------------------------------------------------------------------%
+
% intersection(A, B) = A /\ B
%
intersection(nil, _) = nil.
@@ -725,6 +811,8 @@ int_a_nb(As @ range(LA, UA, As0), UB, Bs0) = Result :-
Result = ranges.difference(As, Bs0)
).
+%---------------------------------------------------------------------------%
+
% difference(A, B) = A \ B
%
difference(nil, _) = nil.
@@ -803,28 +891,12 @@ diff_na_nb(UA, As0, UB, Bs0) = Result :-
%---------------------------------------------------------------------------%
-restrict_min(_, nil) = nil.
-restrict_min(Min, As0 @ range(L, U, As1)) = As :-
- ( if Min =< L then
- As = As0
- else if Min =< U then
- As = range(Min - 1, U, As1)
- else
- As = restrict_min(Min, As1)
- ).
-
-restrict_max(_, nil) = nil.
-restrict_max(Max, range(L, U, As0)) = As :-
- ( if Max =< L then
- As = nil
- else if Max =< U then
- As = range(L, Max, nil)
- else
- As = range(L, U, restrict_max(Max, As0))
- ).
+:- pragma foreign_export("C", ranges.split(in, out, out, out),
+ "ML_ranges_split").
+:- pragma foreign_export("Java", ranges.split(in, out, out, out),
+ "split").
-restrict_range(Min, Max, As) =
- ranges.intersection(range(Min - 1, Max, nil), As).
+split(range(Min1, Max, Rest), Min1 + 1, Max, Rest).
%---------------------------------------------------------------------------%
@@ -851,6 +923,121 @@ prune_to_prev_non_member(range(LA, UA, As0), Result, !N) :-
Result = range(LA, UA, Result0)
).
+%---------------------------------------------------------------------------%
+
+from_list(List) =
+ list.foldl(ranges.insert, List, ranges.empty).
+
+from_set(Set) =
+ ranges.from_list(set.to_sorted_list(Set)).
+
+%---------------------------------------------------------------------------%
+
+to_sorted_list(nil) = [].
+to_sorted_list(range(L, H, Rest)) =
+ to_sorted_list_2(L, H, to_sorted_list(Rest)).
+
+:- func to_sorted_list_2(int, int, list(int)) = list(int).
+
+to_sorted_list_2(L, H, Ints) =
+ ( if H = L then
+ Ints
+ else
+ to_sorted_list_2(L, H - 1, [H | Ints])
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_export("C", size(in) = out, "ML_ranges_size").
+:- pragma foreign_export("Java", size(in) = out, "size").
+
+size(nil) = 0.
+size(range(L, U, Rest)) = (U - L) + size(Rest).
+
+%---------------------------------------------------------------------------%
+
+median(As) = N :-
+ Size = size(As),
+ ( if Size > 0 then
+ MiddleIndex = (Size + 1) / 2
+ else
+ error($pred, "empty set")
+ ),
+ N = element_index(As, MiddleIndex).
+
+ % element_index(Intervals, I) returns the I'th largest value in the set
+ % represented by Intervals (the least item in the set having index 1).
+ %
+:- func element_index(ranges, int) = int.
+
+element_index(nil, _) =
+ func_error($pred, "index out of range").
+element_index(range(L, U, Rest), I) = N :-
+ N0 = L + I,
+ ( if N0 =< U then
+ N = N0
+ else
+ N = element_index(Rest, N0 - U)
+ ).
+
+%---------------------------------------------------------------------------%
+
+least(range(L, _, _), L + 1).
+
+greatest(range(_, U0, As), U) :-
+ greatest_2(U0, As, U).
+
+:- pred greatest_2(int::in, ranges::in, int::out) is det.
+
+greatest_2(U, nil, U).
+greatest_2(_, range(_, U0, As), U) :-
+ greatest_2(U0, As, U).
+
+next(range(L, U, As), N0, N) :-
+ ( if N0 < U then
+ N = int.max(L, N0) + 1
+ else
+ ranges.next(As, N0, N)
+ ).
+
+search_range(N, range(Lo0, Hi0, Rest), Lo, Hi) :-
+ ( if
+ N > Lo0,
+ N =< Hi0
+ then
+ Lo = Lo0 + 1,
+ Hi = Hi0
+ else
+ search_range(N, Rest, Lo, Hi)
+ ).
+
+%---------------------------------------------------------------------------%
+
+restrict_min(_, nil) = nil.
+restrict_min(Min, As0 @ range(L, U, As1)) = As :-
+ ( if Min =< L then
+ As = As0
+ else if Min =< U then
+ As = range(Min - 1, U, As1)
+ else
+ As = restrict_min(Min, As1)
+ ).
+
+restrict_max(_, nil) = nil.
+restrict_max(Max, range(L, U, As0)) = As :-
+ ( if Max =< L then
+ As = nil
+ else if Max =< U then
+ As = range(L, Max, nil)
+ else
+ As = range(L, U, restrict_max(Max, As0))
+ ).
+
+restrict_range(Min, Max, As) =
+ ranges.intersection(range(Min - 1, Max, nil), As).
+
+%---------------------------------------------------------------------------%
+
negate(As) = negate_aux(As, nil).
:- func negate_aux(ranges::in, ranges::in) = (ranges::out) is det.
@@ -959,113 +1146,6 @@ div_down_np(A, B) = int.unchecked_quotient(A - B + 1, B).
%---------------------------------------------------------------------------%
-to_sorted_list(nil) = [].
-to_sorted_list(range(L, H, Rest)) =
- to_sorted_list_2(L, H, to_sorted_list(Rest)).
-
-:- func to_sorted_list_2(int, int, list(int)) = list(int).
-
-to_sorted_list_2(L, H, Ints) =
- ( if H = L then
- Ints
- else
- to_sorted_list_2(L, H-1, [H | Ints])
- ).
-
-from_list(List) =
- list.foldl(ranges.insert, List, ranges.empty).
-
-from_set(Set) =
- ranges.from_list(set.to_sorted_list(Set)).
-
-%---------------------------------------------------------------------------%
-
-compare_lex(Result, A, B) :-
- (
- A = nil,
- B = nil,
- Result = (=)
- ;
- A = nil,
- B = range(_, _, _),
- Result = (<)
- ;
- A = range(_, _, _),
- B = nil,
- Result = (>)
- ;
- A = range(LBA, UBA, APrime),
- B = range(LBB, UBB, BPrime),
- % NOTE: when we unpack a range/3 constructor we must add one
- % to the first argument since that is the lowest value in that
- % subset.
- compare_lex_2(Result, LBA + 1, UBA, LBB + 1, UBB, APrime, BPrime)
- ).
-
-:- pred compare_lex_2(comparison_result::uo, int::in, int::in,
- int::in, int::in, ranges::in, ranges::in) is det.
-
-compare_lex_2(Result, !.LBA, !.UBA, !.LBB, !.UBB, !.NextA, !.NextB) :-
- compare(LBResult, !.LBA, !.LBB),
- (
- ( LBResult = (<)
- ; LBResult = (>)
- ),
- Result = LBResult
- ;
- LBResult = (=),
- compare(UBResult, !.UBA, !.UBB),
- (
- UBResult = (=),
- compare_lex(Result, !.NextA, !.NextB)
- ;
- ( UBResult = (<)
- ; UBResult = (>)
- ),
- ( if
- !.LBA = !.UBA,
- !.LBB = !.UBB
- then
- compare_lex(Result, !.NextA, !.NextB)
- else if
- !.LBA < !.UBA,
- !.LBB = !.UBB
- then
- !:LBA = !.LBA + 1,
- (
- !.NextB = nil,
- Result = (>)
- ;
- !.NextB = range(!:LBB, !:UBB, !:NextB),
- compare_lex_2(Result, !.LBA, !.UBA, !.LBB + 1, !.UBB,
- !.NextA, !.NextB)
- )
- else if
- !.LBA = !.UBA,
- !.LBB < !.UBB
- then
- !:LBB = !.LBB + 1,
- (
- !.NextA = nil,
- Result = (<)
- ;
- !.NextA = range(!:LBA, !:UBA, !:NextA),
- compare_lex_2(Result, !.LBA + 1, !.UBA, !.LBB, !.UBB,
- !.NextA, !.NextB)
- )
- else
- !:LBA = !.LBA + 1,
- !:LBB = !.LBB + 1,
- disable_warning [suspicious_recursion] (
- compare_lex_2(Result, !.LBA, !.UBA, !.LBB, !.UBB,
- !.NextA, !.NextB)
- )
- )
- )
- ).
-
-%---------------------------------------------------------------------------%
-
foldl(P, Ranges, !Acc) :-
(
Ranges = nil
More information about the reviews
mailing list