在学习命题逻辑和谓词逻辑后,我转向Prolog。
我想知道是否有人可以为我澄清语法,因为我无法阅读它。
我可以轻松阅读下面的内容。所以它是在说
如果X是Y的孩子,则X是Y的下降。
然后继续说
如果X是Z的子节点,Z是Y的下降,则X是Y的下降。
descend(X,Y) :-
child(X,Y).
descend(X,Y) :-
child(X,Z),
descend(Z,Y).
但是一旦我开始研究列表编程,我就很难阅读谓词的语法。例如下面的
remove([], _, []).
remove([X | Xs], X, Ys) :- remove(Xs, X, Ys).
remove([Y | Xs], X, [Y | Ys]) :- X \== Y, remove(Xs, X, Ys).
从测试开始,它会移除第二个项目,例如,如果我输入
remove([a,b,c], b, Ys).
我会得到Ys = [a,c].
但我不知道如何阅读语法,如果有人可以为我分解,那就太好了。
答案 0 :(得分:4)
由于您有一些逻辑背景,您可能会发现将规则作为逻辑公式阅读会很有帮助。让我们用dif / 2替换(\ ==)/ 2然后删除/ 3读取如下:
remove([], _, [])
←true
remove([X | Xs], X, Ys)
←remove(Xs, X, Ys)
remove([Y | Xs], X, [Y | Ys])
←dif(X,Y)
∧remove(Xs, X, Ys)
注意暗示箭头如何指向规则的头部。这意味着规则的主体是先行者,规则的主体是结果。因此,您将规则读作:如果规则的主体为真,则规则的头部为真。规则中的目标通过结合连接。请注意事实如何true
为先行,意味着remove([], _, [])
始终为真。另一方面,如果规则的主体为假,则规则失败,但如果另一规则的主体为真,则谓词可能仍然成功。如果所有其他规则的主体也是假的,则谓词失败。因此,为谓词设置多个规则构成逻辑或:如果rule1 OR rule2 OR rule3成功,谓词remove / 3会成功。
正如您特别要求语法一样,熟悉列表的头尾符号也是合适的。也就是说,您可以显式地编写列表的第一个元素,然后是列表构造函数|
和列表的其余部分:
[1|Xs]
...列表以1
开头,然后有一个休息
[1,2|Xs]
...列表以1
和2
开头,然后是休息
[X|Xs]
...列表至少有一个元素后跟一个休息
请注意列表元素如何用,
分隔,而列表的其余部分用|
分隔。 |
之后的术语实际上是一个列表,也可以是一个空列表。以下是相等列表的一些示例:
[1]
与[1|[]]
[1,2]
= [1|[2]]
= [1|[2|[]]]
= [1,2|[]]
对于以下列表,已有8种方法可以编写它:
[1,2,3]
= [1,2|[3]]
= [1|[2,3]]
= [1|[2|[3|[]]]]
= ...
考虑到上述观察结果,您将逐个检查规则。由于@lurker在答案中已经这样做了,所以我不会详细介绍。但是,我想补充一点,如果一个规则有几个目标,比如你的例子中的第三个规则,我发现一次一个地完成目标是有帮助的:
remove([Y | Xs], X, [Y | Ys]) :-
原始列表的元素Y
也在没有X
IF的列表中...
remove([Y | Xs], X, [Y | Ys]) :-
dif(X,Y),
... X
与Y
AND ...
remove([Y | Xs], X, [Y | Ys]) :-
dif(X,Y),
remove(Xs, X, Ys).
......此关系也适用于Xs
,X
和Ys
。
那为什么要更换?内置谓词(\ ==)/ 2只是成功或失败,没有统一或副作用。它适用于在给定时间测试术语不等式,但以后没有任何影响。请考虑以下查询:
?- X=Y, X\==Y.
no
首先,变量X
和Y
是统一的,随后对不等式的测试失败。但是:
?- X\==Y, X=Y.
X = Y
首先,对不平等的测试成功,否则Prolog甚至不会考虑第二个目标。然后X
和Y
成功统一。这就是我的意思以后没有效果。所以我在上面写的关于读取谓词的所有内容对于(\ ==)/ 2并没有多大意义。
作为较短的版本,我使用if_/3和=/3在帽子中抛出以下内容:
list_without_element([],[],_E).
list_without_element([X|Xs],L,E) :-
if_(X=E,L=Ys,L=[X|Ys]),
list_without_element(Xs,Ys,E).
答案 1 :(得分:2)
你需要对它进行测试只是为了看它的作用,这说明remove/3
可能不是那么好。 remove
非常通用,并留下了“删除内容?”的问题。此外,它是命令式,而Prolog希望成为关系型。或许更好的名称是list_without/3
,它表示第三个参数中的列表是第一个参数中的列表,但没有第二个参数。
尽管如此,让我们阅读你的内容。
阅读remove/3
谓词可以按如下方式进行:
remove([], _, []).
如果删除任何元素,空列表仍然是空列表。
remove([X | Xs], X, Ys) :- remove(Xs, X, Ys).
列表
Ys
是已移除[X|Xs]
元素的列表X
如果Ys
是删除所有X
后的列表Xs
来自remove([Y | Xs], X, [Y | Ys]) :- X \== Y, remove(Xs, X, Ys).
的1}}元素。
[Y|Ys]
如果[Y|Xs]
与X
不同,那么
X
是已删除Y
元素的列表Ys
和X
{1}}是从Xs
移除所有preg_match('/([A-Z]{2}[0-9]{3})/', $albumid)
元素后获得的列表。
作为练习,您应该再次尝试阅读这些内容,但请使用更多关系名称,例如我提供的示例重命名。