/* Languages at a round table in Picat. From Stack overflow "A prolog program that reflects people sitting at a round table" http://stackoverflow.com/questions/13305356/a-prolog-program-that-reflects-people-sitting-at-a-round-table """ I've got a prolog homework to do: There are 5 persons sitting at a round table of different nationalities (french, english, polish, italian, turkish). Each of them knows only one other language other than their own. They sit at the round table in such a way that each of them can talk with their 2 neighbors (with one neighbor they talk in their native tongue and with the other in the single foreign language they know). The english person knows italian, the polish person knows french, the turkish person doesn't know english. The question is what foreign language does the turkish person know? """ Solution: The French person knows Polish The Polish person knows Turkish The Turkish person knows Italian The Italian person knows English The English person knows French This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> N = 5, Langs = [French, English, Polish, Italian, Turkish], Langs = 1..N, S = ["French", "English", "Polish", "Italian", "Turkish"], % decision variables Native = new_list(N), Native :: 1..N, Foreign = new_list(N), Foreign :: 1..N, % foreign language for the native Turkish TurkForeign :: 1..N, % the native languages are distinct % (and - as it happen - so are the foreign languages) all_different(Native), % They sit at the round table in such a way that each of them can talk with % their 2 neighbors (with one neighbor they talk in their native tongue % and with the other in the single foreign language they know). foreach(I in 1..N) Native[1+(I mod N)] #= Foreign[1+((I-1) mod N)] end, % % The english person knows italian, p(Italian, English,Native,Foreign), % the polish person knows french, p(French, Polish,Native,Foreign), % the turkish person doesn't know english. not_p(English,Turkish,Native,Foreign), % The question is what foreign language does the turkish person know? p(Turkish, TurkForeign,Native,Foreign), % symmetry breaking: the French sits at position 1 Native[French] #= 1, Vars = Native ++ Foreign ++ [TurkForeign], solve(Vars), println(native=Native), println(foreign=Foreign), println(native=[S[I] : I in Native]), println(foreign=[S[I] : I in Foreign]), println(turkForeign=S[TurkForeign]), foreach(I in 1..N) nth(I,Native,J), nth(I,Foreign,F), printf("The %w person knows %w\n", S[J],S[F]) end, nl, fail, nl. go => true. % p(native_language, foreign_language) % i.e. the person with native_language speak foreign_language p(Nat, F,Native,Foreign) => sum([Native[J] #= Nat #/\ Foreign[J] #= F : J in 1..Native.len]) #= 1. not_p(Nat, F,Native,Foreign) => sum([Native[J] #= Nat #/\ Foreign[J] #= F : J in 1..Native.len]) #= 0.