Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地
Would you like to react to this message? Create an account in a few clicks or log in to continue.
Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地

一个供Prolog爱好者学习与交流的地方


您没有登录。 请登录注册

如何用prolog编写程序来解答4证人难题?

+2
Mercury Liao
kgisme169
6 posters

到页面 : 上一页  1, 2

向下  留言 [第2页/共2页]

Mercury Liao


Admin

ccandkk 写道:非常感谢版主!!那么晚了还回复我。这个prolog的很多题目和以前学的离散数学好像啊。不过跟C语言什么的区别还是挺大的。这学期刚刚接触!

再次感谢! Very Happy

是喔?没学过离散数学不知道,哈哈。
什么课会需要学prolog?

http://prolog.longluntan.net

yauhsien



调查了罪案的4位证人。从证人的话侦探得出的结论是:
如果男管家(mate)说的是真话,那么厨师(cook)说的也是真话。
厨师和园丁(gardener)说的不可能都是真话。
园丁和杂役(worker)说的不可能都是谎话。
如果杂役说真话,那么厨师在撒谎。请问,侦探能分别出这4位证人谁在说真话谁在撒谎吗?
*******************************************************
我想用prolog来写出程序进行推理,感觉到困难的地方是:
(1)"厨师和园丁(gardener)说的不可能都是真话"这样的逻辑用prolog该怎么表示呢?
(2)能否写出一个简单的程序来推出结论?
(3)假设推理的结果是要么A说真话要么B说真话,但是不可能同时说真话。这样的结论prolog以什么样的形式表示呢? 例如我的prolog程序的字句叫做true()。那么当我输入完条件的时候,请求结论true(X).的时候,prolog打印结果是打印可能的X。但是我刚才说了,如果答案是一个"异或"的答案,prolog该怎么打印结果呢?

(1) 厨子和园丁都说真话: honest(Cook), honest(Gardener)
厨子和园丁不都说真话: not(honest(Cook), honest(Gardener))
这要定义NAND:

nand(A, B) :- not(honest(A), honest(B)).

反面也可定义不都说谎的NAND

nand1(A, B) :- not(lie(A), lie(B)).

(3) 要嘛A说真话,要嘛B说真话,就是异或XOR:

xor(A, B) :- honest(A), lie(B).
xor(A, B) :- lie(A), honest(B).

prolog较特别的是,如果你有个字句为true/1,只能用这个字句找到什么东西是真的,
不过不能因为没找到它为真,就说它为假。
要像以下我这样定义: honest(true). lie(false). 诚实叫做真,说谎叫做假。
但是假如没找到诚实的事实,可不代表是假的。

而我的简单程序如此:
代码:

%无论谁都可能是诚实或说谎,
%诚实叫做真,说谎叫做假。
honest(true).
lie(false).

%如果A(男管家)说的是真话,那么B(厨师)说的也是真话。
%逻辑为 A->B === ~A v B
imply(A, B) :- lie(A), !, (honest(B); lie(B)); honest(A), honest(B).

%A(厨师)和B(园丁)说的不可能都是真话。
%逻辑为 A NAND B
nand(A, B) :- not(honest(A), honest(B)).

not(honest(A), honest(B)) :-
  lie(A), !, (honest(B); lie(B));
  (honest(A); lie(A)), lie(B).
not(lie(A), lie(B)) :-
  honest(A), !, (honest(B); lie(B));
  (honest(A); lie(A)),  honest(B).

%A(园丁)和B(杂役)说的不可能都是谎话。
%為前句「不可能都是真话。」的反面,但同样是 A NAND B
nand1(A, B) :- not(lie(A), lie(B)).

%如果杂役说真话,那么厨师在撒谎。
%逻辑类似 A->B ,但若 A 为 true 则 B 一定是 false
imply1(A, B) :- lie(A), !, (honest(B); lie(B)); honest(A), lie(B).

%求解
judge([Mate,Cook,Gardener,Worker]) :-
  imply(Mate, Cook),
  nand(Cook, Gardener),
  nand1(Gardener, Worker),
  imply1(Worker, Cook).

