0

I'm trying to solve the Einstein Riddle using Prolog. I'm sorry for my English. The task is:

  • In the block of flats is 5 flats. (ground floor a 1., 2., 3., 4. floor)
  • Family Mullerovi have 4 children.
  • An administrator lives on the middle floor.
  • Mrs. Meierova pays for her flat 60 crowns less than a doctor on 3. floor.
  • Family living on the hightest floor have 5 children.
  • Family Kernovi have 1 child than teacher.
  • Mr Kaufmann works as a sales representative.
  • The teacher pays for her flat 1740 crowns.
  • On the hightest floor janitor lives.
  • The doctor pays for his flat 1800 crowns.
  • In the flat, which costs 1760 crowns, arent any children.
  • On the 2.floor the family have twice more children than family on the 3.floor.
  • Mr Hanz lives directly above family Kernovi.
  • In the flat under the janitor live 2 children.
  • Mullerovi pay for their flat 1770 crowns.
  • The roof flat is cheaper 10 crowns than then ground floor.
  • Sales representative pays 30 crowns more than janitor does.

My code looks like, I don't know how to solve problems with hire:

person('Name', 'Job','Children','Hire','Floor').

houses(Hs):-
   length(Hs),
   member(person(mullerovi,_,4,1770,_),Hs),
   member(person(_,administrator,_,_,2),Hs),
   member(person(_,doctor,_,1800,_),Hs),
   pays_less(person(_,doctor,_,Hire,_),person('Meinova',_,_,Hire-60,_),Hs),
   member(person(_,_,5,_,4),Hs),
   have_one_children_less(person('Kernovi',_,Children-1,_,_),person(_,teacher,Children,_,_),Hs),
   member(person('Kaufmann','Sales representative',_,_,_),Hs),
   member(person(_,teacher,_,1740,_),Hs),
   member(person(_,janitor,_,_,4),Hs),
   member(person(_,_,0,1760,_),Hs),
   have_2x_children(
         person(_,_,2*Children,_,2),
         person(_,_,Children,_,3),Hs),
   lives_above(person('Hanz',_,_,_,_),person('Kernovi',_,_,_,_),Hs),
   lives_above(person(_,janitor,_,_,_),person(_,_,2,_,_),Hs),
   pays_more(
         person(_,_,_,Hire+10,4),
         person(_,_,_,Hire,'Ground floor'),Hs),
   pays_more(
         person(_,'Sale representative',_,Hire+30,_),
         person(_,janitor,_,Hire,_),Hs).

Thanks for any advices.

Machavity
  • 30,841
  • 27
  • 92
  • 100
user3637775
  • 499
  • 4
  • 20
  • 3
    You're making the assumption that prolog will arithmetically evaluate `Hire+10`. It doesn't. It's trying to unify against a term in the form of `X+Y`. Prolog does structural evaluation, not arithmetic. – Enigmativity Apr 24 '16 at 07:44
  • Do you mean to create a new rule? I'm new to Prolog. – user3637775 Apr 24 '16 at 10:01
  • `length(Hs),` makes no sense. You really need to put more effort into it first. – false Apr 24 '16 at 10:30
  • Possible duplicate of [Einstein Riddle using Prolog](http://stackoverflow.com/questions/36816529/einstein-riddle-using-prolog) – lurker Apr 24 '16 at 10:59
  • @lurker - It's close to being a duplicate, but there is a little more complexity here that isn't covered in the other question. – Enigmativity Apr 24 '16 at 11:39
  • @WillNess why delete it? – false Jul 10 '16 at 13:09
  • 1
    @WillNess so you are starting your own CLP-implementation :-) – false Jul 10 '16 at 14:01
  • Possible duplicate of [Einstein Riddle with List of terms](http://stackoverflow.com/questions/36743498/einstein-riddle-with-list-of-terms) –  Dec 20 '16 at 23:19

1 Answers1

0

"In the block of flats is 5 flats" translates as length(Hs,5).

Then, pays_less( person(_,doctor,_,Hire,_), person('Meinova',_,_,Hire-60,_),Hs) is undefined; it ought to be

.....
member( person(_,doctor,_,Hire,_), Hs), 
member( person('Meinova',_,_,Hire2,_), Hs), 
.....
Hire2 is Hire-60,  
.....

or something like that.

Acquaint yourself with is/2 operator and its preconditions. B=80, A = B-60 succeeds, unifying A with -(80,60). You want B=80, A is B-60 which succeeds and unifies A with 20 (but would fail if B were not yet a numerical expression).

The line Hire2 is Hire-60, should be placed as high as possible in the predicate, for maximal efficiency.

Will Ness
  • 70,110
  • 9
  • 98
  • 181