如何使用地/1?

发布于 2024-12-19 14:50:17 字数 578 浏览 2 评论 0原文

我是 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 是如何工作的,以及如何使用它来检查特定参数的实例化,并使用它来不让代码检查不存在的答案?

I'm a complete beginner with Prolog and I wanted to know how to use ground/1.

At the moment I have this code:

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

But when I try to call this in the shell:

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

I get the right answer X=[a,b], but the query doesn't end, as if it thinks there is another answer left. So, I press ";" and I get "false" as output. I read in another question's answer that I should use ground/1 to check whether the third list is already completely instantiated to handle the case.

Thing is, being a complete beginner, I have no clue how to do that. So is there someone kind enough to explain to me how ground works and how I can use it to check instantiation of a specific parameter and use that to not have the code check for an answer that isn't there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吾家有女初长成 2024-12-26 14:50:17

这种行为完全没问题。有时,Prolog 能够确定没有进一步的解决方案,有时则不能。细节与所描述的内容没有区别。考虑一下:

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

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

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

That behaviour is completely OK. Sometimes, Prolog is able to figure out that there is no further solution, and sometimes not. The details do not make a difference to what is described. Consider:

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

Here, it is evident to us that 2 = 3 is not a solution, still Prolog asks us to continue.

BTW, instead of ; you can also press SPACE to get the next solution.

萌面超妹 2024-12-26 14:50:17

正如虚假所说,这种行为确实可以。 ground/1 谓词实际上与该问题无关。

不让代码检查不存在的答案?

如果我正确回答了你的问题,Cut 在这里可能会有所帮助。

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].

?- 

Like false said, this behavior is really ok. ground/1 predicate isn't related to that question actually.

to not have the code check for an answer that isn't there?

Cut can be helpful here, if I get your question right.

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

So you've got your single answer.

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

?- 
以可爱出名 2024-12-26 14:50:17

代替 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 get (希望)以膨胀数据的名称进行实例化。

Instead of ground/1, to check the instatiation of a parameter you should consider using var/1 (or the related nonvar/1). var/1 it's the fundamental metapredicate that extends the power of Prolog beyond what's know as the pure subset of language. It allows to reason about the program itself, selecting appropriate behaviour depending on the 'state' of such fundamental entities as variables.

A (very) simple use of these metapredicate, from a practical programming POV, allows to implement default values for specific parameters: for instance

%%  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) )
              ).

if we call gunzip('file.gz', F), F get instanced (hopefully) with the name of inflated data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文