【问题标题】:How to append list to a list in Prolog?如何将列表附加到 Prolog 中的列表?
【发布时间】:2018-04-25 04:42:40
【问题描述】:

我想将一个列表附加到一个列表中。

foo([a,b,c]).
goo([d,e,f]).
hi(X):-append(foo(X),goo(X)).

我想得到如下所示的结果。但我意识到我无法执行foo(X)goo(X)

?- hi(X).
|: [a,b,c,d,e,f].

【问题讨论】:

  • 你可以,但这不是这样做的方法。 Prolog有没有函数,它只有谓词

标签: list prolog append


【解决方案1】:

关于 Prolog 的一个常见误解是它没有函数:它只有谓词。谓词没有输入或输出,它统一了调用它的变量。因此,谓词可以是多向的

关于 prolog 的另一个误解是,如果你调用:

append(foo(X), goo(Y)).

Prolog 会将foo(x)goo(Y) 视为谓词调用。它不是:在这种情况下foo(X)goo(Y)术语。带有函子(不是谓词)的术语和术语。所以这里foo(X) 是函子foo/1 的术语,术语X 作为第一个(也是唯一的)参数。

但是,您可以调用谓词,方法是将它们写在另一个谓词的正文中。

例如你可能想要的:

hi(X) :-
    foo(A),
    goo(B),
    append(A, B, X).

那么这是如何工作的呢?如果我们调用hi(X),那么 Prolog 将在源代码中查找是否存在由该名称定义的谓词。如果有,它将旨在从上到下执行谓词的子句。这里只有一个子句hi/1,就是我们刚刚写的那个。所以现在 Prolog 将开始执行该子句的 body

我们现在看到正文中的第一项是foo(A)(注意A,而不是X)。所以现在 Prolog 将再次为 foo/1 谓词寻找一个子句。你的问题中有一个。 foo([a,b,c])。这意味着 Prolog 现在将执行 unification。它将统一我们的变量A 与事实。所以在调用foo/1 谓词之后,现在是A = [a,b,c]。我们对goo(B) 做同样的事情:调用它之后,B = [d,e,f]

最后我们打电话给append(A, B, X).。现在append/3 是一个内置谓词,它将两个第一个参数中的列表附加到第三个参数(但它可以多向使用)。调用后,X 将统一为[a,b,c,d,e,f]。由于谓词调用结束,Prolog 会报告X = [a,b,c,d,e,f]

我们现在完成了吗?不! Prolog 的另一个重要方面是它在语法上免费回溯。这意味着对于我们完成的每个谓词调用(foo(A)goo(B)append(C)),仍然可能存在我们感兴趣的子句。所以从概念上讲,Prolog 解释器会寻找更多的答案。但在这里我们很幸运foo/1goo/1 只有一个定义。请注意,大多数 Prolog 解释器不必在这里进行回溯,因为他们会做一些记录,以便提前知道我们是否应该尝试回溯。

【讨论】:

  • 句法回溯?这个概念不存在。
  • @false:我曾经从与我的博士生导师(Bart Demoen)的讨论中借用它。它基于这样一个事实,即在 Prolog 中,“你可以免费回溯”。不是计算意义上的,而是句法意义上的。如果我没记错的话,这些条款是在 Maurice Bruynooghe 想聘请 Bart Demoen 为 KU Leuven 的 Prolog 研究团队时引入的,尽管我可能已经忘记了细节。
  • 句法统一。即,无理论或配备 Herbrand 理论。然而,有按时间顺序回溯
  • @false: 意思是你不必编写一个有结构的程序来进行回溯:它从你引入一个新子句的那一刻起就自动完成了。因此,从某种意义上说,它是免费的,将一个简单的程序变成一个带有回溯的程序不需要任何努力。使用“语法上免费”。我重新排序(可能生活在一个既有罗马语系又有德语系的国家的缺点之一是形容词的顺序不合逻辑)。
  • 就目前而言,它没有任何意义。
【解决方案2】:

也可以自己写附加谓词,这可能有助于你更全面地理解Prolog:

append_list([],L, L).
append_list([Head|Tail], List2, [Head|List]):-
     append_list(Tail, List2, List).

它获取第一个列表的第一个元素并将其插入结果列表,然后在没有列表的第一个元素的情况下递归调用自身,这意味着它将移动到第二个元素。基本谓词是 append_list([], L, L). 这表示:当第一个列表为空时,返回结果列表。

融入你的价值观

append_list([a,b,c],[d,e,f],X).

将返回X = [a, b, c, d, e, f]

【讨论】:

    猜你喜欢
    • 2015-02-05
    • 2013-02-08
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多