prolog - 在序言中输出或输入

标签 prolog

我只是“学习”了Prolog,但我并不真正理解函数中的输入和输出。

例如

concatenate([X|L1], L2, [X|L3]) = concatenate (L1,L2,L3).
concatenate([],L,L).


这是什么意思?

If I write 
?- concatenate(X,[2,Y],[1,1,1,2,3]) 


它返回

X=[1,1,1],
Y=3.


因此,这意味着3rd参数是1st和2d的串联,但是如何通过读取函数的声明来知道这一点?
谢谢

最佳答案

只是补充两个已经很好的答案...

在Prolog中,您不会将事物视为带有参数输入和输出的“函数”(尽管它们的行为确实如此),而是将其视为定义规则的“谓词”,并将尝试实例化变量中的任何可变参数(未实例化的变量)。一种使规则真实的方法。此过程可能导致没有解决方案,一个解决方案或多个解决方案,您将获得全部解决方案。并非所有谓词都为未实例化变量的每种组合提供这种“全部功能”,或者如果未实例化太多变量,则在逻辑上不可行提供解决方案。决定这些情况下参数的行为以及谓词是否具有任何解决方案的因素是谓词的逻辑,而不是输入或输出的任何正式声明。

让我们以给定的concatenate为例(注意,我正在为此使用GNU Prolog)。谓词concatenate(L1, L2, L3)的意思是“将L1与L2连接(按此顺序)得到L3”,比说“给定L1和L2在L3中提供它们的连接”更笼统,这意味着特定的输入和输出。

因此,如果我输入:

concatenate( [1,2], [3,4], L3 ).


我得到:

L3 = [1,2,3,4]

(1 ms) yes
| ?-


这意味着prolog使用所示的L3实例找到了该谓词的一种解决方案。我也可以输入以下内容:

concatenate( L1, [3,4], [1,2,3,4] ).


我会得到:

L1 = [1,2]

(1 ms) yes
| ?-


这意味着prolog使用所示的L1实例找到了该谓词的一种解决方案。同样,如果输入concatenate( [1,2], L2, [1,2,3,4] ),我将得到一个解决方案:L2 = [3,4]

让我们尝试一些更有趣的事情:

concatenate( L1, L2, [1,2,3,4] ).


Prolog将为此找到解决方案,但我提供了两个未实例化的变量。因此,解决方案将涉及以下可能性:

L1 = [1,2,3,4]
L2 = [] ? ;

L1 = [1,2,3]
L2 = [4] ? ;

L1 = [1,2]
L2 = [3,4] ? ;

L1 = [1]
L2 = [2,3,4] ? ;

L1 = []
L1 = [1,2,3,4] ? ;

(1 ms) yes
| ?-


现在让我们尝试一下:

concatenate( [1,2], L2, L3 ).


我得到:

L3 = [1,2|L2]

| ?-


在这种情况下,L2以及L3的可能性是无限的,因此prolog显示了一种通用的解决方案。

在您的示例concatenate( X, [2,Y], [1,1,1,2,3] )中,同样的想法适用。 Prolog将尝试查找满足以下条件的XY的实例化:“与[2,Y]串联的X给出[1,1,1,2,3]”,并且[2,Y]为a具有第一个元素2和第二个元素Y的列表。在这种情况下,您只能显示一种解决方案。

作为此主题的变体,请使用@DrH描述的列表概念(如果已这样做):

concatenate( X, [2|Y], [1,1,1,2,3] ).


您将得到X = [1,1,1]Y = [3]。请注意,如果您这样做:

concatenate( X, [2,Y], [1,1,1,2,3,4] ).


您会得到“否”(没有解决方案),因为Y在这里显示为原子,而不是列表(由于逗号语法)。换句话说,没有两个看起来像[2,Y]的元素列表,当它们与X的任何可能性连接在一起时,将产生[1,1,1,2,3,4]。但是,如果您这样做:

concatenate( X, [2|Y], [1,1,1,2,3,4] ).


您将得到X = [1,1,1]Y = [3,4],因为现在我将未实例化的Y显示为列表的尾部,列表本身就是一个列表,而不仅仅是一个原子(使用|语法)。

正如@WillNess指出的那样,如果未声明某些变量,则给定谓词的文档将告诉您要期望谓词的行为。写得好的序言谓词比写得不好或限制性更强的谓词更有可能“做您期望或想要的事情”。但这不会使谓词“坏”更为严格,因为它可能会起到非常有用的作用。只是没有用。在编写自己的序言谓词时,请考虑这些因素。

Prolog就像围棋游戏:几个简单的规则,但有许多有趣的可能性。

关于prolog - 在序言中输出或输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17806614/

相关文章:

prolog - 为什么 Prolog 中的 CLP(FD) 没有除法?

macos - Prolog错误的编译?

通过给类打分来进行 Prolog 分类

list - 我应该如何删除列表中的非数字使用序言

Prolog 谓词 - 无限循环

list - 检查序言中多个不同的数字列表

python - python中的prolog fact词法分析器

prolog - 生成毕达哥拉斯三元组到无穷大

Prolog:计算列表中的原子数

prolog - 最通用的统一符(Prolog)