小结到现在为止,我们已经对Prolog有了一个基本的了解,现在有必要对我们所学过的知识做一个系统的总结。
在Prolog的程序的运行流程方面我有了如下的认识:
我们还学习了,
有了以上的知识,我们还可以编写出一些让其它语言的程序员吃惊的小程序。下面就举一个分析家谱的程序。
father(a,b).表示a是b的父亲。 wife(aw,a). 表示aw是a的妻子。 male(t).表示b是男性。 female(d).表示d是女性。 上面我们并没有定义a、b、aw、bw的性别。 因为通过他们和其他人的关系我们可以很容易地确定他们的性别。不过要想让Prolog知道他们的性别我们就要定义如下的规则。 male(X):-father(X,_). female(X):-wife(X,_). 上面的male/1和female/1的谓词名称和事实的名称相同,这并不是什么特别的情况,你可以把所有定义相同的谓词的子句之间的关系想象“或者”的关系。也就是说:t和d是男性,或者如果X是其他人的父亲,则它也是男性。在判断性别时,我们并不关心此人是谁的父亲,所以后面一个变量用“_”代替了。 好了,假如有如下的询问:
最后一个询问,它虽然把所有的男性找了出来,可是它把a找了三次,原因很简单,因为我们有三个father/2的子句都包含a,好像不太理想,不过现在只能将就一下了,当我们学习了更多的知识后,就好解决了。 下面我们定义一些其他的亲戚关系的规则。你大概一看就能够理解。例如:X和Y是兄弟的条件是: X和Y有相同的父亲{father(Z,X),father(Z,Y)},并且他们都是男性{male(X),male(Y)},最后由于X和Y可以取相同的值,所以我们不得不加上一条X和Y不是同一个人{X\=Y}。 grandfather(X,Y):-father(X,Z),father(Z,Y). mother(X,Y):-wife(X,Z),father(Z,Y). brother(X,Y):-father(Z,X),father(Z,Y),male(X),male(Y),X\=Y. 当然我们还可以加入更复杂一点的规则, uncle(X,Y):-brother(X,Z),father(Z,Y). 这个叔伯的规则uncle/2调用了前面的规则brother/2。 这里只是简单回顾一下前面所学习的知识,所以这个家族程序虽然可以使用,但是却极不完善。例如:它会把某一答案重复多次,还不能描述没有小孩的丈夫的性别。 我们这样改一下会更好一点:male(X):-wife(_,X)。因此,规则的定义是多种多样的,到底哪种更好、哪种更快,这就是我们以后所要研究的问题之一了。 第八章、Prolog教程8 - 算术 |
