【问题标题】:Einsteins puzzle in prolog序言中的爱因斯坦谜题
【发布时间】:2020-09-14 10:56:58
【问题描述】:

我试图在序言中解决爱因斯坦难题 - 五朋友版 - 但我卡住了。我似乎无法在我的代码中找到错误,或者如何解决它。目标是编写一个 Prolog 程序,正确识别他们每个人做了什么样的谜题、谜题的主题以及他们完成它需要多长时间 - 解决方案(人、种类、时间、主题)

我也收到此错误: uncaught exception: error(existence_error(procedure,members/3),clue1/0)

我认为这与成员有关?

知识库:

  1. 这五个朋友是 Krystal、Angie,一个是做外太空拼图的,一个是用 30 分钟完成拼图的,一个是做单词搜索的。

  2. Ethan 要么在 90 分钟内完成字母拼图,要么在 20 分钟内完成冬季主题拼图。

  3. Dereck 和那个做逻辑谜题的人,一个花了 45 分钟,而另一个人做了一个电影主题的谜题。男孩用最短和最长的时间完成他们的谜题。

  4. 尼克花了不到 40 分钟的时间来解决他的谜题,这不是视觉数独。安吉花了 40 多分钟来解决她的猫拼图。

  5. 那个花了 60 分钟做运动拼图的女孩没有玩拼图。拼图是由一个男孩做的,比做逻辑谜题的孩子用时少,但比做单词搜索的孩子用时多。

  6. 视觉数独需要一个小时才能完成,或者是外太空主题。德雷克没有做冬季主题的拼图(不是单词搜索。)

这是我的代码:

woman(krystal).
woman(angie).
man(dereck).
man(ethan).
man(nick).

kind(word).
kind(sudoku).
kind(letter).
kind(jigsaw).
kind(logic).

time(30).
time(90).
time(20).
time(45).
time(60).

theme(outerspace).
theme(winter).
theme(movies).
theme(sports).
theme(cat).

members([],_).
members([M|Ms],Xs) :- select(M,Xs,Ys),members(Ms,Ys).


clue1(Game) :- members([[krystal,_,_,_,_], [angie,_,_,_], [P,_,30,_], [P,word,_,_], [P,_,_,outerspace]], Game, man(P)).
clue2(Game) :- members([[krystal,_,_,_,_], [angie,_,_,_],[P,_,_,outerspace], [P,_,_,outerspace], [P,_,_,outerspace]], Game, man(P)).
clue3(Game) :- members([[krystal,_,_,_,_], [angie,_,_,_],[P,_,30,_], [P,_,30,_], [P,_,30,_]], Game, man(P)).
clue4(Game) :- members([[krystal,_,_,_,_], [angie,_,_,_],[P,_,_,word], [P,_,_,word], [P,_,_,word]], Game, man(P)).
clue5(Game) :- member([ethan, letter, 90,_], Game).
clue5(Game) :- member([ethan, _, 20, winter], Game).
clue6(Game) :- member([P, _, 20, _], Game, man(P)).
clue6(Game) :- member([P, _, 90, _], Game), man(P).
clue7(Game) :- member([dereck, _, 45, _], Game).
clue7(Game) :- member([dereck, _, _, movies], Game).
clue8(Game) :- member([_, logic, 45, _], Game).
clue8(Game) :- member([_, logic, _, sport], Game).
clue9(Game) :- member([nick, _, 30, _], Game).
clue9(Game) :- member([nick, _, 20, _], Game).
clue10(Game) :- member([P, sudoku, _, _], Game, \+nick(P)).
clue11(Game) :- member([angie, _, 45, cat], Game).
clue11(Game) :- member([angie, _, 60, cat], Game).
clue11(Game) :- member([angie, _, 90, cat], Game).
clue12(Game) :- member([P, Q, 60, sport], Game, girl(P), \+sport(Q)).

clue13(Game) :- member([P, jigsaw, Q, _], Game, man(P), \+time(20)).
clue13(Game) :- member([P, jigsaw, Q, _], Game, man(P), \+time(90)).
clue13(Game) :- member([P, jigsaw, 30, _], Game, man(P)), member([_, word, 20, _], Game), (member([_, logic, 40, _], Game); member([_, logic, 60, _], Game); member([_, logic, 90, _], Game)).
clue13(Game) :- member([P, jigsaw, 45, _], Game, man(P)), (member([_, word, 20, _], Game); member([_, word, 30, _], Game)), (member([_, logic, 60, _], Game); member([_, logic, 90, _], Game)).
clue13(Game) :- member([P, jigsaw, 60, _], Game, man(P)), (member([_, word, 20, _], Game); member([_, word, 30, _], Game); member([_, word, 46, _], Game)), member([_, logic, 90, _], Game).

clue14(Game) :- member([_, sudoku, 60, _], Game).
clue14(Game) :- member([_, sudoku, _, outerspace], Game).
clue15(Game) :- member([P, _, _, winter], Game, \+dereck(P)).
clue16(Game) :- member([_,word,_,P], Game, \+winter(P)).

clue17(Game, A,B,C,D) :- member([A,B,C,D], Game).

