2

我是 Prolog 的初学者,我想知道如何使用ground/1.

目前我有这个代码:

intertwine([], [], []).
intertwine([E|Es], Fs, [E|Gs]) :- intertwine(Es, Fs, Gs).
intertwine(Es, [F|Fs], [F|Gs]) :- intertwine(Es, Fs, Gs).

但是当我尝试在 shell 中调用它时:

intertwine([1,2],X,[1,a,2,b]).

我得到了正确的答案X=[a,b],但查询并没有结束,好像它认为还有另一个答案。所以,我按“;” 我得到“假”作为输出。我读了另一个问题的答案,我应该用它ground/1 来检查第三个列表是否已经完全实例化来处理这个案例。

问题是,作为一个完整的初学者,我不知道该怎么做。那么有没有人好心地向我解释 ground 是如何工作的,以及我如何使用它来检查特定参数的实例化并使用它来不让代码检查不存在的答案?

4

3 回答 3

2

这种行为是完全可以的。有时,Prolog 能够找出没有进一步的解决方案,有时则没有。细节对所描述的内容没有影响。考虑:

?- X = 1 ; 2 = 3.
X = 1 ;
false.

在这里,我们很明显这2 = 3不是一个解决方案,Prolog 仍然要求我们继续。

顺便说一句,而不是 ; 您也可以按空格键获得下一个解决方案。

于 2011-12-02T04:25:09.707 回答
0

而不是ground/1,要检查参数的实例化,您应该考虑使用var/1(或相关的 nonvar/1 )。var/1 它是基本的元谓词,它将 Prolog 的力量扩展到了所谓的语言子集之外。它允许对程序本身进行推理,根据变量等基本实体的“状态”选择适当的行为。

从实际编程 POV 中(非常)简单地使用这些元谓词,可以实现特定参数的默认值:例如

%%  gunzip(+Gz, ?Ex) is det.
%
%   uncompress the file Gz in Ex
%   if Ex is var strip .gz extension
%
gunzip(Gz, Ex) :-
    (   nonvar(Ex)
    ->  true
    ;   atom_codes(Gz, Cs),
        phrase(string(ExCs), Cs, ".gz"),
        atom_codes(Ex, ExCs)
    ),
    gzopen(Gz, read, I, [type(binary)]),
    setup_call_cleanup(open(Ex, write, O, [type(binary)]),
               copy_stream_data(I, O),
               ( close(I), close(O) )
              ).

如果我们调用 gunzip('file.gz', F), F 会(希望)以膨胀数据的名称进行实例化。

于 2011-12-02T10:18:46.767 回答
0

就像 false 说的,这种行为真的没问题。ground/1谓词实际上与该问题无关。

没有代码检查不存在的答案?

如果我的问题正确,剪切在这里会有所帮助。

intertwine([], [], []).
intertwine([E|Es], Fs, [E|Gs]) :- intertwine(Es, Fs, Gs), !.
intertwine(Es, [F|Fs], [F|Gs]) :- intertwine(Es, Fs, Gs), !.

所以你有你的唯一答案。

?- intertwine([1,2],X,[1,a,2,b]).
X = [a, b].

?- 
于 2011-12-02T04:28:37.420 回答