This is perhaps the most trivial implementation
Depends on the point of view: consider
count(L,C) :- length(L,C).
Shorter and more functional. And it also works for your use case.
change
library CLP (FD) allows
:- use_module(library(clpfd)). count([], 0). count([_|B], T) :- U #>= 0, T #= U + 1, count(B, U). ?- count(X,3). X = [_G2327, _G2498, _G2669] ; false.
(further) by replying to comments
It was clearly sarcasm
No, sorry for that impression. It was an attempt to give you a synthetic answer to your question. All the details of the implementation of length / 2 - indeed much longer than your code, were carefully weighed to give us a common and efficient building block.
There must be some general concept
I would call the (complete) Prologue such a general concept. From the very beginning, Prolog requires us to solve computational problems that describe the relationship between predicate arguments. Once we have described our relationship, we can query our “knowledge database,” and Prolog tries to list all the answers in a specific order.
High-level concepts such as unification and backtracking are the keys to this model.
Now I think you're looking for second-order constructs, such as var / 1, that allow us to reason about our predicates. Such constructs cannot be written in (pure) Prolog, and a growing school of thought should avoid them because they are quite difficult to use. So I posted an alternative using CLP (FD) that effectively protects us in some situations. In this matter, the specific context, he actually gives us a simple and elegant solution.
I am not trying to reimplement length
Well, I know about this, but since count / 2 aliases length / 2, why not explore the reference model? (The watched source was used on the SWI-Prolog website, but it seems to be broken right now)