展会信息港展会大全

用prolog解爱因斯坦的智力题
来源:互联网   发布日期:2011-10-03 20:11:54   浏览:29333次  

导读:c语言数组和指针的三大区别用prolog解爱因斯坦的智力题在公司做事和在实验室做事 博客 博客中国 博客动力 blog blogdriver blogger 中国...

用prolog解爱因斯坦的智力题                                       

 

      昨天刚学了prolog,解决了几个简单的逻辑问题,就想用prolog来解决人脑不容易解决的问题,于是想到传说中的爱因斯坦出的智力题。对于这种比较复杂的逻辑问题来说,在概念不清楚,逻辑学基础不够强的情况下,用prolog解决起来其实并不简单,犯了很多概念和逻辑上的错误,花了一天功夫终于会解了。

    这就是传说中爱因斯坦出的,号称全世界只有2%的人能解出的逻辑题:
------------------------------------------------
1、在一条街上,有5座房子,喷了5种颜色。
2、每个房里住着不同国籍的人
3、每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物
问题是:谁养鱼?
提示:
1、英国人住红色房子
2、瑞典人养狗
3、丹麦人喝茶
4、绿色房子在白色房子左面
5、绿色房子主人喝咖啡
6、抽PallMall香烟的人养鸟
7、黄色房子主人抽Dunhill香烟
8、住在中间房子的人喝牛奶
9、挪威人住第一间房
10、抽Blends香烟的人住在养猫的人隔壁
11、养马的人住抽Dunhill香烟的人隔壁
12、抽BlueMaster的人喝啤酒
13、德国人抽Prince香烟
14、挪威人住蓝色房子隔壁
15、抽Blends香烟的人有一个喝水的邻居

  我们用列表
  [h(N1,C1,D1,P1,S1),h(N2,C2,D2,P2,S2),h(N3,C3,D3,P3,S3),h(N4,C4,D4,P4,S4),h(N5,C5,D5,P5,S5)]
来表示房子列表。房子列表中的元素h(N,C,D,P,S)表示一个房子,N,C,D,P,S分别表示房子的属性:主人的国籍,颜色,主人所喝的饮料,养的宠物,抽的烟。

  然后定义如下的谓词:

  nation(h(N,_,_,_,_),N).表示判断房间主人的国籍。
  color(h(_,C,_,_,_),C).表示判断房间的颜色。
  drink(h(_,_,D,_,_),D).表示判断房间主人所喝的饮料。
  pet(h(_,_,_,P,_),P).表示判断房间主人所养的宠物。
  smoke(h(_,_,_,_,S),S).表示判断房间主人所抽的烟。

  定义题目中要用到一些关于位置的谓词:

  left(HA,HB,L) :- append(L1,L2,L),append(L3,[HA,HB],L1).
  定义的是:在房子列表L中,房子HA在HB的左边。用的是分治定义:将L分为两个子表L1,L2,如果L1等于表[HA,HB]连接在某一个表L3的末尾所构成的新表,那么HA就在HB的左边。
  neighbor(HA,HB,L) :- left(HA,HB,L).
  neighbor(HA,HB,L) :- left(HB,HA,L).
  利用前面定义的left谓词来定义neighbor谓词。
  center(H,[_,_,H,_,_]).
  first(H,[H,_,_,_,_]).
  定义center和first谓词,分别表示房屋H在房子列表的中间和房子列表的最左边。

  定义部分完成,以下是解决问题部分。

  将要解决的问题标记为einsten(X),X是需要求的参数,将它与房子列表绑定:

  X = [h(N1,C1,D1,P1,S1),h(N2,C2,D2,P2,S2),h(N3,C3,D3,P3,S3),h(N4,C4,D4,P4,S4),h(N5,C5,D5,P5,S5)],

  以下是对条件的描述:

  注:member(H,X)表示判断房子H是否在房子列表X中,或者从房子列表X中取一间房子放在H中。

  % 英国人住红色房子
  member(H1,X),nation(H1,englishman),color(H1,red),
  % 瑞典人养狗 
  member(H2,X),nation(H2,swede),pet(H2,dog),
  % 丹麦人喝茶
  member(H3,X),nation(H3,dane),drink(H3,tea),
  % 绿色房子在白色房子左面
  member(H4a,X),member(H4b,X),color(H4a,green),color(H4b,white),left(H4a,H4b,X),
  % 绿色房子主人喝咖啡
  member(H5,X),color(H5,green),drink(H5,coffee),
  %抽Pall Mall 香烟的人养鸟
  member(H6,X),smoke(H6,pallmall),pet(H6,bird),
  %黄色房子主人抽Dunhill 香烟
  member(H7,X),color(H7,yellow),smoke(H7,dunhill),
  %住在中间房子的人喝牛奶
  center(H8,X),drink(H8,milk),
  % 挪威人住第一间房
  nation(H9,norwegian),first(H9,X),
  % 抽Blends香烟的人住在养猫的人隔壁
  member(H10a,X),member(H10b,X),smoke(H10a,blend),pet(H10b,cat),neighbor(H10a,H10b,X),
  %抽Blue Master的人喝啤酒
  member(H11,X),smoke(H11,bluemaster),drink(H11,bier),
  %养马的人住抽Dunhill 香烟的人隔壁
  member(H12a,X),member(H12b,X),pet(H12a,horse),smoke(H12b,dunhill),neighbor(H12a,H12b,X),
  % 德国人抽Prince香烟
  member(H13,X),nation(H13,german),smoke(H13,prince),
  % 挪威人住蓝色房子隔壁
  member(H14a,X),member(H14b,X),nation(H14a,norwegian),color(H14b,blue),neighbor(H14a,H14b,X),
  % 抽Blends香烟的人有一个喝水的邻居
  member(H15a,X),member(H15b,X),smoke(H15a,blend),drink(H15b,water),neighbor(H15a,H15b,X),
  %问题“谁养鱼?”其实也提供了一个信息,表明有一间房子的主人养鱼,把这个信息也要加上
  member(H16,X),pet(H16,fish).   

  好,现在用swi prolog consult这个程序,在:-前输入einsten(X).回车,得到问题的解:

  X = [h(norwegian, yellow, water, cat, dunhill), h(dane, blue, tea, horse, blend), h(englishman, red, milk, bird, pallmall), h(german, green, coffee, fish, prince), h(swede, white, bier, dog, bluemaster)] ;

  这是满足上面所有描述的唯一正确房子列表。观察这个房子列表,得到问题的答案是:德国人养鱼。

  从解决这个问题所犯的错误中我总结了如下经验和教训:

  1,一定要把prolog的三种语句:事实、规则、问题,完全搞清楚。

  2,要理解prolog求解问题的原理,也就是要把霍恩子句逻辑搞清楚。

  3,解决问题的关键在于清楚地描述问题所需要的全部条件,人解决问题的时候难免会使用直觉,而在下意识中使用某些隐含条件,要让prolog正确解决问题,就应该把这些隐含条件也挖掘出来。

  prolog是一种基于一阶谓词逻辑的语言,它在人工智能程序设计中有广泛应用。

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港