2

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?

false
  • 10,264
  • 13
  • 101
  • 209
user1008820
  • 181
  • 1
  • 2
  • 9

3 Answers3

2

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.

false
  • 10,264
  • 13
  • 101
  • 209
0

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

?- 
0

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.

CapelliC
  • 59,646
  • 5
  • 47
  • 90