1:- module(pset, [
    2    pset_empty/1,
    3    list_set/2,
    4    set_list/2,
    5    subset_t/3,
    6    punion/3,
    7    pdifference/3,
    8    pintersection/3
    9]).   10
   11:- use_module(purity).   12:- use_module(plist).   13
   14:- multifile(purity:pcompare/4).   15:- multifile(purity:ptype/2).   16
   17purity:ptype(pset([]), pset).
   18purity:ptype(pset([_,_]), pset).
   19
   20purity:pcompare(pset, pset(A), pset(B), C) :-
   21    % compare list contents
   22    pcompare(A, B, C).
   23
   24% p_is_set/1
   25pset_empty(pset([])).
   26
   27% subset_t(SubSet, Set, Truth)
   28subset_t(pset(Sub), pset(Set), T) :-
   29    subset_(Sub, Set, T).
   30
   31subset_([],_,true).
   32subset_([A|Sub],Set,T) :-
   33    subset__(Set, [A|Sub],T).
   34
   35subset__([],_,false).
   36subset__([B|Set],[A|Sub],T) :-
   37    pcompare(A,B,C),
   38    subset_c(C,[A|Sub],[B|Set],T).
   39
   40subset_c(=,[_|Sub],[_|Set],T) :- 
   41    subset_(Sub,Set,T).
   42subset_c(<,_,_,false).
   43subset_c(>,Sub,[_|Set],T) :- 
   44    subset_(Sub,Set,T).
   45
   46% list_set(List, Set).
   47list_set(L, pset(Set)) :-
   48    psort(L,B),
   49    remove_dups_sorted(B,Set).
   50
   51remove_dups_sorted([], []).
   52remove_dups_sorted([A|T],R) :-
   53    remove_dups_sorted_(T,A,R).
   54
   55remove_dups_sorted_([],A,[A]).
   56remove_dups_sorted_([B|T],A,R) :-
   57    pdif_t(A,B,C),
   58    remove_dups_sorted_(C,[A,B|T],R).
   59
   60remove_dups_sorted_(true,[A,B|T],[A|R]) :-
   61    remove_dups_sorted([B|T],R).
   62remove_dups_sorted_(false,[A,A|T],R) :-
   63    remove_dups_sorted([A|T],R).
   64
   65% set_list(Set, List).
   66set_list(pset(List), List).
   67
   68
   69% punion(L1,L2,Union).
   70punion(pset(S1), pset(S2), pset(S3)) :-
   71    punion_(S1,S2,S3).
   72 
   73punion_([],B,B).
   74punion_([A|At],B,R) :-
   75    punion_1(B,[A|At],R).
   76
   77punion_1([],A,A).
   78punion_1([B|Bt],[A|At],R) :-
   79    pcompare(A,B,C),
   80    punion_c(C,[A|At],[B|Bt],R).
   81
   82punion_c(=,[A|At],[A|Bt],[A|R]) :- 
   83    punion_(At,Bt,R).
   84punion_c(<,[A|At],[B|Bt],[A|R]) :- 
   85    punion_(At,[B|Bt],R).
   86punion_c(>,[A|At],[B|Bt],[B|R]) :- 
   87    punion_([A|At],Bt,R).
   88
   89
   90% difference(Set1, Set2, Difference).
   91pdifference(pset(S1),pset(S2),pset(S3)) :-
   92    pdifference_(S1,S2,S3).
   93 
   94pdifference_([],_,[]).
   95pdifference_([A|At],B,R) :-
   96    pdifference_1(B,[A|At],R).
   97
   98pdifference_1([],A,A).
   99pdifference_1([B|Bt],[A|At],R) :-
  100    pcompare(A,B,C),
  101    pdifference_c(C,[A|At],[B|Bt],R).
  102
  103pdifference_c(=,[A|At],[A|Bt],R) :- 
  104    pdifference_(At,Bt,R).
  105pdifference_c(<,[A|At],[B|Bt],[A|R]) :- 
  106    pdifference_(At,[B|Bt],R).
  107pdifference_c(>,[A|At],[_|Bt],[A|R]) :- 
  108    pdifference_([A|At],Bt,R).
  109
  110
  111% pintersection(Set1,Set2,Intersection).
  112pintersection(pset(S1),pset(S2),pset(S3)) :-
  113    pintersection_(S1,S2,S3).
  114 
  115pintersection_([],_,[]).
  116pintersection_([A|At],B,R) :-
  117    pintersection_1(B,[A|At],R).
  118
  119pintersection_1([],_,[]).
  120pintersection_1([B|Bt],[A|At],R) :-
  121    pcompare(A,B,C),
  122    pintersection_c(C,[A|At],[B|Bt],R).
  123
  124pintersection_c(=,[A|At],[A|Bt],[A|R]) :- 
  125    pintersection_(At,Bt,R).
  126pintersection_c(<,[_|At],[B|Bt],R) :- 
  127    pintersection_(At,[B|Bt],R).
  128pintersection_c(>,[A|At],[_|Bt],R) :- 
  129    pintersection_([A|At],Bt,R)