如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/


目前商业上广泛使用的编程语言多是命令式或函数式的编程语言,这些语言在某些方面具有很高的相似度,比如 python 和 ruby 在很多地方是相通的,学会了一门,再学另一门便能够事半功倍,很多语言都是如此,然而今天要介绍的这门语言,却跟主流编程语言截然不同,它就是prolog——一门逻辑编程语言。

prolog 是 Programming in Logic 的缩写,它被广泛应用在人工智能、自然语言等研究领域,使用它来解决逻辑难题完全不在话下,今天我们将使用它来解决着名的爱因斯坦逻辑难题(斑马难题),首先让我们来认识一下 prolog 的语法。

prolog 基本语法

prolog 中有3种基本元素:事实、规则和查询。事实和规则用于描述数据,查询用于获取问题的答案。
我们可以这样定义事实:

  1. human(lucy).
  2. human(lili).
  3. father(lucy,david).
  4. sister(lucy,lili).
  5. sister(lili,lucy).

这段代码表示 lucy 和 lili 是人类,且她们是姐妹,david 是 lucy 的父亲,继续定义规则:

  1. daughter(Father,A,B) :-
  2. father(A,Father), sister(A,B)

这段规则表示对于变量A、B,如果Father变量是A的父亲,且A、B是姐妹,则A、B是Father对象的女儿。 
注意,在 prolog 中一个词若以小写开头,那么它是一个固定值,若以大写字母开头,则是一个变量。 
将这些事实和规则放在一个文件里面,在命令行下打开 prolog ,对这个文件进行编译,即可提出查询,比如 daughter(david,A,_),prolog 将会求出A可能的取值并输出到控制台,最后的下划线是一个占位符,不会进行求值。

在 prolog 中还可以使用递归完成列表和数学等运算,这部分是很强大的,但这里不打算讲,因为有了上面的基础知识后,我们就可以利用它来解决逻辑问题了,下面就让我们来解决“斑马难题”吧。

爱因斯坦逻辑难题

题目:5个不同国家且工作各不相同的人分别住在一条街上的5所房子里,每所房子的颜色不同,每个人都有自己养的不同宠物,喜欢喝不同的饮料。根据以下提示,你能告诉我哪所房子里的人养斑马,哪所房子里的人喜欢喝矿泉水吗?

  1. 英国人住在红色的房子里
  2. 西班牙人养了一条狗
  3. 日本人是一个油漆工
  4. 意大利人喜欢喝茶
  5. 挪威人住在左边的第一个房子里
  6. 绿房子在白房子的右边
  7. 摄影师养了一只蜗牛
  8. 外交官住在黄房子里
  9. 中间那个房子的人喜欢喝牛奶
  10. 喜欢喝咖啡的人住在绿房子里
  11. 挪威人住在蓝色的房子旁边
  12. 小提琴家喜欢喝橘子汁
  13. 养狐狸的人所住的房子与医生的房子相邻
  14. 养马的人所住的房子与外交官的房子相邻

这道题的解题关键在于,要以一种清晰的方式将每个房子相关的属性(国家、颜色、工作、宠物、饮料、编号)列出来,前面5个提示中包含了5个国家,那么可以利用这一点画出一个表格,每一行表示一个国家,每一列表示房子的一种属性。一步步根据提示得到一些推论,将结果填入表格,答案便渐渐清晰起来,使用这种人工方式推理的结果如下图所示:

虽然我们知道了解题的关键,但这个问题仍然需要经过很多步的推导才能得出结果,如果使用 prolog 那得到这个问题的答案就简单多了,只需要定义好事实和规则,然后向 prolog 提出问题,逻辑引擎就会为我们查出结果来。

下面是解决这个问题的 prolog 代码。

  1. house(A,[A,_,_,_,_]).
  2. house(A,[_,A,_,_,_]).
  3. house(A,[_,_,A,_,_]).
  4. house(A,[_,_,_,A,_]).
  5. house(A,[_,_,_,_,A]).
  6.  
  7. right(A,B,[A,B,_,_,_]).
  8. right(A,B,[_,A,B,_,_]).
  9. right(A,B,[_,_,A,B,_]).
  10. right(A,B,[_,_,_,A,B]).
  11.  
  12. middle(A,[_,_,A,_,_]).
  13.  
  14. first(A,[A,_,_,_,_]).
  15.  
  16. neighbor(A,B,[A,B,_,_,_]).
  17. neighbor(A,B,[_,A,B,_,_]).
  18. neighbor(A,B,[_,_,A,B,_]).
  19. neighbor(A,B,[_,_,_,A,B]).
  20. neighbor(A,B,[B,A,_,_,_]).
  21. neighbor(A,B,[_,B,A,_,_]).
  22. neighbor(A,B,[_,_,B,A,_]).
  23. neighbor(A,B,[_,_,_,B,A]).
  24.  
  25. attr(Country,Pet,Color,Drink,Work).
  26.  
  27. all_houses(Houses) :-
  28. house(attr(britsh,_,red,_,_), Houses),
  29. house(attr(spain,dog,_,_,_), Houses),
  30. house(attr(japan,_,_,_,painter), Houses),
  31. house(attr(italy,_,_,tea,_), Houses),
  32. house(attr(norway,_,_,_,_), Houses),
  33. first(attr(norway,_,_,_,_), Houses),
  34. right(attr(_,_,white,_,_), attr(_,_,green,_,_), Houses),
  35. house(attr(_,snail,_,_,photographer), Houses),
  36. house(attr(_,_,yellow,_,diplomat), Houses),
  37. middle(attr(_,_,_,milk,_), Houses),
  38. house(attr(_,_,green,cafe,_), Houses),
  39. neighbor(attr(norway,_,_,_,_), attr(_,_,blue,_,_), Houses),
  40. house(attr(_,_,_,orange,violinst), Houses),
  41. neighbor(attr(_,fox,_,_,_), attr(_,_,_,_,doctor), Houses),
  42. neighbor(attr(_,horse,_,_,_), attr(_,_,_,_,diplomat), Houses),
  43.  
  44. house(attr(_,zebra,_,_,_), Houses),
  45. house(attr(_,_,_,water,_), Houses).

