سؤال

The pipe operator in prolog returns one or more atomic Heads and a Tail list.

?- [a,b,c] = [a,b|[c]].
true.

Nesting multiple pipes in a single match can be done similar to this:

?- [a,b,c] = [a|[b|[c]]].
true.

What does the statement [a|b|c] infer about a, b and c?

EDIT

So far, all I can deduce is:

?- [a,b,c] = [a|b|c].
false.

I am more interested in any techniques to find the answer rather than to answer this borderline useless question.

EDIT2
I'm clearly not too familiar with prolog, a simple assignment answered my question...

?- R = [a|b|c].
R = [a| (b'|'c)].

What exactly is going on with (b'|'c)?

هل كانت مفيدة؟

المحلول

Since I'm your lecturer I, here's my answer.
(Oh, and I can confirm that this isn't homework, it's related to the practice exam).

The syntax [a|b|c] actually doesn't seem to be standard Prolog, and some implementations interpret it differently. (Had I known this I might not have used it.)

Some interpret it as [a|[b|c]]. (As I intended.)

But with SWI Prolog (and probably others):

?- [a|b|c] = [a|[b|c]].
false.

The (b '|' c) is actually constructed using '|' rather than '.' as a list would be. So, the the second | is not interpreted as being part of constructing a list at all.

To confirm this, the following succeeds:

   ?- X=(b|c), [a|b|c] = [a|X].
   X = (b'|'c) .

The '|' here seems to be a another binary operator on terms just like '.'.

Instead of [a|b|c] the standard in Prolog is to use [a,b|c].

(I only decided to use [a|b|c] in Programming Paradigms because it more directly relates to the notation a::b::c from F#, and we only saw a tiny glimpse of Prolog. In future I guess I'll relate to [a|[b|c]] and then give [a,b|c] as an abbreviation.)

نصائح أخرى

It isn't a statement, it's a term, and it doesn't imply anything at all about a, b or c. It just constructs an improper list.

To elaborate: The [|] syntax is actually syntactic sugar for the .() operator. Lists are internally constructed via '.'(a,[]), but since that becomes extremely tedious to type right away, you are allowed to write [a] instead. So the . operator is supposed to take a thing and a list and then contructs a longer list, but since there is no typing, nobody prevents you from applying it to two atoms, or any other pair of things. The result is a structure on which some list operations succeed and others fail. This is sometimes useful (think binary trees), but not as common as lists, therefore there is no special read syntax for it.

(Much the same happens with the cons operator in Lisp; if you google "improper list" you are liable to get many more results about Lisp, but the principle is exactly the same.)

Within ISO-Prolog, [a|b|c] is invalid syntax. And in the meantime also within SWI. It seems you used an older version. Some Prolog systems gave this term some interpretation. Alas, they all differed in the very precise way how they interpreted that term. Some as [(a'|'b)|c] or [a|(b'|'c)] or [a|(b;c)] ... well, you get it.

Related to this is the use of the bar as an infix operator ('|')/2.

With ISO/IEC 13211-1:1995/Cor.2:2012, Technical Corrigendum 2, published 2012-02-15 the use of bar | as infix operator is now precisely defined. Prior to it, | had to be quoted. Here is its draft.

Now, '|' can be defined as an infix operator but only with a priority above 1000. In this manner otherwise ambiguous cases as [a|b|c] remain syntactically invalid, but uses of | for DCGs and CHR are valid.

If you want to learn syntax by trying it out, the best is to use writeq/1 and write_canonical/1.

The most conforming system w.r.t ISO-Prolog syntax is GNU Prolog.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top