我只是“学习”了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将尝试查找满足以下条件的X
和Y
的实例化:“与[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/