% Problem posted by Ken
% Logic Problems Issue 16 page 46
% Program written by Neng-Fa Zhou, 2002
% Run on B-Prolog 6.x (www.probp.com)
%
%On one page of the visitor's book at Sandholme Castle, seat of the Duke of
%Wallingfen, were the names of ten couples from various locations in the
%English-speaking world who had paid to look round the ancestral pile.
%From the clues given below, can you fill in the blank page of the book with
%the surnames and home-towns of each couple?
%
%Clues:
%1. The Drummonds are from Edinburgh; their name appears on the line above the
%   Jones family, who were not the last couple to sign the page. 
%2. Mr and Mrs Ince's signatures are immediately followed by those of the London couple.
%3. The couple on line 3 gave a North American address; their surname contains
%   two more letters than that of the Portsmouth pair and three more than that
%   of the couple on line 9.
%4. Only one couple's surname initial immediately preceeds that of the next
%  family to sign; they are not the Childers family, whose name appears on line 5
%   and who do not live in Melbourne.
%5. Bristol is the address on the line above Durban; one of these cities is the
%   home of the Adams family.
%6. The Los Angeles couple signed on line 8; their surname contains an even
%   number of letters.
%7. Mr and Mrs Fellowes, who are not transatlantic visitors, wrote their name on
%   an odd-numbered line, unlike the couple from Wellington.
%8. The Toronto family's name immediately follows that of the Harringtons, who
%   are not from Washington.
%9. Mr and Mrs Bourne signed on the lower half of the page, whilst the Giles
%   family, who did not sign on line 6, are not resident in the U.K.
%
%London, Edinburgh, Bristol and Portsmouth are all in the U.K. Durban is in
%South Africa. Los Angeles and Washington (D.C.) are in the U.S.A. Toronto is in
%Canada. Wellington is in NewZealand. And of course, Melbourne is in Australia.
/* 
This is the solution to check your answer with.
 
L = [[1, drummond, edinburgh], [2, jones, portsmouth], [3, edwards, washington], [4, giles, wellington], [5, childers, bristol], [6, adams, durban], [7, fellowes, melbourne], [8, harrington, los_angeles], [9, ince, toronto], [10, bourne, london]]
*/
 
go:-
    Persons=[person("adams",Cadams,Ladams),
	     person("ince",Cince,Lince),
	     person("childers",Cchilders,Lchilders),
	     person("bourne",Cbourne,Lbourne),
	     person("drummond",Cdrummond,Ldrummond),
	     person("edwards",Cedwards,Ledwards),	     
	     person("fellowes",Cfellowes,Lfellowes),
	     person("giles",Cgiles,Lgiles),
	     person("harrington",Charrington,Lharrington),
	     person("jones",Cjones,Ljones)],
    Lines=[Ladams,Lince,Lchilders,Lbourne,Ldrummond,Ledwards,Lfellowes,Lgiles,Lharrington,Ljones],
    Lines :: 1..10,
    alldifferent(Lines),
    Cities=[Cadams,Cince,Cchilders,Cbourne,Cdrummond,Cedwards,Cfellowes,Cgiles,Charrington,Cjones],
    Cities :: [london,edinburgh,bristol,portsmouth,durban,la,washington,toronto,wellington,melbourne],
    alldifferent(Cities),
    
    %clue 1
    Cdrummond=edinburgh,
    Ldrummond #< Ljones,
    Ljones #\= 10,

    %clue 2
    Llondon #= Lince+1,

    %clue 3
    C3 :: [la,washington,toronto],
    N3Len #= NportsmouthLen+2,
    N3Len #= N9Len+3,

    %clue 4
    Lchilders = 5,
    Cchilders #\= melbourne,

    %clue 5
    Lbristol #= Ldurban-1,
    Cadams :: [durban,bristol],

    %clue 6
    Lla = 8,
    NlaLen #= 2*_,

    %clue 7
    Lfellowes  #= 2*_+1,
    Cfellowes notin [la,washington,toronto,edinburgh,bristol,portsmouth],
    Lwellington #= 2*_,

    %clue 8
    Ltoronto #= Lharrington+1,
    Charrington #\= washington,

    %clue 9
    Lbourne #> 5,
    Lgiles #\= 6,
    Cgiles notin [edinburgh,bristol,portsmouth],

    labeling(Lines), % find a permutation
    %check other clues
    member(person(_,london,Llondon),Persons),
    member(person(N3,C3,3),Persons),
    length(N3,N3Len),    
    member(person(Nportsmouth,portsmouth,Lportsmouth),Persons),
    length(Nportsmouth,NportsmouthLen),
    member(person(N9,_,9),Persons),
    length(N9,N9Len),
    % clue 4
    findall(preceed(P1,P2),preceed(P1,P2,Persons),Preceeds),
    length(Preceeds,NumPreceeds),NumPreceeds =:=1,
    %
    member(person(Ndurban,durban,Ldurban),Persons),
    member(person(Nbristol,bristol,Lbristol),Persons),
    member(person(Nla,la,Lla),Persons),
    length(Nla,NlaLen),
    member(person(Nwellington,wellington,Lwellington),Persons),
    member(person(Ntoronto,toronto,Ltoronto),Persons),
    write_persons(Persons,1),nl.

write_persons(Persons,N):-
    member(person(Name,City,N),Persons),!,
    write(N),write(':'),write_string(Name),write(':'),write(City),nl,
    N1 is N+1,
    write_persons(Persons,N1).
write_persons(Persons,N).

preceed(P1,P2,Persons):-
    member(person(P1,_,L1),Persons),
    P1 \= "childers",
    L2 is L1+1,
    member(person(P2,_,L2),Persons),
    P2 \= "childers",
    P1=[C1|_],
    P2=[C2|_],
    C1 =:= C2-1.
    
