# Confusion over functor versus predicate -- and predicates in general

**URL:** <https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945>\
**Category:** General\
**Created:** [April 17, 2025, 4:02pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945 "2025-04-17T16:02:43Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![borgauf](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/borgauf/32/7116_2.png) [@borgauf](https://swi-prolog.discourse.group/u/borgauf)\
**Post date:** [April 17, 2025, 4:02pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/1 "2025-04-17T16:02:43Z")

</div>

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](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/Predicate_(logic)) 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.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [April 17, 2025, 5:10pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/2 "2025-04-17T17:10:32Z")

</div>

There is some discussion that might help you here:

> [@How does prolog tell the difference between atoms and zero arity predicates?](https://swi-prolog.discourse.group/t/how-does-prolog-tell-the-difference-between-atoms-and-zero-arity-predicates/8903):
>
> true is a predicate, but ?- atom(true). true. ?- functor(true, X, 0). X = true. How can it be atom and functor at the same time? From here, they [should be different entities](https://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&pageid=lpn-htmlse5). Can you explan me what the functor really is? Are there strict Prolog language specification which I can refer to?

> [@What is meant by "meta-level" in logic programming?](https://swi-prolog.discourse.group/t/what-is-meant-by-meta-level-in-logic-programming/7717/7):
>
> Yes, but call/n can be defined as a first-order thing (just add a corresponding call/n clause for every predicate in the program), so I don’t think of it as something special. Others might disagree. “Thunk” is, I suppose an old-fashioned word for what is now called “closure” (although the definition of “closure” is somewhat variable, it seems) – basically, a pointer to code plus some environment. See also [delimited continuations](https://www.swi-prolog.org/pldoc/man?section=delcont), which I don’t fully understand. So, it might be useful to have…

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [April 17, 2025, 6:18pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/3 "2025-04-17T18:18:38Z")

</div>

> [@borgauf](#):
>
> family(bill, mary, child(tom,child(alice,none)))

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

```prolog
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 😀

---

<div class="post-metadata">

**Author:** ![borgauf](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/borgauf/32/7116_2.png) [@borgauf](https://swi-prolog.discourse.group/u/borgauf)\
**Post date:** [April 18, 2025, 2:47am UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/4 "2025-04-18T02:47:47Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [April 18, 2025, 4:57am UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/5 "2025-04-18T04:57:27Z")

</div>

> [@borgauf](#):
>
> list

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

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [April 18, 2025, 6:00am UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/6 "2025-04-18T06:00:14Z")

</div>

> [@borgauf](#):
>
> it looks just like the cons cell link list from Lisp

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

---

<div class="post-metadata">

**Author:** ![PasiK](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pasik/32/84_2.png) [@PasiK](https://swi-prolog.discourse.group/u/PasiK)\
**Post date:** [April 18, 2025, 6:51am UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/7 "2025-04-18T06:51:10Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![borgauf](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/borgauf/32/7116_2.png) [@borgauf](https://swi-prolog.discourse.group/u/borgauf)\
**Post date:** [April 18, 2025, 5:07pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/8 "2025-04-18T17:07:02Z")

</div>

Just found the Ramsey _Programming Languages Build Prove Compare_ [supplement](https://www.build-prove-compare.net/supplement-2022-10-11.pdf) (free) and he’s got a chapter on Prolog. He talks about _terms_, giving these examples

```prolog
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

```prolog
% 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

```prolog
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…

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [April 18, 2025, 5:35pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/9 "2025-04-18T17:35:40Z")

</div>

Maybe this will help …

Just as in LISP, Prolog calls look like data (“homoiconic”, but see [Bicameral, Not Homoiconic](https://parentheticallyspeaking.org/articles/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).

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [April 18, 2025, 6:57pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/10 "2025-04-18T18:57:10Z")

</div>

> [@borgauf](#):
>
> `cons`

swi-prolog no longer uses the `cons` style for lists: [SWI-Prolog -- Lists are special](https://www.swi-prolog.org/pldoc/man?section=ext-lists)

Peano can be convenient - some examples: [Newest 'successor-arithmetics+prolog' Questions - Stack Overflow](https://stackoverflow.com/questions/tagged/successor-arithmetics+prolog) - 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](https://stackoverflow.com/a/75645668/)

Once the limitations of compound terms are seen, see _dicts_ as an evolution: [SWI-Prolog -- Dicts: structures with named arguments](https://www.swi-prolog.org/pldoc/man?section=bidicts)

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [April 19, 2025, 10:15am UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/11 "2025-04-19T10:15:46Z")

</div>

The Prolog community has adopted some weird jargon which makes it a bit beginner unfriendly.  
I find the [glossary](https://www.swi-prolog.org/pldoc/man?section=glossary) at [swi-prolog.org](http://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 “matching rows”, including none. This is very different from state machines where deterministic means there’s no ambiguity in traversing a graph given the edge labels.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [April 19, 2025, 11:17am UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/12 "2025-04-19T11:17:24Z")

</div>

> [@joeblog](#):
>
> 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.

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.

> [@joeblog](#):
>
> Another thing bound to trip many novices up is “nondeterministic” means an aggregator (something that returns one value) whereas “deterministic” 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.

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.

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [April 19, 2025, 11:28am UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/13 "2025-04-19T11:28:18Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)\
**Post date:** [April 26, 2025, 1:23pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/14 "2025-04-26T13:23:53Z")

</div>

> [@brebs](#):
>
> `family(bill, mary, children([tom, alice])).`

I don’t think that’s right. I think this:

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

```

Is supposed to model “alice is the child of tom who is the child of bill and mary”.

Otherwise tom and alice would both be on the same level as each other instead of alice being a child term nested inside the tom child term.

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [April 26, 2025, 1:49pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/15 "2025-04-26T13:49:25Z")

</div>

> [@stassa.p](#):
>
> supposed to model

The OP specifies:

> [@borgauf](#):
>
> The family consisting of the parents Bill and Mary and children Tom and Alice

On the other point:

> [@stassa.p](#):
>
> ```prolog
> family(bill, mary, child(tom,child(alice,none)))
> 
> ```
> 
> Is supposed to model “alice is the child of tom who is the child of bill and mary”.

It could… but wasn’t asked for, and is rather unintuitive and inelegant - what’s the advantage of such a representation? How would a compound term, ending in `none`, be better than a list? Considering database normalisation, could use instead (keeping with the original data, for this example) e.g.:

```prolog
mother_spouse(mary, bill).

mother_child(mary, tom).
mother_child(mary, alice).

```

---

<div class="post-metadata">

**Author:** ![stassa.p](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stassa.p/32/712_2.png) [@stassa.p](https://swi-prolog.discourse.group/u/stassa.p)\
**Post date:** [April 26, 2025, 2:04pm UTC](https://swi-prolog.discourse.group/t/confusion-over-functor-versus-predicate-and-predicates-in-general/8945/16 "2025-04-26T14:04:27Z")

</div>

> [@brebs](#):
>
> The OP specifies:

You’re right, I didn’t notice that. I agree that the nested binary tree notation is a bit shit and I would never do that myself, I hate having to strain my eyes to read my own code.It’s one of those things where you think, “sure, you can do that in Prolog but… why?”.

Ideally you wouldn’t represent a whole family tree (however shallow) in one term anyway. More or less like you show above.
