您现在的位置是:心海E站 > 文案短句 > >正文

prolog(Prolog的基本概念和语法规则)

发布时间:2024-02-03 19:23:50 admin 阅读:59

导读一、SWI-Prolog的截断机制 1、Prolog为用户提供了一种可存在于程序中并控制回溯水平的机制,即所谓的“截断(cut)”。Porlog中用叹号“!”表示截断。当在几个目标合取中设置了截断时,...
一、SWI-Prolog的截断机制

1、Prolog为用户提供了一种可存在于程序中并控制回溯水平的机制,即所谓的“截断(cut)”。Porlog中用叹号“!”表示截断。当在几个目标合取中设置了截断时,其作用就好似安上了一扇单向门。截断作为目标总是成功的,且不能重复满足。例如,下面的规则:example:-a,b,c,!,d,e,f.Prolog可以在目标a、b、c之间任意回溯,但一旦目标c一经满足,将通过截断符号,然后Prolog继续沿着目标链试图满足目标d、e、f,回溯可能在d、e、f之前进行,然而不能通过“!”回溯前面的,即使导致总体目标example失败也是如此。。

2、程序中一个谓词常常以多种形式存在,其中一般至少有两种不同形式的谓词丰硕,即递归规则和停止条件。当编写这样的谓词时,必须保证Prolog总是选择谓词的正确形式。如当Prolog应当采用停止条件时,就不应选择递归规则,否则会导致无穷递归。例如,下面这个程序是用于计算X的Y次幂。。

3、如果我们对Prolog提出询问:?-power(2,3,Result).将会以以下方式进行操作:2³=2²*2²=2¹*2¹=2⁰*且2⁰=。

4、但如果我们要求上例在给出回答后继续回溯,即键入分号,则会试图在知识库中寻找到另一个事实或规则,使其与上面的目标匹配。这就是说,Prolog搜索到的另一个Prolog谓词便是递归规则。Prolog与之匹配,使X为Y为0,然后Prolog计算Y_tmp得到-并试图满足目标:power(X,Y_tmp,Pow_tmp),这等于在计算2⁻¹,依次进行下去,将试图计算2⁻²,2⁻³,等等。这时无穷递归出现了,即递归目标连续产生自己,而永远不能满足停止条件,开始报错。。

5、上面的情况显然不是我们所期望的,它可以通过在停止条件中设置截断而得以避免,这样就得到了下列新的、更加健全和可靠的power谓词形式:power(_,0,1).:-!.power(X,Y,Pow):-   Y_tmpisY-1,   power(X,Y_tmp,Pow_tmp),   PowisPow_tmp*X.这里截断符号表示“如果已经选择了某个规则,那么决不允许回溯并选择同一谓詞的其他规则”。因此,这将会产生合理结果。。

6、此时我们可能已经意识到上一节中给出的两递归规则也会产生类似的、不希望的结果,而这可以通过在它们的停止条件中分别加入截断而加以避免。加入截断后的程序如图所示。总而言之,如果在停止条件处可能用到递归规则,那么必须在递归谓词的停止条件中加入截断符号。。

7、截断的另一个常用方式是与谓词fail联用。fail是一个Prolog标准谓词,由于它总是失败,因而可引起回溯。截断可设置在fail前面,以防止失败后的回溯。考虑图中的程序。这里截断与fail联用可以保证当一个雇员满足某个表明其不符合候选条件的规则时,在其它任何规则都不再考虑。例如,一个员工小于50岁,谓词fail将使目标eligible失败,而截断则保证在其它两个eligible规则中都不考虑他。。

8、应当注意,截断与fail联用通常可用否定谓词“+”代替,+是Prolog另一个标准谓词,如果目标X失败,则目标+(X)成功;如果X成功,则会失败。因此上面程序可以重写为图片中的形式。这里把三个eligible规则合成为一个规则,这两种编程方式中哪种可读性更高呢?关于这一问题存在争议,因为这取决于对截断的理解程度。。

二、Prolog句子语法判断问题,求大神帮忙!谢谢啦!

1、ListBox是编程中的列表框控件。

2、列表框控件显示项目列表,用户可以从中塌笑败选择一个或几个项目。

3、虽然可以设置多列的列表,但是在默认情况下,是在单列列表中团颤垂直显示选项。

4、如果项目数目超过了列表框可以显示的数目,控件上将自动出现滚动条。

