2

I seem to be having an issue with the unification of facts in Prolog, but can't confirm it. Everything looks like it should work, and I've looked up examples of solved logic puzzles using Prolog to no real effect, given the relative rarity of Prolog.

This is an extra credit assignment, so I'm unsure if it's valid, but I'm genuinely stumped on how to proceed from here

% Names
name(teo).
name(mira).
name(bruno).
name(igor).

%Food
food(sandwich).
food(pie).
food(hamburger).
food(pizza).

%Hobby
hobby(crosswords).
hobby(writing).
hobby(reading).
hobby(photography).

%Shirt Colour
shirt(white).
shirt(yellow).
shirt(blue).
shirt(red).

%Other
girl(mira).

student((Name, Food, Hobby, Shirt)) :-
    name(Name), food(Food), hobby(Hobby), shirt(Shirt).

solution(L):-
    length(L,4),
    L= [student(teo, sandwich,_,_),_,_,_],
    member(student(mira, pite, crosswords,_),L),
    member(student(girl(GirlName),_,_,white),L),
    member(student(bruno,_,_,yellow),L),
    member(student(_,hamburger,writing,_),
    L= [_, student(_,pie,_,_),_,_],
    next(student(_,pie,_,_), student(teo,_,_,_), L),
    next(student(bruno,_,_,_), student(_,pizza,_,_), L),
    next(student(_,_,_,white), student(_,pizza,_,_), L),
    member(student(igor,_,reading,_),L),
    next(student(_,_,_,blue), student(girl(GirlName),_,_,_), L).

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

The issue is that it won't treat solution(L) as if it's a predicate or a rule, simply a block of text, so I can't even test if it's correct or not. I am most interested in why it won't even function.

false
  • 10,264
  • 13
  • 101
  • 209
  • What purpose is the predicate `student((Name, Food, Hobby, Shirt)) :- name(Name), food(Food), hobby(Hobby), shirt(Shirt).` supposed to provide? Your usage of `student/4` everyone else in the program is simply as a data structure term. In addition, none of the smaller facts are exercised, either. If you say, for example `member(student(girl(GirlName),_,_,white),L)`, Prolog does not query `girl(GirlName)` in this context to determine what values of `GirlName` make it true. It is simply a term in this context, not a query. – lurker Nov 17 '17 at 11:45
  • That makes sense. Does that mean I can simply input the facts into solution? Like member([mira, pite, crosswords,_], L)? – Riste Dimitrov Nov 17 '17 at 11:53
  • If you're consistent, you can do that. In other words, if you establish a convention that you are working with a list where the first element is the name, second is food, etc, then it works. There is nothing wrong with using the terms such as `[name(mira), food(pite), ...]`, again as long as you're consistent. It's just that your code currently doesn't make use of the facts you have asserted that indicate what foods are valid foods, etc. If you want to make use of those facts, somewhere in your code you'd want something like, `name(Name)` ... then `[Name, ...]`. – lurker Nov 17 '17 at 11:59
  • Here's another example. Let's say we take your facts which describe valid foods, names, hobbies, and shirts. You could generate a list of valid sets using: `findall( [Name, Food, Hobby, Shirt], (name(Name), food(Food), hobby(Hobby), shirt(Shirt)), AllPossibleCombinations)`. Try that at a Prolog prompt and see what it looks like. It's not clear from your question what problem `solution` is solving, so I can't offer any hints in that regard. – lurker Nov 17 '17 at 12:01
  • *I've looked up examples of solved logic puzzles using Prolog to no real effect* ... There are actually a number of examples on the web in general, and several here in the `[prolog]` section of StackOverflow.com if you search for them. Here's one near the top of a google search list: [Using Prolog to solve logic puzzles](http://bennycheung.github.io/using-prolog-to-solve-logic-puzzles). On Stackoverflow.com, try searching for `[prolog] puzzle`. – lurker Nov 17 '17 at 12:59
  • Yes, I've read on that page. It specified that it uses a special library, but the link to such no longer exists. I can grasp the logic behind what it's trying to say, however, it's the implementation that frustrates me. I apologize, the study material that we were given for class is not much. – Riste Dimitrov Nov 17 '17 at 13:18
  • There are lots of other examples besides that page if you search a little. But as I mentioned, I have no idea what `solution` is supposed to solve, so I can't offer much more help than that. The key is to try to understand the principle of what's happening in Prolog, then you can figure it out. If you just try to mimick other solutions without understanding how they work, it will bend your brain. :) – lurker Nov 17 '17 at 13:43
  • 1
    When you say *The issue is that it won't treat `solution(L)` as if it's a predicate or a rule, simply a block of text*, I don't understand. You do have a syntax error here: `member(student(_,hamburger,writing,_),` but outside of that, it looks like a perfectly well-formed Prolog rule/predicate. – lurker Nov 17 '17 at 15:26
  • Is this the link that broke? https://github.com/LogtalkDotOrg/logtalk3/blob/master/examples/puzzles/jam_thief.lgt By the way, this is a Logtalk solution, which is an OO language based on Prolog. – Daniel Lyons Nov 17 '17 at 15:46
  • What i mean by it being treated as just text is that it cannot be queried, as if it isn't even a fact or commented out. I'll go back to the basics and try working my way up, then see if I can make a solution from that. Thank you for your help! :) – Riste Dimitrov Nov 17 '17 at 18:50
  • The purpose of the assignment is to find out the order of people sat around a table based around given facts. It's a bit awkward, but the facts are given in the format of person( name, favorite food, hobby, shirt colour) and whether they're left or right or next to another fact, similar somewhat to the zebra puzzle, though with only four places and not as many categories. – Riste Dimitrov Nov 17 '17 at 18:57
  • @lurker: Tag `[puzzle]` is a not a good idea, always stick to a concrete category – false Nov 17 '17 at 22:35
  • @false ummm I didn't set it to `puzzle`. – lurker Nov 18 '17 at 02:32
  • @lurker: Indeed, but you saw it – false Nov 18 '17 at 18:13
  • @false to be honest, I wasn't paying that close attention to the tags and hadn't noticed until you pointed it out. – lurker Nov 18 '17 at 22:04

