mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 01:43:35 +00:00
224 lines
5.7 KiB
Mathematica
224 lines
5.7 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module rtree_test.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module bool.
|
|
:- import_module float.
|
|
:- import_module int.
|
|
:- import_module list.
|
|
:- import_module math.
|
|
:- import_module rtree.
|
|
:- import_module std_util.
|
|
:- import_module string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type irtree == rtree(interval, int).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
main(!IO) :-
|
|
some [!RTree] (
|
|
!:RTree = rtree.init,
|
|
add_integers(0, 100, !RTree),
|
|
|
|
% Find all integers between 33.0 and 66.0.
|
|
some [!Is] (
|
|
!:Is = rtree.search_intersects(!.RTree, interval(33.0, 66.0)),
|
|
list.sort(!Is),
|
|
io.write_string("Integers from 33 to 66:\n", !IO),
|
|
io.write(!.Is, !IO),
|
|
io.nl(!IO),
|
|
io.nl(!IO)
|
|
),
|
|
|
|
% Find integer 22.
|
|
some [!Is] (
|
|
!:Is = rtree.search_intersects(!.RTree, interval(22.0, 22.0)),
|
|
io.write_string("Integers from 22 to 22:\n", !IO),
|
|
io.write(!.Is, !IO),
|
|
io.nl(!IO),
|
|
io.nl(!IO)
|
|
),
|
|
|
|
% Find all prime numbers.
|
|
some [!Is] (
|
|
!:Is = rtree.search_general(any_is_prime, true1, !.RTree),
|
|
list.sort(!Is),
|
|
io.write_string("Primes from 0 to 100:\n", !IO),
|
|
io.write(!.Is, !IO),
|
|
io.nl(!IO),
|
|
io.nl(!IO)
|
|
),
|
|
|
|
% Find the first prime number.
|
|
io.write_string("First prime from 0 to 100:\n", !IO),
|
|
( if rtree.search_first(any_is_prime, id, !.RTree, 100.0, L, _) then
|
|
io.write(L, !IO),
|
|
io.nl(!IO),
|
|
io.nl(!IO)
|
|
else
|
|
io.write_string("search_first FAILED!\n\n", !IO)
|
|
),
|
|
|
|
% Delete all odd numbers.
|
|
io.write_string("All odds deleted, " ++
|
|
"remaining integers from 33 to 66:\n", !IO),
|
|
some [!Is] (
|
|
( if delete_odd(1, 100, !RTree) then
|
|
!:Is = rtree.search_intersects(!.RTree, interval(33.0, 66.0)),
|
|
list.sort(!Is),
|
|
io.write(!.Is, !IO),
|
|
io.nl(!IO),
|
|
io.nl(!IO)
|
|
else
|
|
io.write_string("delete FAILED!\n\n", !IO)
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred true1(T::in) is semidet.
|
|
|
|
true1(_) :-
|
|
semidet_succeed.
|
|
|
|
:- pred id(int::in, float::out) is semidet.
|
|
|
|
id(I, float(I)) :-
|
|
semidet_succeed.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred add_integers(int::in, int::in, irtree::in, irtree::out) is det.
|
|
|
|
add_integers(N, M, !RTree) :-
|
|
( if N >= M then
|
|
true
|
|
else
|
|
NF = float(N),
|
|
K = interval(NF, NF),
|
|
insert(K, N, !RTree),
|
|
add_integers(N + 1, M, !RTree)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred test_range(bool::in, int::in, int::in, irtree::in,
|
|
list(int)::out, bool::out) is det.
|
|
|
|
test_range(Cnts, Mn, Mx, RT, Is, P) :-
|
|
K = interval(float(Mn), float(Mx)),
|
|
(
|
|
Cnts = yes,
|
|
Is0 = search_contains(RT, K)
|
|
;
|
|
Cnts = no,
|
|
Is0 = search_intersects(RT, K)
|
|
),
|
|
list.sort(Is0, Is),
|
|
P = check_range(Mn, Mx, Is).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func check_range(int, int, list(int)) = bool.
|
|
|
|
check_range(N, M, Is) = P :-
|
|
( if N > M then
|
|
(
|
|
Is = [] ,
|
|
P = yes
|
|
;
|
|
Is = [_ | _],
|
|
P = no
|
|
)
|
|
else
|
|
( if Is = [N | Is1] then
|
|
P = check_range(N + 1, M, Is1)
|
|
else
|
|
P = no
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% A very naive prime number test.
|
|
%
|
|
:- pred any_is_prime(interval::in) is semidet.
|
|
|
|
any_is_prime(I) :-
|
|
any_is_prime(I, _).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred any_is_prime(interval::in, float::out) is semidet.
|
|
|
|
any_is_prime(interval(Min, Max), P) :-
|
|
Min1 = ceiling(Min),
|
|
Max1 = floor(Max),
|
|
any_is_prime(Min1, Max1, P).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred any_is_prime(float::in, float::in, float::out) is semidet.
|
|
|
|
any_is_prime(Min, Max, P) :-
|
|
Min =< Max,
|
|
( if is_prime(Min) then
|
|
P = Min
|
|
else
|
|
any_is_prime(Min + 1.0, Max, P)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred is_prime(float::in) is semidet.
|
|
|
|
is_prime(N) :-
|
|
NI = floor_to_int(N),
|
|
NI > 1,
|
|
MaxD = round_to_int(sqrt(N)),
|
|
none_divides(2, MaxD, NI).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred none_divides(int::in, int::in, int::in) is semidet.
|
|
|
|
none_divides(N, M, I) :-
|
|
( if N > M then
|
|
true
|
|
else if I mod N = 0 then
|
|
false
|
|
else
|
|
none_divides(N + 1, M, I)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Assumption: N is odd.
|
|
%
|
|
:- pred delete_odd(int::in, int::in, irtree::in, irtree::out) is semidet.
|
|
|
|
delete_odd(N, M, !RT) :-
|
|
( if N >= M then
|
|
true
|
|
else
|
|
NF = float(N),
|
|
I = interval(NF, NF),
|
|
delete(I, N, !RT),
|
|
delete_odd(N + 2, M, !RT)
|
|
).
|