1

I am new to prolog and I am trying to solve this puzzle problem. I did a couple tutorials on youtube on the basics of prolog, but I need some help solving the puzzle below.

Two weeks ago, four enthusiasts made sightings of objects in the sky in their neighborhood. Each of the four reported his or her sightings on a different day. The FBI came and was able to give each person a different explanation of what he or she had "really" seen. Can you determine the day ( Tuesday through Friday ) each person sighted the object, as well as the object that it turned out to be?

  1. Mr. K made his sighting at some point earlier in the week than the one who saw the balloon, but at some point later in the week, than the one who spotted the Kite ( who isn't Ms. G ).
  2. Friday's sighting was made by either Ms. Barn or the one who saw a plane ( or both ).
  3. Mr. Nik did not make his sighting on Tuesday.
  4. Mr. K isn't the one whose object turned out to be a telephone pole.

I have my set my rules up correctly, but I can't seem to get the logic down pack. I am looking for guidance not direct answers. On the far right, I have listed the number to each question i am attempting to answer

        enthu(mr_k).
        enthu(ms_barn).
        enthu(ms_g).
        enthu(mr_nik).

        object(ballon).
        object(kite).
        object(plane).
        object(tele_pole).

        day(tuesday).
        day(wednesday).
        day(thursday).
        day(friday).



        sight(X,ballon).

        sighting(mr_k):-   1
        day(X),
        sight(X,Y),
        didntc_kite(ms_g).

        friday_sight:- enthu(ms_barn);    2
        saw(X,plane);
        both(ms_barn,X).


        nosight_tuesday(mr_nik,X).          3

        no_telepole(mr_k,Y).          4
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Micheal C.
  • 101
  • 3
  • 11
  • Is there a reason for this `mr_klien` and not `mr_k` that you fist declared ? – Searching Nov 14 '16 at 23:50
  • Aha, that's what i get for copying and pasting incorrectly. It has been updated. – Micheal C. Nov 14 '16 at 23:58
  • 1
    What is a "logic down pack"? – Enigmativity Nov 15 '16 at 00:08
  • Oh, do you mean "down pat"? – Enigmativity Nov 15 '16 at 00:17
  • Pointer 1: See if you can rewrite your rules with `sighting` as the the action/object of interest.. e.g instead of saying `nosight_tuesday(mr_nik,X).`. build the rule that made sighting `true` ike `sighting(mr_nik) :- ...` `sighting(mr_k) :- ...` so on – Searching Nov 15 '16 at 00:27
  • See for example [here](http://swish.swi-prolog.org/example/houses_puzzle.pl). The "Examples" menu at the top has many more small programs to get you started. –  Nov 15 '16 at 08:48
  • 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:20

1 Answers1

0

I know you didn't ask for a solution, but I find it hard to describe what to do without a working solution. I apologise for that.

Here's what I would do:

/*
1. Mr. K made his sighting at some point earlier in the week than the one who saw the balloon, but at some point later in the week, than the one who spotted the Kite ( who isn't Ms. G ).
2. Friday's sighting was made by either Ms. Barn or the one who saw a plane ( or both ).
3. Mr. Nik did not make his sighting on Tuesday.
4. Mr. K isn't the one whose object turned out to be a telephone pole.
*/

?-
% Set up a list of lists to be the final solution
        Days = [[tuesday,_,_],[wednesday,_,_],[thursday,_,_],[friday,_,_]],
/* 1 */ before([_,mr_k,_],[_,_,balloon],Days),
/* 1 */ before([_,_,kite],[_,mr_k,_],Days),
/* 2 */ (member([friday,ms_barn,_],Days);
            member([friday,_,plane],Days);
            member([friday,ms_barn,plane],Days)),
% Fill in the rest of the people
        members([[_,mr_k,_],[_,ms_barn,_],[_,ms_g,_],[_,mr_nik,_]],Days),
% Fill in the rest of the objects
        members([[_,_,balloon],[_,_,kite],[_,_,plane],[_,_,tele_pole]],Days),
% Negations should be done after the solution is populated
/* 1 */ member([_,NOT_ms_g,kite],Days), NOT_ms_g \= ms_g,
/* 3 */ member([tuesday,NOT_mr_nik,_],Days), NOT_mr_nik \= mr_nik,
/* 4 */ member([_,NOT_mr_k,tele_pole],Days), NOT_mr_k \= mr_k,
    write(Days),
    nl,
    fail.

% Checks that `X` comes before `Y`
% in the list `Ds`
before(X,Y,Ds) :-
    remainder(X,Ds,Rs),
    member(Y,Rs).

% Finds a member of a list and
% unifies the third parameter such
% that it is the remaining elements in
% the list after the found member
remainder(X,[X|Ds],Ds).
remainder(X,[_|Ds],Rs) :- remainder(X,Ds,Rs).

% An extended version of `member` that
% checks if the members of the first list
% are all members of the second
members([],_).
members([X|Xs],Ds) :-
    member(X,Ds),
    members(Xs,Ds).

That gives me:

[[tuesday, ms_g, tele_pole],
    [wednesday, mr_nik, kite],
    [thursday, mr_k, plane],
    [friday, ms_barn, balloon]]
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • I greatly appreciate your answer. But this seems very complex. Can you simplify it/ explain to me what's really going on. – Micheal C. Nov 15 '16 at 03:04
  • @MichealC. - I sure can, but it might be in a few hours. – Enigmativity Nov 15 '16 at 03:10
  • Okay that's not a problem. But when you get a chance I see you're using arrays, wayyyy out of my league at this point. Simplicity please. – Micheal C. Nov 15 '16 at 03:17
  • @MichealC. There are no arrays in this answer. This is a classical way of solving this classic example of puzzles in Prolog. There is a ton of similar puzzles and solutions all over the internet and here on stackoverflow. –  Nov 15 '16 at 08:36
  • @MichealC. You are asking for a free personal mentoring session from Enigmativity. This is all good, but I don't know if Stackoverflow is the forum for this. –  Nov 15 '16 at 08:43
  • @Boris - There's no problem with what the OP has asked for. I should have provided some sort of explanation along with this answer anyway. – Enigmativity Nov 15 '16 at 09:23
  • 1
    As I said, it's all fine, but something in the attitude irked me. OP's question is anyway a textbook example of a bad attempt at asking a question _in a forum like Stackoverflow_. –  Nov 15 '16 at 09:34
  • what atttitude? Are you okay? I cant ask questions? Thanks again @Enigmativity. – Micheal C. Nov 15 '16 at 17:48
  • @Enigmativity so back to our conversation.... I get an error *Full stop in clause-body? Cannot redefine ,/2* Any suggestions? – Micheal C. Nov 15 '16 at 18:08
  • @MichealC. - The code above runs verbatim in Strawberry Prolog. I might imagine that there syntax differences between prolog systems, but not that would redefine `,/2`. Can you check that you copy and pasted correctly? – Enigmativity Nov 15 '16 at 22:38
  • i did copy and past correctly. I am using swi-prolog. – Micheal C. Nov 15 '16 at 22:56
  • @MichealC. - I ran it in SWI perfectly fine once I move the `?-` query to the bottom of the source. – Enigmativity Nov 16 '16 at 00:29
  • @MichealC. - I got it running. – Enigmativity Nov 16 '16 at 05:51
  • @Enigmativity Thank you very much my good sir. I really appreciate it. – Micheal C. Nov 16 '16 at 16:07
  • @Enigmativity you never really explained how you solved the puzzle. We got side tracked. Can you please explain whats going on? – Micheal C. Dec 20 '16 at 21:19
  • @MichealC. - I've added an explanation. – Enigmativity Dec 20 '16 at 23:12