% true when Y follows X in a list consecutive(X, Y, [X, Y|_]). consecutive(X, Y, [_|T]):- consecutive(X, Y, T). days([mo, tu, we, th, fr, sa, su]). tomorrow(X, Y) :- days(L), consecutive(X, Y, L). % true when X and Y are at the same position in corresponding lists lookup(X, Y, [X|_], [Y|_]). lookup(X, Y, [_|T1], [_|T2]) :- lookup(X, Y, T1, T2). % distance to Sunday (which is not on the day's week) distances([1, 2, 3, 4, 5, 6, 7]). dist_to_sunday(X, D) :- days(L1), distances(L2), lookup(X, D, L1, L2). % "the day after tomorrow": day_after_tomorrow(X, Y):- tomorrow(X, Z), tomorrow(Z, Y). % "yesterday": yesterday(X, Y):- tomorrow(Y, X). % "the day before yesterday": day_before_yesterday(X, Y):- day_after_tomorrow(Y, X). % the problem statement conversation(Today) :- % "the day after tomorrow becomes "yesterday": day_after_tomorrow(Today, X0), yesterday(X, X0), % same distance to Sunday (not the current week's one) dist_to_sunday(X, D), dist_to_sunday(Y, D), % when the day before yesterday still was still "tomorrow" day_before_yesterday(Today, Y0), tomorrow(Y, Y0).