Prolog and Logic Puzzles

瘦欲@ 提交于 2019-12-24 02:23:16

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/47348548/prolog-and-logic-puzzles

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!