prologzebra-puzzle

How is the day of the week unicorn?


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).

Solution

  • 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 ;