一、实验目的
1、学会使用Prolog语言;
2、用Prolog语言巩固一阶逻辑知识;
3、能够使用prolog语言实现一阶逻辑的证明;
二、实验硬件软件平台
硬件:计算机
软件:操作系统:WINDOWS
应用软件:Prolog
三、实验内容及步骤
熟悉prolog语言的使用并实现对于一阶逻辑推理的证明。
prolog软件安装请参考:https://blog.csdn.net/houmou/article/details/41845595
源代码和实验截图下载
链接:https://pan.baidu.com/s/14JDHdVDM-CfxwTK3Ip-y7g
密码:xj6n
【内含实验报告,本实验小题目较多,图片也很多且多为小图,放在博客上可能会影响阅读,完整版请从上面自取】
实验题目及解答
第1题:对于a,b,c,d四种输入情况,验证|?- p(a).的真假;
a. p(b). p(a) :- p(b). p(a) :- p(c).
b. p(c). p(a) :- p(b). p(a) :- p(c).
c. p(b). p(a) :- p(b), p(c).
d. p(c). p(a) :- p(b); p(c).
解答此题的prolog语言相关原理——Prolog 的语句
Prolog 语言仅有三种语句:事实(Fact)、规则(Rule)和问题(Question)。
1、事实:格式:<谓词名>(<项表>),比如a题中的p(b)就是一个事实。
2、规则:
格式:<谓词名>(<项表>):-<谓词名>(<项表>){,<谓词名>(<项表>)}。
其中,“:-”号表示“if”(也可以直接写为 if ),其左部的谓词是规则的结论,右部的谓词是规则的前提,因此有右边的条件满足了,就可以推出左边的结论。
3、问题:
格式:?-<谓词名>(<项表>){,<谓词名>(<项表>)},这个就是问题1的输入。将每个问题的代码复制进txt文件后,将后缀改为pl,直接点开就会出现prolog页面。就可以输入问题,让prolog求解。
第一题的解答
a. p(b). p(a) :- p(b). p(a) :- p(c).
事实:p(b),
规则(2条):p(a) :- p(b). p(a) :- p(c).
因为p(b)为真,因此根据第一条规则,p(a)为真。
【如何操作】将题目的代码,比如这一题是 “p(b). p(a) :- p(b). p(a) :- p(c).” ,把它复制到一个TXT文件中,将后缀名改为.pl,如果安装好了prolog,那么就可以直接打开输入要查询的命题语句了,下同。
b. p(c). p(a) :- p(b). p(a) :- p(c).
事实:p(c),
规则(2条):p(a) :- p(b). p(a) :- p(c).
因为p(c)为真,因此根据第二条规则,p(a)为真。
c. p(b). p(a) :- p(b), p(c).
事实:p(b),
规则(1条):p(a) :- p(b), p(c)。
因为p(b)为真,但是不知道p(c)是否为真,所以p(a)为false。注意这里只有一条规则,因为中间是逗号,逗号表示要同时满足所有用逗号连起来的条件,才能推出为真。
d. p(c). p(a) :- p(b); p(c).
事实:p(c),
规则(1条):p(a) :- p(b); p(c).
因为p(c)为真,且p(b)和p(c)之间使用分号连接的,分号的意思是,只要满足其一,就可以退出结论(类似于“或”),因此,p(a)为真。
第2题:先手工得到下面语句的答案,在用Prolog语言进行验证
|?- p(X) = p(a).
|?- p(X, f(Y)) = p(a, Z).
|?- p(X, a, Y) = p(b, Y, Z).
|?- p(X, f(Y, a), Y) = p(f(a, b), V, Z).
|?- p(f(X, g(Y)), Y) = p(f(g(a), Z), b).
步骤:找到prolog安装目录文件夹bin下的prolog.exe,直接逐条输入就可以观察到结果。
第二题,实质上是一个全程量词的实例化过程。
第3题:为下列集合构造Prolog检测器
• 非负数;
• 奇数;
• {0,1,2,3,4,5,6,7,8}
此题的原理:prolog语言的运算
Prolog给用户提供了一些预先定义的运算符,这些运算符可用于完成基本的算术运算,它们是:
+ 加 - 减 * 乘 / 除 div 整除 mod 整数的余数 is 令表达式求值
比如,输入 ?-ANS is 5 + 1.
输出:ANS is 6.
Prolog还为用户提供了一些用于比较算术运算值的运算符,它们是:
X > Y X大于Y
X < Y X小于Y
X >= Y X大于或等于Y
X =< Y X小于或等于Y
X = Y X等于Y
X \= Y X不等于Y
第三题的解答
3.1:非负数
p(X) :-
X>=0.
其中,大写字母X可以替换为任意变量(全程量词的实例化),而小写字母或者单词都没有这种功能,他们只能表示一些特定的变量或定义。因此,在做判断的时候,需要用大写字母作为判断条件。之后的练习中也会用到这项特性。
3.2:奇数
p(X) :-
X mod 2>0;
X mod 2<0.
使用上述取余数的运算mod,根据常识,一个数mod2如果大于0或小于0,那么一定是1或-1,对应正奇数和负奇数,所以这样就能判断X是奇数。
3.3:集合{0,1,2,3,4,5,6,7,8}
p(X) :-
member(X,[0,1,2,3,4,5,6,7,8]).
调用一个member函数,用于检测X是否在集合内。
第4题:
已知兄弟sib(X, Y)的定义如下
sib(X, Y):- p(Z, X), p(Z, Y), X \== Y.
4.1:定义堂兄弟co(X, Y);
4.2; 定义二代堂兄弟sco(X, Y),X,Y的父母是堂兄弟。
代码如下:
sib(X, Y) :- p(Z, X), p(Z, Y), X\== Y.
co(X,Y) :- sib(A,B),p(A,X),p(B,Y),A\==B,X\==Y.
sco(X,Y) :- co(A,B),p(A,X),p(B,Y),A\==B,X\==Y.
解释:
当X不等于Y,Y且Z是和Y的父亲,则X和Y是兄弟。
当A不等于B,X不等于Y,A和B是兄弟,且A是X的父亲,B是Y的父亲,则X和Y是堂兄弟。
当A不等于B,X不等于Y,A和B是堂兄弟,且A是X的父亲,B是Y的父亲,则X和Y是二代堂兄弟。
为了测试方便,我们需要新增下面这些事实:
p(grandfather,father).
p(grandfather,uncle).
p(father,me).
p(uncle,cousin).
p(me,son1).
p(cousin,son2).
其中,p(X,Y)代表X是Y的父亲。
1、sib(X, Y) :- p(Z, X), p(Z, Y), X\== Y.
X和Y有相同的父亲,且不是同一个人,因此XY是兄弟。
2、co(X,Y) :- sib(A,B),p(A,X),p(B,Y),A\==B,X\==Y.
AB是两兄弟,且AB分别有一个孩子X和Y,那么XY就是堂兄弟。
3、sco(X,Y) :- co(A,B),p(A,X),p(B,Y),A\==B,X\==Y.
AB已经是堂兄弟关系,那么他们各自的孩子就是二代堂兄弟。
测试结果