人工智能技术导论——使用PROLOG逻辑语言解决爱因斯坦斑马文件
一、背景
在上一篇博客https://www.cnblogs.com/wkfvawl/p/12056951.html上,我简单介绍了一下Prolog的一些基本语法,这篇博客主要通过老师课上讲过的一个问题,来体验一下prolog在逻辑推理上的优势。
在介绍问题之前,先引入一道Prolog题:
试编写一个描述亲属关系的Prolog程序,然后再给出一些事实数据,建立一个小型演绎数据库。
提示:可以以父亲和母亲为基本基本关系(作为基本谓词),再由此描述祖父、祖母、兄弟、姐妹以及其他亲属关系。
mother(a,c).
mother(a,d).
mother(c,g).
mother(c,f).
father(b,c).
father(b,d).
father(e,g).
father(e,f).
grandfather(X,Z):-father(X,Z),father(Y,Z).
grandmother(X,Z):-mother(X,Y),mother(Y,Z).
sister(X,Y):-mother(Z,X),mother(Z,Y).
aunt(X,Y):-mother(Z,Y),sister(Z,X).
这里使用SWI-Prolog进行测试

注意,在 Prolog 中一个词若以小写开头,那么它是一个固定值,若以大写字母开头,则是一个变量。
继续定义规则:
family(F,M,C) :-father(F,C), mother(M,C).
提出查询,比如

prolog 将会求出X可能的取值并输出到控制台,中间的下划线是一个占位符,不会进行求值。有了上面的基础知识后,我们就可以利用它来解决逻辑问题了,下面就让我们来解决“斑马难题”吧。
二、爱因斯坦逻辑难题
有5间不同颜色的房间,每间住个不同国籍的人,每人有自己喜欢的饮料、香烟和宠物。已知信息:
英国人在红房间中
西班牙人有一条狗
挪威人住在左边第一间房里
黄房间中的人在抽库尔斯牌香烟
抽切斯菲尔德牌香烟的人是养了一只狐狸的人的邻居
挪威人住在蓝房间隔壁
抽温斯顿牌香烟的人有一只蜗牛
抽幸运牌香烟的人喝橘子汁
乌克兰人喝茶
日本人抽国会牌香烟
抽库尔斯牌烟的房间在有匹马的房间隔壁
绿房间中的人喝咖啡
绿房间在白房间的左边
中间房间的人喝牛奶
这道题的解题关键在于,要以一种清晰的方式将每个房子相关的属性(颜色、国籍、香烟、宠物、饮料、编号)列出来,前面5个提示中包含了5个国家,那可以利用这一点画出一个表格,每一行表示一个国家,每一列表示房子的一种属性。一步步根据提示得到一些推论,将结果填入表格,答案便渐渐清晰起来,使用这种人工方式推理的结果如下图所示:

虽然我们知道了解题的关键,但这个问题仍然需要经过很多步的推导才能得出结果,如果使用 prolog 那得到这个问题的答案就简单多了,只需要定义好事实和规则,然后向 Prolog 提出问题,逻辑引擎就会为我们查出结果来。
下面是解决这个问题的 Prolog 代码。
house(A,[A,_,_,_,_]).
house(A,[_,A,_,_,_]).
house(A,[_,_,A,_,_]).
house(A,[_,_,_,A,_]).
house(A,[_,_,_,_,A]). left(A,B,[A,B,_,_,_]).
left(A,B,[_,A,B,_,_]).
left(A,B,[_,_,A,B,_]).
left(A,B,[_,_,_,A,B]). middle(A,[_,_,A,_,_]). first(A,[A,_,_,_,_]). neighbor(A,B,[A,B,_,_,_]).
neighbor(A,B,[_,A,B,_,_]).
neighbor(A,B,[_,_,A,B,_]).
neighbor(A,B,[_,_,_,A,B]).
neighbor(A,B,[B,A,_,_,_]).
neighbor(A,B,[_,B,A,_,_]).
neighbor(A,B,[_,_,B,A,_]).
neighbor(A,B,[_,_,_,B,A]). attr(Country,Pet,Color,Drink,Smoke). all_houses(Houses) :-
house(attr(britsh,_,red,_,_), Houses),
house(attr(spain,dog,_,_,_), Houses),
house(attr(japan,_,_,_,congressCigarettes), Houses),
house(attr(ukraine,_,_,tea,_), Houses),
house(attr(norway,_,_,_,_), Houses),
first(attr(norway,_,_,_,_), Houses),
left(attr(_,_,green,_,_), attr(_,_,white,_,_), Houses),
house(attr(_,snail,_,_,winstonCigarettes), Houses),
house(attr(_,_,yellow,_,coorsCigarettes), Houses),
middle(attr(_,_,_,milk,_), Houses),
house(attr(_,_,green,cafe,_), Houses),
neighbor(attr(norway,_,_,_,_), attr(_,_,blue,_,_), Houses),
house(attr(_,_,_,orange,luckCigarattes), Houses),
neighbor(attr(_,fox,_,_,_), attr(_,_,_,_,chesfieldCigarettes), Houses),
neighbor(attr(_,horse,_,_,_), attr(_,_,_,_,coorsCigarettes), Houses), house(attr(_,zebra,_,_,_), Houses),
house(attr(_,_,_,water,_), Houses).
在事实部分,将房子看做一个整体,描述了房子在5所房子中、房子的左右关系、中间的房子处于什么位置、第一所房子处于什么位置、房子间的相邻关系以及每所房子拥有哪些属性。
规则部分包含了对题目中提示的描述和最终问题的描述,这些定义是为了告诉逻辑引擎,在求值时必须满足这些条件。
最终的查询为 all_houses(A) ,prolog 逻辑引擎将会查找出满足结果的房子数组,注意每所房子由它的属性组成,这样最后得到的结果为:

人工智能技术导论——使用PROLOG逻辑语言解决爱因斯坦斑马文件的更多相关文章
- 使用prolog逻辑语言解决爱因斯坦斑马难题
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...
- 人工智能技术导论——逻辑程序设计语言PROLOG
最近在复习人工智能导论,里面介绍了一种逻辑关系语言PROLOG,但这本书里面用到的编译器是Turbo PROLOG,这个编译器早就被淘汰了,我后来找的了它的升级版Visual PROLOG,但一些语法 ...
- 七周七语言之使用prolog解决爱因斯坦斑马难题
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...
- GAITC 2019全球人工智能技术大会(南京)
2019年5月25日至26日,由中国人工智能学会主办,以“交叉.融合.相生.共赢”为主题的2019GAITC将在南京全新亮相. 2019 全球人工智能技术大会(2019 GAITC)以“前端引领.深度 ...
- C语言解决约瑟夫问题详解的代码
将开发过程中比较重要的一些内容做个收藏,下面的内容是关于C语言解决约瑟夫问题详解的内容,希望能对码农有帮助. #pragma once #include<vector> class PRO ...
- 第28月第21天 记事本Unicode 游戏编程中的人工智能技术
1. Windows平台,有一个最简单的转化方法,就是使用内置的记事本小程序notepad.exe.打开文件后,点击文件菜单中的另存为命令,会跳出一个对话框,在最底部有一个编码的下拉条. 里面有四个选 ...
- 15 GIL 全局解释器锁 C语言解决 top ps
1.GIL 全局解释器锁:保证同一时刻只有一个线程在运行. 什么是全局解释器锁GIL(Global Interpreter Lock) Python代码的执行由Python 虚拟机(也叫解释器主循环, ...
- 关于C语言解决汉诺塔(hanoi)问题
C语言解决汉诺塔问题 汉诺塔是典型的递归调用问题: hanoi简介:印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜,总有一个僧侣 ...
- VS2015如何新建C++或者C语言版的lib文件
当我们不想公开我们的代码的时候,可以把我们的代码封装成静态数据连接库,即lib文件.下面介绍下如何生成lib文件. 以VS2015为例,一种是C++版的lib文件,一种是C语言版的lib文件. 一.按 ...
随机推荐
- Gemini.Workflow 双子工作流高级教程:数据库-设计文档
数据库设计文档 数据库名:Workflow_New 序号 表名 说明 1 WF_Activity wf_Activity 2 WF_ActivityInstance wf_ActivityInstan ...
- 【Luogu P4779】dijkstra算法的堆优化
Luogu P4779 利用堆/优先队列快速取得权值最小的点. 在稠密图中的表现比SPFA要优秀. #include<iostream> #include<cstdio> #i ...
- Flow入门初识
Flow是facebook出品的JavaScript静态类型检查工具. 由于JavaScript是动态类型语言,它的灵活性也会造成一些代码隐患,使用Flow可以在编译期尽早发现由类型错误引起的bug, ...
- jquery浅复制和深复制区别
jquery浅复制和深复制区别
- C博客作业05--2019-指针
0.展示PTA总分 1.本章学习总结 1.1 学习内容总结 1.2 本章学习体会 2.PTA实验作业 2.16 -7 输出月份英文名 2.1.1 伪代码 char* getmonth(int n) { ...
- 聚类-K-Means
1.什么是K-Means? K均值算法聚类 关键词:K个种子,均值聚类的概念:一种无监督的学习,事先不知道类别,自动将相似的对象归到同一个簇中 K-Means算法是一种聚类分析(cluster ana ...
- UML类图绘制
UML图简介 含义:UML-Unified Modeling Language 统一建模语言,又称标准建模语言.是用来对软件密集系统进行可视化建模的一种语言 主要模型: 功能模型:从用户的角度展示系统 ...
- Python如何爬取实时变化的WebSocket数据【华为云技术分享】
一.前言 作为一名爬虫工程师,在工作中常常会遇到爬取实时数据的需求,比如体育赛事实时数据.股市实时数据或币圈实时变化的数据.如下图: Web 领域中,用于实现数据'实时'更新的手段有轮询和 WebSo ...
- 一道随机函数题:由rand5()生成rand7()
题目:已知rand5()函数能随机等概率的生成0, 1, 2, 3, 4,利用rand5()函数编写一个rand7()函数实现相似的功能. 分析:其实就是利用rand5()组合成一个更大范围的数,之后 ...
- vue axios 总结篇
1.npm --save 和 --save-dev 有什么区别 发布到线上的叫生产环境~,在本地开发的时候叫开发环境,--save就是会打包到线上去并且在线上环境能用到的,比如你npm install ...