求解为
?- judge(L).
L = [false, false, true, true] ;
L = [false, false, true, false] ;
L = [false, false, false, true].

http://yauhsien.wordpress.com

Mercury Liao


Admin

yauhsien 写道:
调查了罪案的4位证人。从证人的话侦探得出的结论是:
如果男管家(mate)说的是真话,那么厨师(cook)说的也是真话。
厨师和园丁(gardener)说的不可能都是真话。
园丁和杂役(worker)说的不可能都是谎话。
如果杂役说真话,那么厨师在撒谎。请问,侦探能分别出这4位证人谁在说真话谁在撒谎吗?
*******************************************************
我想用prolog来写出程序进行推理,感觉到困难的地方是:
(1)"厨师和园丁(gardener)说的不可能都是真话"这样的逻辑用prolog该怎么表示呢?
(2)能否写出一个简单的程序来推出结论?
(3)假设推理的结果是要么A说真话要么B说真话,但是不可能同时说真话。这样的结论prolog以什么样的形式表示呢? 例如我的prolog程序的字句叫做true()。那么当我输入完条件的时候,请求结论true(X).的时候,prolog打印结果是打印可能的X。但是我刚才说了,如果答案是一个"异或"的答案,prolog该怎么打印结果呢?

(1) 厨子和园丁都说真话: honest(Cook), honest(Gardener)
厨子和园丁不都说真话: not(honest(Cook), honest(Gardener))
这要定义NAND:

nand(A, B) :- not(honest(A), honest(B)).

反面也可定义不都说谎的NAND

nand1(A, B) :- not(lie(A), lie(B)).

(3) 要嘛A说真话,要嘛B说真话,就是异或XOR:

xor(A, B) :- honest(A), lie(B).
xor(A, B) :- lie(A), honest(B).

prolog较特别的是,如果你有个字句为true/1,只能用这个字句找到什么东西是真的,
不过不能因为没找到它为真,就说它为假。
要像以下我这样定义: honest(true). lie(false). 诚实叫做真,说谎叫做假。
但是假如没找到诚实的事实,可不代表是假的。

而我的简单程序如此:
代码:

%无论谁都可能是诚实或说谎,
%诚实叫做真,说谎叫做假。
honest(true).
lie(false).

%如果A(男管家)说的是真话,那么B(厨师)说的也是真话。
%逻辑为 A->B === ~A v B
imply(A, B) :- lie(A), !, (honest(B); lie(B)); honest(A), honest(B).

%A(厨师)和B(园丁)说的不可能都是真话。
%逻辑为 A NAND B
nand(A, B) :- not(honest(A), honest(B)).

not(honest(A), honest(B)) :-
  lie(A), !, (honest(B); lie(B));
  (honest(A); lie(A)), lie(B).
not(lie(A), lie(B)) :-
  honest(A), !, (honest(B); lie(B));
  (honest(A); lie(A)),  honest(B).

%A(园丁)和B(杂役)说的不可能都是谎话。
%為前句「不可能都是真话。」的反面,但同样是 A NAND B
nand1(A, B) :- not(lie(A), lie(B)).

%如果杂役说真话,那么厨师在撒谎。
%逻辑类似 A->B ,但若 A 为 true 则 B 一定是 false
imply1(A, B) :- lie(A), !, (honest(B); lie(B)); honest(A), lie(B).

%求解
judge([Mate,Cook,Gardener,Worker]) :-
  imply(Mate, Cook),
  nand(Cook, Gardener),
  nand1(Gardener, Worker),
  imply1(Worker, Cook).

求解为
?- judge(L).
L = [false, false, true, true] ;
L = [false, false, true, false] ;
L = [false, false, false, true].

很佩服yauhsien,我一般对尚未有解决办法的贴子较有热情,
不太有动力想去回覆已解决的文章。
yauhsien的这种对prolog的学习态度值得我们学习啊……
非常感谢你对本论坛的积极参与。

http://prolog.longluntan.net

返回页首  留言 [第2页/共2页]

到页面 : 上一页  1, 2

您在这个论坛的权限:
不能在这个论坛回复主题