Confusion over functor versus predicate -- and predicates in general

I’m a wretched Prolog beginner who likes to sometimes tackle the hardest books just to see how difficult, how high up in the clouds it can all get. So I’m looking at Logic, Programming and Prolog (2nd edition) from Nilsson and Maluszynski, and right on page 5 I’m in trouble with the idea of a functor versus a predicate:

…Assume now that there is a ternary functor family, a binary functor child and a constant none. The family consisting of the parents Bill and Mary and children Tom and Alice can now be represented by the construction:

family(bill, mary, child(tom,child(alice,none)))

Such a construction is called a compound term.

Wow. So this child expression/form reminds me of Lisp and the linked list cons cell idea, not Prolog. I guess I don’t understand the difference between a functor and a predicate? The way I understand Prolog so far is if Bill and Mary have two immediate offspring Tom and Alice we maybe should have

family(bill, mary, child(tom), child(alice))

as in “Bill, Mary, child(tom), child(alice) is/are a family.” I’m confused about the establishing facts here as well. Do we presume bill and mary were established as parents before, i.e., parents of Tom and Alice?

Trying to firm up my understanding of what a predicate was, I got confused when I read Logical Reasoning: A First Course from Nederpelt and Kamareddine where in Chapter 8 they introduce the concept of predicates saying that with, e.g., 3m + n \gt 3 the truth of such a proposition cannot be determined until we know what m and n are. Good. But then it then says

a predicate like 3m + n \gt 3 only becomes a proposition after the filling of number-values for m and n.

Again, this seems to be a more general concept of a what a predicate is than what I’ve seen in my Prolog first chapter books so far. How can a math formula be a predicate? I researched this to the Wikipedia page on Propositional function, which further confuses with…

…As a mathematical function, A(x) or A(x1, x2, ..., xn), the propositional function is abstracted from predicates or propositional forms. As an example, consider the predicate scheme, “x is hot”…

So what is meant by a “predicate scheme?” It hyperlinks predicate in this sentence to another page that gets into “predicates are interpreted as relations” … and there goes another rabbit hole to fall down.

Any enlightenment on all this would be appreciated.

There is some discussion that might help you here:

I would never choose that representation. Surely this is easier to understand and parse:

family(bill, mary, children([tom, alice])).

“None” could make sense if this were a binary tree - but it isn’t, it’s just a list of children of the parents.

This is assuming that neither parent has children from another partner :grinning:

1 Like

Do you think this is a mistake? After all, it looks just like the cons cell link list from Lisp.

That’s my point - it’s a list, so use a list datatype rather than a more awkward term.

In some Prologs, [a,b,c] is shorthand for a . b . c . [] or '.'(a, '.'(b, '.'(c, []))) (this won’t work with SWI-Prolog). That is, in some Prologs, . is like the cons in Lisp (or the . in Lisp).

So, in a sense, Prolog’s functor is a generalization of Lisp’s “cons cell” – the name isn’t limited to just . and there can be any number of items in the “cell”.

Don’t have the book but the children term in family term might be representing big sister/brother or little sister/brother relations. I agree the family term from book looks weird.

Just found the Ramsey Programming Languages Build Prove Compare supplement (free) and he’s got a chapter on Prolog. He talks about terms, giving these examples

cons(0, cons(1, cons(2, nil)))  
s(s(s(z)))
move(b, table)
lambda(cons(x, nil), x)

i.e., a list containing first three natural numbers; Peano’s 3; moving blocks AI Kindergarten; Scheme code for the identity function. As I’m guessing these are to be understood as functor constructors, then used in facts. Still, as a beginner, it’s confusing a bit. I got this

% Shape functors
point(X, Y).
circle(Center, Radius) :- point(Center), Radius > 0.
rectangle(TopLeft, BottomRight) :- point(TopLeft), point(BottomRight).

% Shape facts
point(p1, 2, 3).
point(p2, -1, 4).
point(p3, 0, 0).
point(p4, 4, 0).

circle(c1, p1, 5).
circle(c2, p2, 2.5).

rectangle(r1, p1, p3).
rectangle(r2, p3, p4).

out of Grok, and this

shape( point(1, 2) ).                % A single point exists.
shape( circle(point(0, 0), 5) ).      % A circle centered at origin with radius 5.
shape( rectangle(point(1, 1), point(4, 3)) ). % A rectangle.
shape( rectangle(point(5, 5), point(7, 7)) ). % Another rectangle (actually a square).
shape( circle(point(10, -2), 3) ).    % Another circle.

out of Gemini, which seems to inline/embed the Grok shape functors – and introduce the shape predicate. So yes, the Grok code seems to say a functor is a abstract data type structure thingy – but then in the form of rules as well. Mind duly blown, i.e., all a bit confusing for this beginner. Any clarification welcome…

Maybe this will help …

Just as in LISP, Prolog calls look like data (“homoiconic”, but see Bicameral, Not Homoiconic).

In LISP, the default semantics for a term is to execute it unless it’s in the context of a QUOTE or is a special form, such as COND.

In Prolog, the default is to quote a term (it can be executed by call/1) unless it’s at the “outer level” of a clause – when writing a clause, we don’t need to write p(X) :- call(q(X,Y)), call(foo(Y))) … we can just write p(X) :- q(X,Y), foo(Y). If the predicate calls contain terms, those terms are not executed – that is, foo(1+2) doesn’t call foo(3); it’s calls foo/1 with the argument +(1,2) (if you want to evaluate 1+2, use is/2).

swi-prolog no longer uses the cons style for lists: SWI-Prolog -- Lists are special

Peano can be convenient - some examples: Newest 'successor-arithmetics+prolog' Questions - Stack Overflow - I believe the fastest conversion between Peano and integer is my code at clpfd - Convert peano number s(N) to integer in Prolog - Stack Overflow

Once the limitations of compound terms are seen, see dicts as an evolution: SWI-Prolog -- Dicts: structures with named arguments

The Prolog community has adopted some weird jargon which makes it a bit beginner unfriendly.
I find the glossary at swi-prolog.org very handy.

A functor is a predicate’s name along with the number of arguments it takes (aka arity), written eg maplist/2

Learning Prolog I got tripped up by quite a lot of the jargon. For instance, in Prolog, predicate means a “row in a database” as opposed to a function that returns a boolean as in most other programing languages.

Another thing bound to trip many novices up is “deterministic” means an aggregator (something that returns one value) whereas “nondeterministic” means a query that can return any number of search results, including none. This is very different from state machines where deterministic means there’s no ambiguity in traversing a graph given the edge labels.

Don’t mix up things. A predicate is still a “procedure” that can succeed of fail. And if we talk about how it is modeled, then a predicate would be a set of rows in a database while the predicate clauses would be the individual rows.

This is somehow reversed. Deterministic means that it can succeed or fail exactly once. Non-deterministic means it can fail or succeed any number of times.

“Predicate”, “deterministic”, and “non deterministic” are in the glossary that you linked.

Thanks for picking up my mixup of nondeterministic and deterministic. I edited my comment to fix it.