% Naive Prolog solution of job assignment problem

% X is an assignment that satisfies all the constraints

assignment(X) :-
   X = [Sch,Rep,Prog1,Prog2,Pla,Doc,Fin,Cha,Pur,Har,Rec,Mai,Tra,Saf,Trai,Can],
   capable(scheduling,Sch),
   capable(reporting,Rep),
   capable(programming1,Prog1),
   capable(programming2,Prog2),
   capable(planning,Pla),
   capable(documentation,Doc),
   capable(financial,Fin),
   capable(chairperson,Cha),
   capable(purchasing,Pur),
   capable(hardware,Har),
   capable(recruitment,Rec),
   capable(maintenance,Mai),
   capable(transport,Tra),
   capable(safety,Saf),
   capable(training,Trai),
   capable(canteen,Can),
   all_in([austin,becker,cromwell,davies,nicholls,olsen,parker,queen],X),
   eq_loads(X,_).

% eq_loads(Assignment,L)
%
% Succeeds if every element of Assignment occurs the same number
% (L) of times

eq_loads([],_).
eq_loads([X|Rest],Load) :-
   extract(X,Rest,Xs,Others),
   length([X|Xs],Load),
   eq_loads(Others,Load).

% extract(El,List,Yes,No)
%
% Succeeds if the elements of Yes and No are the elements of List,
% with Yes being those equal to El and No being the others

extract(_,[],[],[]).
extract(X,[X|Rest],[X|Xs],Others) :- extract(X,Rest,Xs,Others).
extract(X,[Y|Rest],Xs,[Y|Others]) :- \+ X=Y, extract(X,Rest,Xs,Others).

% all_in(L1,L2)
%
% Succeeds if every element of L1 is in L2

all_in([],_).
all_in([X|Rest],List) :-
   member(X,List), !,
   all_in(Rest,List).

   member(X,[X|_]).
   member(X,[_|L]) :- member(X,L).

   % capable(Job,Person)

   capable(canteen,parker).
   capable(canteen,queen).
   capable(chairperson,olsen).
   capable(chairperson,parker).
   capable(chairperson,queen).
   capable(documentation,becker).
   capable(documentation,cromwell).
   capable(documentation,davies).
   capable(financial,nicholls).
   capable(financial,parker).
   capable(hardware,austin).
   capable(hardware,becker).
   capable(hardware,davies).
   capable(maintenance,austin).
   capable(planning,nicholls).
   capable(planning,parker).
   capable(planning,queen).
   capable(programming1,austin).
   capable(programming1,becker).
   capable(programming1,davies).
   capable(programming2,austin).
   capable(programming2,becker).
   capable(programming2,davies).
   capable(purchasing,austin).
   capable(purchasing,cromwell).
   capable(purchasing,davies).
   capable(recruitment,olsen).
   capable(recruitment,queen).
   capable(reporting,olsen).
   capable(reporting,parker).
   capable(reporting,queen).
   capable(safety,austin).
   capable(safety,cromwell).
   capable(safety,davies).
   capable(scheduling,olsen).
   capable(scheduling,queen).
   capable(training,queen).
   capable(transport,austin).
   capable(transport,cromwell).
   capable(transport,davies).
