[net.lang.prolog] miscellany re income tax planning s

goldfain@uiucdcsb.CS.UIUC.EDU (05/28/86)

Since our network is down to UUCP at the moment, I will put this response
here.  If the problems clear up in a few days, I will mail this to the note
poster.

	--------------------------------------------

Your "aggregate" predicate looks pretty clever to me ... it certainly uses
some of the deeper concepts of prolog (functor-building and calling, etc.)
I can suggest one improvement in elegance, since you mention you wrote a new
aggregate predicate for each number of arguments.  You could rewrite aggregate
to always expect three arguments, the first is the "Goal" as before, the
second "ArgList", and the third "Aggr" to hold the result.  Then you could
use this form for goals with any number of arguments:

aggregate(Goal, ArgList, Aggr) :-
   append([Goal | ArgList], [Amount], Funct),
   Z =.. Funct,
   findall(Amount, call(Z), List),
   listtotal(List, Aggr).

I haven't actually tried this code, but something close to it should work.  I
am using UNSW prolog, here.

	----------------------------------------
As to your other question, here is some code that works for me.
	----------------------------------------

% This is the function you want: group([a, b, c, d], X)? returns X
% instantiated to the list of all subsets of [a, b, c, d] excepting the
% null set, singleton sets, and the set [a, b, c, d] itself.

groups([], []).
groups([H | T], Result) :-
   length([H | T], Full),
   powerset([H | T], Sets),
   filter(Full, Sets, Result).

% This takes a set (written as a list) as its first argument and returns the
% set of all NONEMPTY subsets of it in its second argument.  Example:
% powerset([a, b, c], X)?     gives :
%      X = [[c], [b,c], [b], [a,c], [a,b,c], [a,b], [a]]
% argument.  Warning: it returns with every member of the power set EXCEPT the
% null set.  (It does return the set itself as one of the subsets, unless the
% set itself is the null set.)

powerset([], []).
powerset([H | T], Result) :-
   powerset(T, Set1),
   include(H, Set1, Set2),
   append(Set1, Set2, Result).

% This builds a new "powerset" from a new element and a "sub-powerset".

include(Item, [], [[Item]]).
include(Item, [H | T], [[Item | H] | Rest]) :- include(Item, T, Rest).

% A very-often used predicate, which should be pre-defined.

append([], X, X).
append([H | T], X, [H | Rest]) :- append(T, X, Rest).

% The "powerset" routine returns too much for our purposes, so we filter out
% singleton sets and the whole set.

filter(_, [], []).
filter(Full, [Set | More], Result) :-
   length(Set, 1), !, filter(Full, More, Result).
filter(Full, [Set | More], Result) :-
   length(Set, Full), !, filter(Full, More, Result).
filter(Full, [Okay | More], [Okay | Rest]) :- filter(Full, More, Rest).

	--------------------------------------------