5、这时用户可以在列表中上下左右滚动。

6、对于列表框事件,特别是当列表框作为对话框的一部分出现时,建议添加一个命令按钮,并把这个按钮和列表框并用。

7、按钮的单击事件过程应该使用列表框的选项执行适于应用程序的操作。

8、双击列表中的项目和先选定项目然后单击命令按钮具有相同的效果。

9、为此,应该在列表框控件的双击事件过程中调用命令按钮的单击过程。

10、也可以把命令按钮的Value属性值设置为True,这就将自动调用事件过程。

11、这将为爱用鼠标的用户提供快捷方式,同时没有妨碍喜欢使用键盘的用户执行同样的操作。

12、注意,没有与双击事件等价的键盘命令升衫。

13、希望我能帮助你解疑释惑。

三、用Prolog实现过程

1、If…Then…Else结构是最简单的过程式控制结构,我们常常称之为选择结构或条件结构。下图是一个由Python语言编写的一个例子:。

2、用Prolog表达上述过喝陕程的程序如图所示。程序中的write和read是Prolog内置的谓词,分别用于输出和输入昆八。nl表示换行。子句writetest(注意其变元)可保证Prolog做出正确的路线选择,其中截断用于保证得到唯一确定的解。空变量记作“_”,表耍低斤示对其变量的值并不关心。。

3、下图是Prolog运行后交互和输出的情况。。

4、循环结构也是过程式程序设计中常见的一种程序结构。下图是一段简短的Python代码,执行后会打出8×5大小的由“*”组成的矩形。。

5、与其相对应的Prolog程序如图所示。显然该程序中第一个while子句是递归循环的过程,在其测试条件失败之前始终进行自身调用。第二个while子句是停止条件。。

6、Prolog程序运行后交互和输出情况如图所示。读者还可以设计出其它循环结构,设计具有循环结构的程序的基本过程可归纳成下述规则:❶把过程转换成标准的While循环;❷整个过程分为三步:初始化,循环,给出结果所需的后续计算过程;❸用递归子句的尾表示循环,在循环开始处进行条件测试;❹用循环谓词的第二个子句进行徃完成后所需的计算;❺建立递归子句的前端谓词,该谓词用于为循环提供所需的变量值和从循环中获取变量值;❻设计调用前端谓词的程序。。

四、Prolog的数据结构

1、Prolog提供了一种在谓词中建立结构的方法,即允许谓词的变元具有变元,从而达到使谓词变元具有结构的目的。用这种方法可以使谓词中具有的信息反映现实生活中数据的实际关系。例如,考虑下面简单事实:吉恩的头发是红色的。显然,这个事实在Prolog中可以表示为:has(jean,red_hair).还有其他一系列关于人以及他们的头发、眼睛颜色和其它表征他们属性的事实,知识库可能如图所示。。

2、现在如果打算询问知识库中每个人的头发颜色,我们不得不这样提问:?-has(X,Y).并不断在提示符“?”后键入“;”,迫使回溯。会话过程如图所示。正如读者所看到的,这样将导致大量不必要的信息输出。这是因为数据是非结构化的,因而无法较为明确地询问。。

3、一种非常有用的,可确切地表达上述事实信息的方法如下:has(jean,hair(red)).。

4、现在为了了解知识库里每个人头发的颜色,我们可以简单地提出询问:?-has(X,hair(Y)).然后再要求Prolog在每个回答之后进行回溯,会话过程如图所示。这些信息不多不少正是我们想要的。。

5、表是基本的数据结构,许多实用的Prolog程序都是建立在表的基础之上的,表是许多元素的简单集合。比如:[red,yellow,green][1,5,68]没有元素的表叫作空表,表示为:[]下图是一行列表的代码。。

6、表头和表尾的概念是理解Prolog中表处理的基础。表头是一个元素,而表尾本身是一个表。表具有递归的数据结构,因为它是由表头和另一个表(表尾)组成的。正像其递归结构那样,表也可以递归定义。比如:考虑到[a,b,c],该表表头=a,表尾=[b,c];表尾也是一个表,表头=b,表尾=[c];而表尾[c],也是一个表,表头=c,表尾=[]。由于[]是个空表,所以递归过程到此为止。空表可视为停止条件。若用H表示表头,T表示表尾,则表记作:[H|T]其中竖线“|”是Prolog中用于分隔表头和表尾的符号。下图是对上一个例子询问的结果,注意观察匹配模式。其中“_”为空变量,表示不关心该位置上的元素。。

