Page 1 of 1

Einstein's Riddle

Posted: 18 Mar 2021 9:15
by Reinhold Becker

I have the following problem:

How can I program "Einstein's Riddle" in Visual Prolog?

Have you any suggestion?
Must I use main pro?

Code: Select all

%%  houses(-Solution) %   @param  Solution is a list of houses that satisfy all constraints. %   @author Folklore attributes this puzzle to Einstein %   @see     /* Houses logical puzzle: who owns the zebra and who drinks water?            1) Five colored houses in a row, each with an owner, a pet, cigarettes, and a drink.          2) The English lives in the red house.          3) The Spanish has a dog.          4) They drink coffee in the green house.          5) The Ukrainian drinks tea.          6) The green house is next to the white house.          7) The Winston smoker has a serpent.          8) In the yellow house they smoke Kool.          9) In the middle house they drink milk.         10) The Norwegian lives in the first house from the left.         11) The Chesterfield smoker lives near the man with the fox.         12) In the house near the house with the horse they smoke Kool.         13) The Lucky Strike smoker drinks juice.         14) The Japanese smokes Kent.         15) The Norwegian lives near the blue house.   Who owns the zebra and who drinks water? */   % Render the houses term as a nice table. :- use_rendering(table,                  [header(h('Owner', 'Pet', 'Cigarette', 'Drink', 'Color'))]).   zebra_owner(Owner) :-         houses(Hs),         member(h(Owner,zebra,_,_,_), Hs).   water_drinker(Drinker) :-         houses(Hs),         member(h(Drinker,_,_,water,_), Hs).     houses(Hs) :-         % each house in the list Hs of houses is represented as:         %      h(Nationality, Pet, Cigarette, Drink, Color)         length(Hs, 5),                                            %  1         member(h(english,_,_,_,red), Hs),                         %  2         member(h(spanish,dog,_,_,_), Hs),                         %  3         member(h(_,_,_,coffee,green), Hs),                        %  4         member(h(ukrainian,_,_,tea,_), Hs),                       %  5         next(h(_,_,_,_,green), h(_,_,_,_,white), Hs),             %  6         member(h(_,snake,winston,_,_), Hs),                       %  7         member(h(_,_,kool,_,yellow), Hs),                         %  8         Hs = [_,_,h(_,_,_,milk,_),_,_],                           %  9         Hs = [h(norwegian,_,_,_,_)|_],                            % 10         next(h(_,fox,_,_,_), h(_,_,chesterfield,_,_), Hs),        % 11         next(h(_,_,kool,_,_), h(_,horse,_,_,_), Hs),              % 12         member(h(_,_,lucky,juice,_), Hs),                         % 13         member(h(japanese,_,kent,_,_), Hs),                       % 14         next(h(norwegian,_,_,_,_), h(_,_,_,_,blue), Hs),          % 15         member(h(_,_,_,water,_), Hs),           % one of them drinks water         member(h(_,zebra,_,_,_), Hs).           % one of them owns a zebra   next(A, B, Ls) :- append(_, [A,B|_], Ls). next(A, B, Ls) :- append(_, [B,A|_], Ls).   /** <examples>   ?- zebra_owner(Owner).   ?- water_drinker(Drinker).   ?- houses(Houses).   */
This is the code from the Internet.
How must I use this code in visual prolog???

Many thanks for your help.

Best wishes
Reinhold Becker

Re: Einstein's Riddle

Posted: 18 Mar 2021 18:13
by Thomas Linder Puls
The brief answer is: You cannot use this code in Visual Prolog.

(You can however (I guess/believe) run it in our PIE program (Prolog Interpreter Engine), which is an example program comes with Visual Prolog that implements a classical Prolog system much closer to ISO Prolog).

I don't know how much of the more complex answer that makes sense to you, but here it is:

The code is ISO Prolog and can be executed in SWI Prolog, SICStus Prolog and the like, but Visual Prolog does not support the ISO Prolog standard.

There are some syntactical issues, but they can easily be easily solved.

The real problem with this code is that it relies on data structures containing free variables.

Somewhere in the execution of the code the list in Hs could look for example like this:

Code: Select all

[_1, h(english, _2, _3, _4, red), _5, _6, _7, _8]
Where the _i are free variables.

Such free variables can be used in "miraculous" solutions to problems like the "Zebra problem" shown here.

Many, many years ago (in Vip5) we also had such free variables in Visual Prolog and the "Zebra problem" was an example back then (a different solution, but same fundamental principle).

But no matter how powerful and astonishing the use of free variables is, we had discovered that it had some very severe downsides, like:
  • That kind of programming is extremely difficult to scale up to real world problems
  • Often the expected miracle doesn't happen. Instead of producing the nice result the program either goes into an endless loop, is extremely slow or produce nonsense
  • Suddenly a free variable occurs in a data structure that should be written into an SQL database. That does not make sense, but where did that free variable come from? Or rather where did the real value that should have been there not come from?
  • While the solution above looks like a "pure logical declarative formulation" and can be considered as such. You will soon experience that "pure logical declarative formulations" will only work, when you have found one that does work among all those (many more) that doesn't work.
  • At a glance it looks like the free variables automatically solves a lot of complex things, but in reality you will have to consider exactly how the they should contribute to the solution. And you will end up spending much time and code on dealing with the free variables themselves
  • Coming back to old code (for maintenance) you may have forgotten (or maybe the code was written by someone else) what role the free variables play, and you may easily make mistakes from false assumptions about their role. After maintenance the role of the variables may be more unclear and eventually completely inconsistent.
  • (I think there is some overlap/redundancy above so I will just stop now :-)).
At first this meant that we stopped using free variables and later that we completely removed it from the language.

Many people think/thought that we completely ruined the language, but we have not regretted it. But the Zebra problem (and a number of related "school examples") can no longer be solves in such a simple and astonishing way.

Re: Einstein's Riddle

Posted: 19 Mar 2021 1:30
by Martin Meyer
An add-on remark from me: ISO Prolog style variables formerly had the type of "reference domains" in Visual Prolog. Thomas explains a way in which these variables can be emulated in current Visual Prolog in the Tutorial How To Remove Reference Domains from a Project. By the method explained there you can write an Einstein's Riddle solver in Visual Prolog - it only takes a bit more code than the one you have posted.

Looking at the code you present I suppose even though it may find the correct solution in some Prolog, it is not sufficient to prove that the solution(s) it finds do solve the riddle. Because it does not ensure that two of the riddle's constraints are satisfied:

1st) In the solution all variables in the list of the five houses must be bound. A solution in which for example one Nationality variable of a house remains free is not allowed.

2nd) In the solution no two variables in the list of the houses must be bound to the same value. For example a solution in which the Nationality variables of two houses are both bound to the value norwegian is not valid.

Re: Einstein's Riddle

Posted: 19 Mar 2021 6:14
by Reinhold Becker

I am very thankful for your answers.

Best wisches
Reinhold Becker