在事实部分,将房子看做一个整体,描述了房子在5所房子中、房子的左右关系、中间的房子处于什么位置、第一所房子处于什么位置、房子间的相邻关系以及每所房子拥有哪些属性。
规则部分包含了对题目中提示的描述和最终问题的描述,这些定义是为了告诉逻辑引擎,在求值时必须满足这些条件。
最终的查询为 all_houses(A) ,prolog 逻辑引擎将会查找出满足结果的房子数组,注意每所房子由它的属性组成,这样最后得到的结果为:

[attr(norway, fox, yellow, water, diplomat), 
attr(italy, horse, blue, tea, doctor), 
attr(britsh, snail, red, milk, photographer), 
attr(spain, dog, white, orange, violinst), 
attr(japan, zebra, green, cafe, painter)] .

七周七语言之使用prolog解决爱因斯坦斑马难题的更多相关文章

  1. 使用prolog逻辑语言解决爱因斯坦斑马难题

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...

  2. 七周七语言之用ruby做点什么

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/05/25/sevenlang-ruby/. 每学一 ...

  3. Seven xxx in Seven Weeks ebooks | 七周七 xxx 系列图书 电子书| share 分享 | free of charge 免费!

    Seven xxx  in Seven Weeks ebooks |  七周七 xxx 系列图书  电子书| share  分享 | free of charge  免费! Seven Languag ...

  4. 人工智能技术导论——使用PROLOG逻辑语言解决爱因斯坦斑马文件

    一.背景 在上一篇博客https://www.cnblogs.com/wkfvawl/p/12056951.html上,我简单介绍了一下Prolog的一些基本语法,这篇博客主要通过老师课上讲过的一个问 ...

  5. 七周七语言——Prolog(二)

    1  递归 首先来看一个知识库: father(zeb,john_boy_sr). father(john_boy_sr,john_boy_jr). ancestor(X,Y):-father(X,Y ...

  6. 七周七语言之用Io编写领域特定语言

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/05/sevenlang-io/. Io 语言 ...

  7. 七周七语言之Ruby

    1.安装 Ubuntu 14.04 sudo apt-get install ruby version 1.9.1 2.命令行运行: irb 3.文挡查看:man RDoc 4.猜数字 2.2.7程序 ...

  8. 第七周C语言代码

    #ifndef NMN_LIST_H #define NMN_LIST_H   #include <stdio.h>   struct list_head {     struct lis ...

  9. C语言程序设计I—第七周教学

    第七周教学总结(14/10-20/10) 教学内容 第二章 用C语言编写程序 2.5 生成乘方表和阶乘表 课前准备 在蓝墨云班课发布资源: PTA:2018秋第七周作业 分享码:FE065DC5D8C ...

随机推荐

  1. 【Zookeeper】编程实战之Zookeeper分布式锁实现秒杀

    1. Zookeeper简述 我们要了解一样技术,首先应该要到它的官网,因为官网的信息一般都是最准确的,如下图是Zookeeper官网对它的介绍. 从官网的介绍中,可以总结出,Zookeeper是一个 ...

  2. Google protobuf使用技巧和经验

    Google protobuf是非常出色的开源工具,在项目中可以用它来作为服务间数据交互的接口,例如rpc服务.数据文件传输等.protobuf为proto文件中定义的对象提供了标准的序列化和反序列化 ...

  3. Kafka跨网络访问设置

    实际场景: kafka应用通过docker进行部署并暴露出不同kafka节点到不同的指定端口: 业务系统通过虚拟机进行部署: docker宿主机与业务系统在同一个局域网: 报错: 业务系统连接kafk ...

  4. 【整理总结】代码沉淀 - Caliburn.Micro - MV*模式短小精悍的框架

    Caliburn.Micro - Xaml made easy. web: https://github.com/Caliburn-Micro/Caliburn.Microdocument: http ...

  5. [BZOJ2738]矩阵乘法-[整体二分+树状数组]

    Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. (N<=500,Q<=60000) Solution 考虑二分答案,问题转化为求矩阵内为1 ...

  6. 八月暑期福利,10本Python热门书籍免费送!

    八月第一周,网易云社区联合博文视点为大家带来Python专场送书福利,10本关于Python的书籍内容涉及Python入门.绝技.开发.数据分析.深度学习.量化投资等.以下为书籍简介,送书福利请见文末 ...

  7. QQ在线交谈一句代码搞定

    现在有很多网页都有QQ在线咨询,还有什么QQ客服什么的,看着很高大上的一个功能,其实要实现很简单,只需要一句代码就搞定. 还是按以前的套路,先看效果图,再晒源代码 点击图标 再点击 就可以聊天了 再来 ...

  8. Introduction to Locking in SQL Server

    Locking is a major part of every RDBMS and is important to know about. It is a database functionalit ...

  9. Scrapy模拟登录GitHub

    d: 进入D盘 scrapy startproject GitHub 创建项目 scrapy genspider github github.com 创建爬虫 编辑github.py: # -*- c ...

  10. 人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型

    人脸检测及识别python实现系列(5)——利用keras库训练人脸识别模型 经过前面稍显罗嗦的准备工作,现在,我们终于可以尝试训练我们自己的卷积神经网络模型了.CNN擅长图像处理,keras库的te ...