逻辑思维的Prolog

起因

         从小就喜欢玩些智力游戏,也经常问别人一些考验智商的小问题。但自从开始程序猿这条不归路,我越来越发现无法与其他人交流。说的东西他们不懂,而且他们也不屑懂。现在写的这些个程序,确实都不需要多少思考,鉴定程序好坏的标准居然只成了是否报错,是否考虑的很周全。

         前阵子看到prolog,惊讶除了函数式编程以外,还有如此令我思想为之一开的语言。逻辑式编程确实符合人类思维,也确实让我对递归、回溯等有另一种认识。

         突然想给大家出个题,只是这次题与程序有关。

Prolog基础

         即是逻辑语言,程序思维在此没有多大帮助,所以会不会程序都没问题。即使是程序猿,如我这等程序猿接触此语言的相信也不是很多。

        

普及知识

         那么先普及一下知识。

         有兴趣的完全可以不看我写的,自己去百度谷歌。

         在此用一个图来解释。

        

 

本来弄了好多人,打了不少关系,最后想想算了。关系还是别太复杂了。

比如说是徐长卿和紫萱生下林清儿(其实不是),然后巫王和林清儿生赵灵儿,赵灵儿和李逍遥生林忆如,旁边那个王小虎是陪衬品。

现在已知林忆如的妈妈是赵灵儿,赵灵儿的妈妈是林清儿,林清儿的妈妈是紫萱,那么用prolog就可以这样描述:

妈妈(紫萱,林清儿).

妈妈(林清儿,赵灵儿).

妈妈(赵灵儿,林忆如).

注意每行后面有个点。

然后告诉prolog奶奶的意思就是妈妈的妈妈,语句可以这样写:

奶奶(X,Y) :- 妈妈(X,Z),妈妈(Z,Y).

注意 :- 是一个冒号一个减号。

 

这时候,你如果问prolog赵灵儿的奶奶是谁:

奶奶(X,赵灵儿).

那么prolog会输出:

X = 紫萱

 

注意:假设这是一个【母系氏族】。

 

如果你觉得简单,那么希望你一直这样觉得。

 

几点注意

代码里面的每一行都代表一个子句(clause)。其中带有“:-”的子句叫做规则(rule),不带有“:- ”的子句叫做事实(fact)。

  • 注意1:这里是为了阅读方便才使用汉字的,真正的prolog是不允许使用除了基本字符以外字符的,也就是说,上面的句子必须写成

  mama(zixuan,lingqinger).

  电脑才能够真正的理解。

  • 注意2:最末尾的“.”一定不能掉,它表示一个句子结束。
  • 注意3:上面词汇对于电脑来说并没有真正的含义,所以我们完全可以用 mama(zx,lqe).来表达这个关系,更进一步,我们甚至可以用 mm(a,b).来表达,只要你自己心里清楚mm表示妈妈,a表示紫萱,b表示林清儿就可以了。
  • 注意4:

  妈妈(紫萱,林清儿).

  这里紫萱和林清儿没有所谓的先后顺序,你完全可以写成妈妈(林清儿,紫萱).只要后面所有的【妈妈】这个事实都是后面的是前面的妈妈就可以了。比如说 妈妈(林清儿,赵灵儿).则应改为 妈妈(赵灵儿,林清儿).

 

另外,在Prolog里面诸如“zixuan”和“lingqinger”这类以小写英文字母开头的名称我们称它们为原子(atom),以大写英文字母为开头的名称我们称它们为变量,例如上面程序里面的“X”和“Y”。顾名思义,原子是常量,即它的值是不可变的,而变量的值可以改变。最后需要讲的是,在Prolog里面“,”代表逻辑关系中的“且”, “;”代表逻辑关系里面的“或”。

 

运行代码

         那么,你现在可以编写代码去运行看看效果了。

         首先要有prolog的环境。

SWI-Prolog中找到适合自己机器的版本。下载、安装、运行。

在文本文件中输入以上代码:

mama(zixuan,linqinger).

mama(linqinger,zhaolinger).

mama(zhaolinger,linyiru).

nainai(X,Y) :- mama(X,Z),mama(Z,Y).

 

然后保存成pl扩展名,例如文件存在d:/xianjian.pl。最后进入SWI-Prolog,输入

consult('d:/xianjian.pl').

 

如果成功则输出Yes,不确保你使用其他系统或版本输出True

这时候你问prolog:

nainai(X,zhaolinger).

那么他会给你说

X = zixuan

你问:

nainai(linqinger,linyiru).

得到结果是真

问:

nainai(zhaolinger,linyiru).

则返回是假

继续逻辑

下来多点代码:

nan(xuchangqing).

nan(wuwang).

nan(lixiaoyao).

nan(wangxiaohu).

nv(zixuan).

nv(linqinger).

nv(zhaolinger).

nv(linyiru).

baba(xuchangqing,linqinger).

baba(wuwang,zhaolinger).

baba(lixiaoyao,linyiru).

mama(zixuan,linqinger).

mama(linqinger,zhaolinger).

mama(zhaolinger,linyiru).

那么nver这个规则怎么定义?

这个就不浪费世间了,直接告诉答案:

nver(X,Y):-baba(Y,X);mama(Y,X),nv(X).

扯点程序

         看到这里,你可能觉得程序不过如此。

         这让我等程序猿如何是好。

         所以我提出如下需求,写下如下代码。

已知:

mama(zixuan,linqinger).

mama(linqinger,zhaolinger).

mama(zhaolinger,linyiru).

需求:

定义一个女娲氏族规则。说简单一点,定义一个祖先的规则。当我问zuxian(X,linyiru).

Prolog会告诉我

X=zhaolinger ;

X=linqinger ;

X=zixuan ;

好吧,这个问题也给答案

zuxian(X,Y):-mama(X,Y).

zuxian(X,Y):-mama(X,Z),zuxian(Z,Y).

也可以直接写成:

zuxian(X,Y):-mama(X,Y);mama(X,Z),zuxian(Z,Y).

这里我想说一句,人理解迭代,神理解递归。

最后一题

在上面表格中白色的方格(带有LXX标识的方格)里面填上英文单词,可供选择的单词有:

word(d,o,g).    word(r,u,n).    word(t,o,p).    word(f,i,v,e).

word(f,o,u,r).  word(l,o,s,t).  word(m,e,s,s).  word(u,n,i,t).

word(b,a,k,e,r).    word(f,o,r,u,m).    word(g,r,e,e,n).

word(s,u,p,e,r).    word(p,r,o,l,o,g).  word(v,a,n,i,s,h).

word(w,o,n,d,e,r).  word(y,e,l,l,o,w).

那么开始吧。

备注

最后,本文内容其中有出处,由于猜谜原因,没有给出出处,估计也没几个人猜,等自己过了这个劲头再给出处。

出题的人,很大程序上都是想让解题的人觉得很难,使用各种巧妙的技巧,费了好大的劲终于解出来了,然后以此证明自己之伟大。

如果那些程序猿觉得非工作时间写与工作、前途无关的程序是一件愚蠢的事情,那么,我也不再多说什么。

原文地址:https://www.cnblogs.com/nanqi/p/prolog.html