Files
mercury/tests/hard_coded/myset.m
2020-10-06 19:20:18 +11:00

103 lines
2.3 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module myset.
:- interface.
:- import_module list.
:- import_module io.
:- type set(T).
% convert list to set
:- func set(list(T)) = set(T).
% convert set to list
:- pred set_to_list(set(T)::in, list(T)::out) is cc_multi.
:- func set_to_sorted_list(set(T)) = list(T).
% empty set
:- func {} = set(T).
:- pred is_empty(set(T)::in) is semidet.
% singleton set
:- func {T} = set(T).
% union of two sets
:- func set(T) + set(T) = set(T).
:- mode in + in = out is det.
% union of an element and a set
:- func [T | set(T)] = set(T).
% :- mode [in | in] = out is det.
:- mode [out | out] = in is cc_nondet.
:- pred print_myset_rep(set(T)::in, io::di, io::uo) is cc_multi.
:- implementation.
:- import_module bool.
:- import_module require.
:- type set(T)
---> set_rep(list(T))
where equality is set_equal.
:- pred set_equal(set(T)::in, set(T)::in) is semidet.
set_equal(Set1, Set2) :-
set_to_sorted_list(Set1) = set_to_sorted_list(Set2).
set(List) = set_rep(List).
set_to_list(set_rep(List), List).
set_to_sorted_list(Set) =
promise_only_solution(
( pred(Sorted::out) is cc_multi :-
Set = set_rep(Unsorted),
list.sort(Unsorted, Sorted)
)
).
{} = set_rep([]).
{X} = set_rep([X]).
is_empty(Set) :-
promise_only_solution(
( pred(Empty::out) is cc_multi :-
Set = set_rep(List),
Empty = (if List = [] then yes else no)
)
) = yes.
Set1 + Set2 =
promise_only_solution(
( pred(Union::out) is cc_multi :-
Set1 = set_rep(List1),
Set2 = set_rep(List2),
list.append(List1, List2, UnionList),
Union = set_rep(UnionList)
)
).
% [Element | set_rep(Rest)] = set_rep([Element | Rest]).
[Element | set_rep(Rest)] = UnionSet :-
( if is_empty(UnionSet) then
fail
else
UnionSet = set_rep(UnionList),
( if UnionList = [Element1 | Rest1] then
Element = Element1,
Rest = Rest1
else
error("unexpected non-empty list")
)
).
print_myset_rep(set_rep(List), !IO) :-
print("set_rep(", !IO),
print(List, !IO),
print(")", !IO).