ken@aiai.ed.ac.uk (Ken Johnson) (10/04/89)
/* * Here is my solution to this problem, which I first came across in * Peter Ross's book `Advanced Prolog' (published in the UK by * Addison Wesley, 1989). I am not claiming this to be a better * version, just different. * * Copyright notice: This program handbuilt from lovingly hand-crafted * predicates in my traditional oak-beamed Scottish workplace. You may * make and distribute copies, recite the code out loud in public houses * and in village streets, store it in a retrieval system etc., BUT if you * sell copies at a profit, I want a share. * * To run the program type `test.' and it should just go by itself. */ test :- has_job(Jra,Jrb,Jta,Jtb,Jsa,Jsb,Jpa,Jpb), describe(roberta,Jra,Jrb), describe(thelma,Jta,Jtb), describe(steve,Jsa,Jsb), describe(pete,Jpa,Jpb), nl, fail. test :- write('No [more] solutions'), nl. describe(Name,Job1,Job2) :- write(Name), write(' is the '), write(Job1), write(' and the '), write(Job2), write('.'), nl. % -------------------- % This is where the story really starts. Roberts has the jobs Jra Jrb, % Thelma has Jta and Jtb, Steve has Jsa and Jsb and Pete has Jpa and % Jpb. % In the generate-and-test loop here I am applying all tests as early % as possible. I think the operator @> may also be less than 100% well % known: it means `collates alphabetically after'. has_job(Jra,Jrb,Jta,Jtb,Jsa,Jsb,Jpa,Jpb) :- % Roberta's jobs right_sex_for(Jra,female), right_sex_for(Jrb,female), Jra @> Jrb, % Roberta is not a boxer. % Roberta, the chef and the police officer went golfing % together. Therefore Roberta is not the chef and nor is % she the police officer different([Jra,Jrb,chef,police_officer,boxer]), distinguish(Jra,Jrb), % Thelma's jobs right_sex_for(Jta,female), right_sex_for(Jtb,female), Jta @> Jtb, distinguish(Jta,Jtb), different([Jra,Jrb,Jta,Jtb]), % Steve's jobs right_sex_for(Jsa,male), right_sex_for(Jsb,male), Jsa @> Jsb, distinguish(Jsa,Jsb), different([Jra,Jrb,Jta,Jtb,Jsa,Jsb]), % Pete's jobs right_sex_for(Jpa,male), right_sex_for(Jpb,male), Jpa @> Jpb, % Pete has no education beyond 9th grade. I suppose this % means he can't be a teacher, nurse or policeman different([Jpa,Jpb,teacher,nurse,police_officer]), distinguish(Jpa,Jpb), % All the jobs are different different([Jra,Jrb,Jta,Jtb,Jsa,Jsb,Jpa,Jpb]). right_sex_for(chef,female). right_sex_for(guard,_). right_sex_for(nurse,male). right_sex_for(telephonist,male). right_sex_for(police_officer,_). right_sex_for(teacher,_). right_sex_for(actor,male). right_sex_for(boxer,_). % I think this has to be either sex, or % you get no solutions % The ad hoc hack distinguish(chef,police_officer) :- !, fail. distinguish(police_officer,chef) :- !, fail. distinguish(_,_). % Utility: Is everything in the list different? (Never called with empty % list as argument so that case is not covered) different([_]) :- !. different([H|T]) :- member(H,T), !, fail. different([_|T]) :- different(T). % ------------ member(X,[X|_]). member(X,[_|T]) :- member(X,T). -- Ken Johnson, AI Applications Institute, 80 South Bridge, Edinburgh EH1 1HN E-mail ken@aiai.ed.ac.uk, phone 031-225 4464 extension 212 `I have read your article, Mr Johnson, and I am no wiser now than when I started'. -- `Possibly not, sir, but far better informed.'