Python人工智能中逻辑编程语言Prolog基础
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
逻辑编程语言Prolog基础
## 什么是Prolog?
我们先给出一个例子.
man(jack)
man(dylan)
happy(jack)
playGuitar(jack) :- happy(jack)
运行:
?- man(jack)
Prolog回答:
yes
再运行:
?- playGuitar(jack)
Prolog回答同样是:
yes
上面的例子展示的就是Prolog程序和它的运行以及运行结果.
Prolog是一种基于模式匹配,树型结构和自动回溯等机制的面向目标的编程语言。这几个机制构成了灵活而强大的编程框架. Prolog尤其适用于包含结构化对象以及这些对象之间的关系的问题. 例如,prolog可以依据空间关系和一般规则进行推理. 所以,对于人工智能和非数值编程,prolog是一种强大的语言。字面上看,Prolog意思是以逻辑(logic)编程. 此观念来自于20世纪70年代初期。早期开发者有Robert Kowalski, Maarten Van Emden 和Alain Colmeraner.
在低级编程语言中,程序员往往指定计算机如何做一件事(How型语言). 在高级编程语言中,程序员给计算机指定需要做什么. 编程语言是从低级向高级演化的. Fortran, C, Lisp,Python,Java等几乎所有语言都属于How型语言. 相反地,Prolog舍弃了“指定计算机如何做事”这样的传统. 它鼓励程序员描述问题,而不是描述解决问题的详尽的方式. Prolog 为我们提供了另外一种编程的方式. 它背后的科学是人工智能. 我们可以从中学习到一些解决问题的观念,比如问题化简,回溯链,各种搜索技术等. Prolog可以让我们将抽象概念具体化. 编程者只需要指定什么是已知的,什么问题需要解决,即编程人员更关注事实而不是算法.
## Prolog语法
Prolog程序由语句(clauses)构成。语句又由对象和关系构成. 例如,上例中的 man(jack)
man就是一种关系,它可以指明对象的性别; jack就是该关系中的对象.
运行Prolog程序的方式很简单: 向程序提问. 语法如下:
?-关系表达式.
其中,
?- 是提示符.
后面有个结束符(.).
例如:
?- happy(jack).
写语句时,常需要用到符号”:-”.
:- 表示”如果”,或“蕴含于”.
例如:
playGuitar(jack) :- happy(jack)
上面代码的意思是:如果jack高兴,那么jack就要弹吉他.
:- 的右边叫主体;
:- 的左边叫规则头.
下面我们通过一个例子来看Prolog的机制,从中可见多个重要的概念. 例如, 甲(a)是乙(b)的父母,可写为:
parent(a,b)
parent是关系名称; a,b 是该关系的参量.
## Prolog举例
下面我们以中国近代著名的家庭义宁陈宝箴家的家谱为例,来看看Prolog的运行机制. 家谱如下:
graph TB
陈宝箴 --> 陈三立
黄淑贞 --> 陈三立
黄淑贞--> 陈三畏
陈三立 --> 陈师曾
陈三立 --> 陈寅恪
陈师曾 --> 陈封怀
```
在以下代码中,我们将人名用其拼音首字母的小写代替. 人名和拼音首字母的对应如下:陈宝箴 cbz
黄淑贞 hsz
陈三立 csl
陈三畏 csw
陈师曾 csz
陈寅恪 cyk
陈封怀 cfh
整个家谱由下列prolog程序给出:
parent(cbz,csl).
parent(hsz,csl).
parent(hsz,csw).
parent(csl,cyk).
parent(csl,csz).
parent(csz,cfh).
此程序包含6个语句. 每个语句声明了一个parent关系. 当此程序与prolog系统交互时,prolog就parent这一关系提问. 例如,陈三立是陈寅恪的父亲吗?实现代码如下: ?- parent(csl,cyk).
当prolog发现这是一个已经声明的事实,因此prolog会给出答案:
yes
我们也可问程序:“陈三畏是陈师曾的父母吗?”
?-parent(csw,csz)
prolog回答:
no
因为程序并未提及陈三畏是否为陈师曾父母.
当然我们也可问:“黄淑贞是Alice的父母吗?”
?-parent(hsz,alice)
Prolog不会判断alice是中国人名还是外国人名. prolog仅仅从程序中的关系来做判断. 因为并未听过”ALice”这个人,因此它果断给出结果:
no
但是,如果我们问“谁是陈三畏的父母?”这样的问题时,prolog确实可以给出我们一个值,而不仅仅是yes或no.
?- parent(X,csw).
Prolog给出的回答是
X=hsz
同理,我们可以问:”谁是陈三立的子女?“
?- parent(csl,X)
输出结果为:
X=csz
这里,我们只得到一个回答. 可是,从家谱中给我们可以发现看到陈三立的子女不止一个,所以我们期待能看到所有的结果的操作. 这时,我们输入一个分号,那么Prolog就会给出其余的答案:
X=cyk
由于上图中没有给出陈三立更多子女的信息,所以,如果我们试图知道更多答案,Prolog 会回答“no”.