1
votes

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
1
Is there a reason for this mr_klien and not mr_k that you fist declared ?Searching
Aha, that's what i get for copying and pasting incorrectly. It has been updated.Micheal C.
What is a "logic down pack"?Enigmativity
Oh, do you mean "down pat"?Enigmativity
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 onSearching

1 Answers

0
votes

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]]