solution(A,B,C,D) :-
    Game = [A,B,C,D],
    clue1(Game),
    clue2(Game),
    clue3(Game),
    clue4(Game),
    clue5(Game),
    clue6(Game),
    clue7(Game),
    clue8(Game),
    clue9(Game),
    clue10(Game),
    clue11(Game),
    clue12(Game),
    clue13(Game),
    clue14(Game),
    clue15(Game),
    clue16(Game),
    clue17(Game, A,B,C,D),
    members([[_,sudoku,_,_], [_,logic,_,_],[_,letter,_,_],[_,jigsaw,_,_],[_,word,_,_]],Game),
    members([[krystal,_,_,_],[angie,_,_,_],[ethan,_,_,_],[dereck,_,_,_],[nick,_,_,_]],Game),
    members([[_,_,60,_],[_,_,45,_],[_,_,90,_],[_,_,30,_],[_,_,20,_]],Game),
    members([[_,_,_,sports],[_,_,_,cat],[_,_,_,outerspace],[_,_,_,movies],[_,_,_,winter]],Game),
    write(Game),
    true.

/*
1) One is named Krytal who didnt do the Outerspace puzzle, the Word search and didnt use 30 min 
    and One is named Angie who didnt do the Outerspace puzzle, the Word search and didnt use 30 min
2) One boy did the Outerspace puzzle
3) One boy used 30 min
4) One boy did the Word Search  
5) Ethan either finished the letter tiles in 90 minutes or did the winter themed puzzle in 20 minutes.
6) Boys took the shortest and longest times to finish their puzzles.
7) Dereck either took 45 minutes or did a movies themed puzzle.
8) The one who did the logic puzzle either took 45 minutes or did a movies themed puzzle.
9) Nick spent less than 40 minutes working on his puzzle
10) Nick did not the Visual Sudoku. 
11) Angie spent more than 40 minutes working on her Cat puzzle.
12) The girl who spent 60 minutes working on a sports puzzle did NOT do the Jigsaw. 
13) the jigsaw was done by a boy in less time than the one who did the Logic Puzzle but more time than the one who did the Word Search.
14) The Visual Sudoku either took an hour to complete or was Outerspace themed. 
15) Dereck did not do the winter themed puzzle 
16) The Word Search is not winter themed
*/

【问题讨论】:

  • 所以错误是带有三个参数的members 不是一个东西。这是正确的,你只用两个定义了一个,但你用三个来调用它。我建议将您的程序粘贴到swish.swi-prolog.org 并检查它标记为红色的所有部分。此外,member/2 是一个内置函数,看起来与您的 members 非常相似。您可能想要重命名谓词...

标签: prolog zebra-puzzle


【解决方案1】:

这只是对最直接问题的回答,它不会为您提供完整的工作解决方案。不过,你的道路很好,请不要气馁!

此外,首先:将您的程序加载到 SWI-Prolog 中会出现两个警告:

Warning: /home/isabelle/einstein.pl:49:
    Singleton variables: [Q]
Warning: /home/isabelle/einstein.pl:50:
    Singleton variables: [Q]

这意味着在这些位置的子句中有“单例”变量:在子句中只出现一次的变量。单例变量可能表示非常严重的逻辑错误,因此您不应忽略此类警告。也许clue13 的前两个子句中的变量Q 应该以某种方式与时间2090 相关?

至于你的报错信息,我们来解包吧:

  • existence_error(procedure, ...) 表示您试图调用一个不存在的“过程”(更常见的是我们称之为“谓词”)
  • members/3 是不存在的程序
  • clue1/0 是错误调用的位置。

作为参考,我本地版本的 SWI-Prolog 也报类似这样的错误,对用户友好一点:

?- solution(A, B, C, D).
ERROR: Undefined procedure: members/3
ERROR:   However, there are definitions for:
ERROR:         members/2
ERROR: 
ERROR: In:
ERROR:   [10] members([[krystal|...],...|...],[_3044,_3050|...],man(_3056))
ERROR:    [9] clue1([_3084,_3090|...]) at /home/isabelle/einstein.pl:29
ERROR:    [8] solution(_3116,_3118,_3120,_3122) at /home/isabelle/einstein.pl:64
ERROR:    [7] <user>

无论哪种方式,您都试图从clue1 调用带有三个参数的谓词members,但不存在这样的定义。让我们看看你的定义:

clue1(Game) :- members([[krystal,_,_,_,_], [angie,_,_,_], [P,_,30,_], [P,word,_,_], [P,_,_,outerspace]], Game, man(P)).

这个问题很难发现,因为你学会了非常糟糕的代码格式化习惯。这不是你的错:太多的经典 Prolog 书籍坚持将太多的代码放在一行中,所以太多的 Prolog 程序员以这种方式编写代码。

你的意思更像是这样的:

clue1(Game) :-
    members([[krystal,_,_,_,_], [angie,_,_,_], [P,_,30,_],
             [P,word,_,_], [P,_,_,outerspace]],
            Game,
    man(P)).

你现在能看到吗? members 调用应在Game 之后关闭,man(P) 不应作为此调用的参数。所以应该是:

clue1(Game) :-
    members([[krystal,_,_,_,_], [angie,_,_,_], [P,_,30,_],
             [P,word,_,_], [P,_,_,outerspace]],
            Game),
    man(P).

我非常非常强烈地建议您不要在每行中编写多个目标,并且在目标内也不要打破长行。您将需要以类似的方式修复更多谓词。

在此之后,您的程序将不再存在存在错误,但会在 members 调用中快速失败。您正在尝试拨打members(&lt;five-element list&gt;, &lt;four-element list&gt;),但无法成功。在solution 中设置Game 变量的方式看起来不对。尝试为您正在谈论的对象使用比AD 更具描述性的名称。

【讨论】:

    猜你喜欢
    • 2016-12-20
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2018-01-31
    • 2021-02-21
    • 1970-01-01
    • 2016-08-13
    相关资源
    最近更新 更多