Siminho
Siminho

Reputation: 119

Prolog: Why is there a vertical line and underscore in the output [x,y|_]?

I don't understand the output of the following example:

isSpaceCode(32).
makeTerms([], Y, [Y|_].
makeTerms([A|X], Y, Terms) :- 
  \+(isSpaceCode(A)),
  char_code(Out, A),
  atom_concat(Y, Out, Neu),
  makeTerms(X, Neu, Terms).
makeTerms([A|X], Y, [Y|Terms]) :- 
  isSpaceCode(A), 
  makeTerms(X, '', Terms).

When I do the call makeTerms("Foo Too", '', Z) I get the output Z = ['Foo', 'Too'|_]. Why is there a vertical line and an underline after the right output and what does is mean?

Upvotes: 1

Views: 681

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477309

Because your makeTerms will, when the list is exhausted, construct an [Y|_], so a "cons" with a variable as tail.

In case the list is exhausted, you should wrap the thus far yielded list in a singleton list:

makeTerms([], Y, [Y]).
makeTerms([A|X], Y, Terms) :- 
  \+ isSpaceCode(A),
  char_code(Out, A),
  atom_concat(Y, Out, Neu),
  makeTerms(X, Neu, Terms).
makeTerms([A|X], Y, [Y|Terms]) :- 
  isSpaceCode(A), 
  makeTerms(X, '', Terms).

You however might want to check if the atom is empty, since in that case, you probably want to yield the empty list:

makeTerms([], '', []).
makeTerms([], Y, [Y]) :-
    Y \= ''.
makeTerms([A|X], Y, Terms) :- 
  \+ isSpaceCode(A),
  char_code(Out, A),
  atom_concat(Y, Out, Neu),
  makeTerms(X, Neu, Terms).
makeTerms([A|X], Y, [Y|Terms]) :- 
  isSpaceCode(A), 
  makeTerms(X, '', Terms).

It might be better here to make two predicates: one where there is an atom that is constructed (thus far), and one without. By decoupling the two, you can construct more simple predicates, and use mutual recursion.

Upvotes: 1

Related Questions