Files
mercury/library/set.m
Thomas Conway c1b2113faa Added set__power_intersect(Sets, Intersection) takes the intersection
set.nl:
	Added set__power_intersect(Sets, Intersection) takes the intersection
	of all the sets in Sets and puts the result in Intersection.
1995-01-19 23:23:44 +00:00

289 lines
7.7 KiB
Mathematica

%--------------------------------------------------------------------------%
%--------------------------------------------------------------------------%
% File: set.nl.
% Main authors: conway, fjh.
% This file contains a `set' ADT.
% Sets are implemented here as unsorted lists, which may contain duplicates.
%--------------------------------------------------------------------------%
:- module set.
:- interface.
:- import_module list, std_util.
:- type set(_T).
% `set__list_to_set(List, Set)' is true iff `Set' is the set
% containing only the members of `List'.
:- pred set__list_to_set(list(T), set(T)).
:- mode set__list_to_set(in, out) is det.
% `set__sorted_list_to_set(List, Set)' is true iff `Set' is the set
% containing only the members of `List'. `List' must be sorted.
:- pred set__sorted_list_to_set(list(T), set(T)).
:- mode set__sorted_list_to_set(in, out) is det.
% `set__list_to_set(Set, List)' is true iff `List' is the list
% of all the members of `Set', in sorted order.
:- pred set__to_sorted_list(set(T), list(T)).
:- mode set__to_sorted_list(in, out) is det.
% `set__init(Set)' is true iff `Set' is an empty set.
% `set__init(Set)' is true iff `Set' is an empty set.
:- pred set__init(set(_T)).
:- mode set__init(out) is det.
:- pred set__singleton_set(set(T), T).
:- mode set__singleton_set(in, out) is semidet.
:- mode set__singleton_set(out, in) is det.
% `set__equal(SetA, SetB)' is true iff
% `SetA' and `SetB' contain the same elements.
:- pred set__equal(set(T), set(T)).
:- mode set__equal(in, in) is semidet.
:- pred set__empty(set(_T)).
:- mode set__empty(in) is semidet.
% `set__subset(SetA, SetB)' is true iff `SetA' is a subset of `SetB'.
:- pred set__subset(set(T), set(T)).
:- mode set__subset(in, in) is semidet.
% `set__superset(SetA, SetB)' is true iff `SetA' is a
% superset of `SetB'.
:- pred set__superset(set(T), set(T)).
:- mode set__superset(in, in) is semidet.
% `set_member(X, Set)' is true iff `X' is a member of `Set'.
:- pred set__member(T, set(T)).
:- mode set__member(in, in) is semidet.
:- mode set__member(out, in) is nondet.
% `set_member(X, Set, Res)' returns yes iff `X' is a member of `Set'.
:- pred set__is_member(T, set(T), bool).
:- mode set__is_member(in, in, out) is det.
% `set__insert(Set0, X, Set)' is true iff `Set' is the union of
% `Set0' and the set containing only `X'.
:- pred set__insert(set(T), T, set(T)).
:- mode set__insert(in, in, out) is det.
% `set__insert_list(Set0, Xs, Set)' is true iff `Set' is the union of
% `Set0' and the set containing only the members of `Xs'.
:- pred set__insert_list(set(T), list(T), set(T)).
:- mode set__insert_list(in, in, out) is det.
% `set__delete(Set0, X, Set)' is true iff `Set0' contains `X',
% and `Set' is the relative complement of `Set0' and the set
% containing only `X', i.e. if `Set' is the set which contains
% all the elements of `Set0' except `X'.
:- pred set__delete(set(T), T, set(T)).
:- mode set__delete(in, in, out) is semidet.
:- mode set__delete(in, out, out) is nondet.
% `set__delete_list(Set0, Xs, Set)' is true iff Xs does not
% contain any duplicates, `Set0' contains every member of `Xs',
% and `Set' is the relative complement of `Set0' and the set
% containing only the members of `Xs'.
:- pred set__delete_list(set(T), list(T), set(T)).
:- mode set__delete_list(in, in, out) is semidet.
% `set__remove(Set0, X, Set)' is true iff `Set' is the relative
% complement of `Set0' and the set containing only `X', i.e.
% if `Set' is the set which contains all the elements of `Set0'
% except `X'.
:- pred set__remove(set(T), T, set(T)).
:- mode set__remove(in, in, out) is det.
% `set__remove_list(Set0, Xs, Set)' is true iff `Set' is the relative
% complement of `Set0' and the set containing only the members of
% `Xs'.
:- pred set__remove_list(set(T), list(T), set(T)).
:- mode set__remove_list(in, in, out) is det.
:- pred set__remove_least(set(T), T, set(T)).
:- mode set__remove_least(in, out, out) is semidet.
% `set_union(SetA, SetB, Set)' is true iff `Set' is the union of
% `SetA' and `SetB'. If the sets are known to be of different
% sizes, then for efficiency make `SetA' the larger of the two.
:- pred set__union(set(T), set(T), set(T)).
:- mode set__union(in, in, out) is det.
% `set__power_union(A, B)' is true iff `B' is the union of
% all the sets in `A'
:- pred set__power_union(set(set(T)), set(T)).
:- mode set__power_union(in, out) is det.
% `set_intersect(SetA, SetB, Set)' is true iff `Set' is the
% intersection of `SetA' and `SetB'.
:- pred set__intersect(set(T), set(T), set(T)).
:- mode set__intersect(in, in, out) is det.
% `set__power_union(A, B)' is true iff `B' is the union of
% all the sets in `A'
:- pred set__power_intersect(set(set(T)), set(T)).
:- mode set__power_intersect(in, out) is det.
% `set__difference(SetA, SetB, Set)' is true iff `Set' is the
% set containing all the elements of `SetA' except those that
% occur in `SetB'
:- pred set__difference(set(T), set(T), set(T)).
:- mode set__difference(in, in, out) is det.
%--------------------------------------------------------------------------%
:- implementation.
:- import_module list, std_util.
:- type set(T) == list(T).
set__list_to_set(List, List).
set__sorted_list_to_set(List, List).
set__to_sorted_list(Set, List) :-
list__sort(Set, List).
:- set__insert_list(_, Xs, _) when Xs. % NU-Prolog indexing.
set__insert_list(Set0, List, Set) :-
list__append(List, Set0, Set).
set__insert(S0, E, [E|S0]).
set__init([]).
set__singleton_set([X], X).
set__equal(SetA, SetB) :-
set__subset(SetA, SetB),
set__subset(SetB, SetA).
set__empty([]).
set__subset([], _).
set__subset([E|S0], S1) :-
set__member(E, S1),
set__subset(S0, S1).
set__superset(S0, S1) :-
set__subset(S1, S0).
set__member(E, S) :-
list__member(E, S).
set__is_member(E, S, R) :-
( set__member(E, S) ->
R = yes
;
R = no
).
:- set__delete_list(_, Xs, _) when Xs.
set__delete_list(S, [], S).
set__delete_list(S0, [X | Xs], S) :-
set__delete(S0, X, S1),
set__delete_list(S1, Xs, S).
set__delete(S0, E, S) :-
list__member(E, S0),
set__remove(S0, E, S).
:- set__remove_list(_, Xs, _) when Xs.
set__remove_list(S, [], S).
set__remove_list(S0, [X | Xs], S) :-
set__remove(S0, X, S1),
set__remove_list(S1, Xs, S).
set__remove(Set0, Elem, Set) :-
list__delete_all(Set0, Elem, Set).
set__remove_least(Set0, E, Set) :-
Set0 = [_|_], % fail early on an empty set
set__to_sorted_list(Set0, [E|Set]).
set__union(Set0, Set1, Set) :-
list__append(Set1, Set0, Set).
set__power_union(PS, S) :-
set__to_sorted_list(PS, SL),
set__init(S0),
set__power_union_2(SL, S0, S).
:- pred set__power_union_2(list(set(T)), set(T), set(T)).
:- mode set__power_union_2(in, in, out) is det.
set__power_union_2([], S, S).
set__power_union_2([T|Ts], S0, S) :-
set__union(T, S0, S1),
set__power_union_2(Ts, S1, S).
set__intersect(S0, S1, S) :-
set__intersect_2(S0, S1, [], S).
:- pred set__intersect_2(set(T), set(T), set(T), set(T)).
:- mode set__intersect_2(in, in, in, out) is det.
set__intersect_2([], _, S, S).
set__intersect_2([E|S0], S1, S2, S) :-
(
list__member(E, S1)
->
S3 = [E|S2]
;
S3 = S2
),
set__intersect_2(S0, S1, S3, S).
set__power_intersect([], []).
set__power_intersect([S0|Ss], S) :-
(
Ss = []
->
S = S0
;
set__power_intersect(Ss, S1),
set__intersect(S1, S0, S)
).
%--------------------------------------------------------------------------%
set__difference(A, B, C) :-
set__difference_2(B, A, C).
:- pred set__difference_2(set(T), set(T), set(T)).
:- mode set__difference_2(in, in, out) is det.
set__difference_2([], C, C).
set__difference_2([E|Es], A, C) :-
set__remove(A, E, B),
set__difference_2(Es, B, C).
%--------------------------------------------------------------------------%