7、确定一个对象是否为某个表的成员。例如,我们有一个表List,内容是一些编程语言的名字。查找程序如下:find(List,[List|_]).find(List,[_|T]):-find(List,T).。

8、这是它的运行结果。Prolog对答案搜索的过程如下:进入知识库,试图与规则一匹配,因为目标与表头不同,故失败;继续搜索,试图与规则二匹配,目标和表尾作为参数,重新回到规则一,直到成功。。

9、两个表的追加。有时需要把两个表合并成一起形成新表,这个过程叫做并置或追加。下面这段代码可实现表的追加,concatenate(A,B,C).后就可以将表B追加到表A后形成表C。。

10、对于它的工作机制,不妨先从特殊到一般的规则来了解。❶编写一个规则concatenate(List1,List2,List3).,它可以将一个空列表与List1连接在一起。这一点很容易,concatenate([],List,List).就可以做到,当执行addto时,List3会和要追加的List2相同;❷添加一个规则,它可以将List1中的一个元素与List2连接在一起:concatenate([Head|[]],List,[Head|List]).;❸添加一个规则,它可以将List1中的两个元素或三个元素与List2连接在一起;❹泛化这些规则,转化递归形式,最终形成上图中的代码。。

11、表的反序。将表中元素的次序颠倒过来也是常用的一种处理过程。这个程序需要结合上一个例子中的追加列表的程序。其Prolog程序如下:re([],[]).re([H|T],L):-   re(T,M),   concatenate(M,[H],L).。

12、以上规则是基于这样的思想,即可以通过把一个表头追加到该表的表尾的反序表上,达到反序的目的。谓词reverse的第一个变元缩减到空表时,满足停止条件,停止条件还可以表述为空表的反序仍为空表本身。下图是程序的运行结果。在导入程序时要注意文件的顺序。。

13、表处理的一般形式。任何用于完成表处理的规则都是自身的递归。表处理规则具有以下一般形式:manipulate(具有表头H和表尾T的表):-   完成表头H的处理,   递归处理表尾T.除此之外,还需要一个停止条件。被处理的表不断缩小,当成为空表时,整个表被处理完了,因此完整的表处理规则具有如下形式:manipulate([]).manipulate([H|T]):-   process(H),   manipulate(T).此外,具体应用时可能还有其他更好的表示形式,因此不必一味强求。。

14、SWI-Prolog内置了丰富的处理列表的库,比如member就是用于查看元素是否属于列表,append用于追加列表,reverse用于倒序列表。你可以在SWI-Prolog的网站上的library(lists):ListManipulation页面上查找更多。。

五、Prolog规则结构与实例

1、让我们先从一个简单的规则开始讨论:eats(john,Y) :-food(Y),sweet(Y).这个规则告诉我们,如果Y是食物且甜,那么约翰会去吃它。规则由三个要素组成:规则头(此例中为eats(john,Y));符号“:-”(这个符号的意思可以理解为“如果”或“是”);规则体(此例中为food(Y),sweet(Y))。。

2、以下是相应的整个代码。。

3、下面是运行结果。Prolog把试图满足讯问?-eats(john,Food).的任务变为同时满足food(Food).和sweet(Food).。。

4、由于Prolog的特性使得它特别适合用于地图上色、日程安排之类没有算法或难以用算法描述的问题。接下来,以地图上色的问题作为例子。地图上色时,需要让相邻的两片区域用不同的颜色表示。下图是美国东南部的地图,尝试用三种颜色将它们区别出来。。

5、 在下面这个规则中,告诉了Prolog各个州的的接壤关系:coloring(Alabama,Mississippi,Georgia,Tennessee,Florida):-  different(Mississippi,Tennessee),  different(Mississippi,Alabama),  ……下图是整个代码。。

6、运行时,对Prolog用下列语句进行提问:?-coloring(Alabama,Mississippi,Georgia,Tennessee,Florida).这样就生成了需要的结果。在这些问题中,我们没有使用算法!Prolog不是通过编写算法来解决逻辑问题的,而是通过如实地描述真实世界,来呈现计算机可以设法解决的逻辑问题,让计算机做这些工作吧。。

下一篇:没有了 上一篇:烩面片的做法(烩面片的制作方法)