在Prolog找到最后一个条目

时间:2016-07-07 16:33:37

标签: prolog

在这里,得到或给予的是时间。 我正在尝试按照代码找出哪个是最后一个条目:得到还是给了?

got(1).
gave(2).
got(3).
gave(4).
got(5).
gave(6).
got(7).

isLastGot():- 
    findall(G, Got(G), Lg),
    findall(A, Gave(A), La),
    Lgg is lastElement(Lg),
    Laa is lastElement(La),
    Lgg > Laa.

lastElement([H|T],A):-lastElement([T],A).
lastElement([A],A).

但它不起作用:

?- isLastGot().
ERROR: functor/3: Domain error: `compound_non_zero_arity' expected, found `isLastGot()'
?- isLastGot.
ERROR: toplevel: Undefined procedure: isLastGot/0 (DWIM could not correct goal)
?- 

问题在哪里以及如何纠正?

编辑:如果我使用以下内容,则会在加载时收到错误:

isLastGot:- 
    findall(G, Got(G), Lg),
    findall(A, Gave(A), La),
    Lgg is lastElement(Lg),
    Laa is lastElement(La),
    Lgg > Laa.

错误:... /gotgave.pl:11:14:语法错误:操作员期望 还有很多警告:got / 1的子句不在源文件中 (对于给予/ 1的类似警告)

文件未加载。

即使把所有得到的东西放在一起,虽然警告和错误已经消失,但主要的运行时错误仍然存​​在:

1 ?- isLastGot.
ERROR: toplevel: Undefined procedure: isLastGot/0 (DWIM could not correct goal)
2 ?- isLastGot().
ERROR: functor/3: Domain error: `compound_non_zero_arity' expected, found `isLastGot()'
3 ?- 

这与我是否在声明中使用isLastGot(): - 或isLastGot: - 无关。

1 个答案:

答案 0 :(得分:0)

我在评论中引用了所示代码中的几个基本问​​题。我会在这里更清楚地拼出来。

got(1).
gave(2).
got(3).
gave(4).
got(5).
gave(6).
got(7).

在上一节中,你应该看到关于"不连续的警告"谓词或谓词"不在一起" (这是"不连续"的意思)。这是因为您定义got/1后跟gave/1,然后返回got/1。您有gotgave穿插或交错。许多Prolog实现将忽略不连续的定义,因此这是一个问题。如果你想表示事实,它们需要是连续的:

got(1).
got(3).
got(5).
got(7).
gave(2).
gave(4).
gave(6).

当然,我意识到这可以解决问题的前提,即找出最后一个问题。使用断言顺序作为仅使用两个不同仿函数创建特定事实序列的方法并不是一种好方法。将序列表达为列表更有意义,例如:[got(1), gave(2), got(3), gave(4), got(5), gave(6), got(7)]。然后处理列表。

isLastGot():-

如前所述,这是基本的,无效的语法。 Prolog不使用空括号来表示没有参数。正确的形式是isLastGot :-

    findall(G, Got(G), Lg),
    findall(A, Gave(A), La),

以上两个调用都有错误,可能是印刷的:GotGave是大写的,但它们不应该是大写的。它们应为gotgave

    Lgg is lastElement(Lg),
    Laa is lastElement(La),

以上两个语句将Prolog 谓词视为函数。 Prolog 谓词不是函数,不能以这种方式调用。您使用两个参数定义了lastElement/2,并且调用它的正确方法是:

    lastElement(Lg, Lgg),
    lastElement(La, Laa),

最后:

lastElement([H|T],A):-lastElement([T],A).
lastElement([A],A).

lastElement([T], A)来电应为lastElement(T, A)。由于T[H|T]的尾部,因此它已经是一个列表,不应表示为[T]。这将只是一个元素的列表,它本身就是一个列表。你的谓词不会像书面那样工作。另请注意,Prolog已经last/2完成了这一点。