1 Answers1

3

At first, I thought this girl/1 is the culprit as many have remarked. But even when removing all such occurrences your definition still fails (and after fixing that syntax error). Here is the responsible part that still fails for solution(L):

:- op(950, fy, *).
*(_).

solution(L) :-
   * length(L,4),
   L= [student(_/*teo*/, sandwich,_,_),_,_,_],
   member(student(_/*mira*/, pite, _/*crosswords*/,_),L),
   * member(student(girl(GirlName),_,_,white),L),
   * member(student(bruno,_,_,yellow),L),
   member(student(_,hamburger,_/*writing*/,_),L),
   L= [_, student(_,pie,_,_)|_/*[_,_]*/],
   * next(student(_,pie,_,_), student(teo,_,_,_), L),
   next(_/*student(bruno,_,_,_)*/, student(_,pizza,_,_), L),
   * next(student(_,_,_,white), student(_,pizza,_,_), L),
   * member(student(igor,_,reading,_),L),
   * next(student(_,_,_,blue), student(girl(GirlName),_,_,_), L).

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

All the names are irrelevant, just as their hobbies. What really matters is the food!

You have only four places, but a total of five foods (sandwich, pie, pite, hamburger, pizza) - give me just one of them!

That's the nice thing in Prolog: You can do such generalizations to get a clean diagnosis.

false
  • 10,264
  • 13
  • 101
  • 209
  • Thank you for your help! – Riste Dimitrov Nov 18 '17 at 09:16
  • @Riste: Just to be sure: Did you understand that you can execute the resulting fragment? – false Nov 18 '17 at 19:32
  • Yes. I inserted the facts and rules with solution(L), and outside of it left only the facts that are supposed to exist but aren't mentioned in the rules given for the assignment, like colour(red). The list is by the end near full and everything is it's proper place, leaving only a simple member([_,_,_, red], L) to add it in the only available space for it. – Riste Dimitrov Nov 19 '17 at 11:29