0

Task: The Unicorn is known to lie on Mondays, Tuesdays, and Wednesdays and tells the truth on all other days of the week. He can say: “Yesterday I lied. After tomorrow, I will lie for two days in a row. ” Determine the day of the conversation.

I sketched the code, but I don’t know how to say that the unicorn lied for two days in a row, correct the code, thanks in advance.

yesterday(mon, sun).
yesterday(tue, mon).
yesterday(wed, tue).
yesterday(thu, wed).
yesterday(fri, thu).
yesterday(sat, fri).
yesterday(sun, sat).

lies([mon, tue, wed]).

tomorrow(Day, Tomorrow) :-
    yesterday(Tomorrow, Day).

unicornLies1(Day) :- 
    lies(Days),
    member(Day, Days).

unicornLies2(Day) :- 
    tomorrow(Day, Tomorrow),
    unicornLies1(Day),
    unicornLies1(Tomorrow).

sol:- unicornLies1(Day), unicornLies2(Day), write(Day).
false
  • 10,264
  • 13
  • 101
  • 209
GOOse
  • 13
  • 2
  • This **is** a simple instance of a [tag:zebra-puzzle], so no reason to remove that tag. – false Nov 10 '19 at 16:04

2 Answers2

0

Following day issue

Write out a follows predicate instead of yesterday for clarity. You can pick out 'tomorrow' with follows(Today, Tomorrow), the day after with follows(Tomorrow, Overmorrow) and the day three days from today with follows(Overmorrow, ThreeDays). Yesterday can come from follows(Yesterday, Today). Enforce your membership rules on Yesterday, Overmorrow and ThreeDays.

Lying unicorn issue

You have a semantic mistake. If the Unicorn is telling the truth (go through the possibilities!), there is no answer. Therefore you are really looking for a day where he lies and it is true that 'yesterday, I didn't lie. After tomorrow, I will not lie for two days in a row'. In other words, monday.

You will need to write a predicate that says that either Today is a not lying day and the predicate says(Animal, Today) is true, or Today is a lying day and says(Animal, Today) is false.

I'll leave the approach to you.

Gamma032
  • 441
  • 4
  • 7
  • I changed the code, but did not understand about the following (Overmorrow, ThreeDays) (look at the code above). – GOOse Nov 10 '19 at 15:43
  • @GOOse You need to bind two variables to a terms that represeent the two days after tomorrow, then ensure that these variables are bounded to days where the Unicorn lies. – Gamma032 Nov 12 '19 at 03:34
0

Here's a simple logic that implements next_day and is used conversely to get the day before and after


day(X) :- member(X,[m,t,w,thu,f,sat,sun]).

lie(m).
lie(t).
lie(w).

truth(X) :- \+lie(X).

next(A, B, Ls) :- append(_, [A,B|_], Ls).

next_day(sun,m).
next_day(X,Y) :- next(X,Y,[m,t,w,thu,f,sat,sun]).

solve(X) :-
    day(X),
    (truth(X),next_day(Y,X),lie(Y),next_day(X,T),next_day(T,U),next_day(U,V),lie(U),lie(V));
    (lie(X),next_day(Y,X),truth(Y),next_day(X,T),next_day(T,U),next_day(U,V),(truth(U);truth(V))).

On running it gives a single result - Monday

?- solve(X).
X = m ;
sudhackar
  • 264
  • 2
  • 13