You are still thinking in terms of functions
z = f(x,y)
: "f(x,y) returns (is replaced by/ is reduced to) value z ..."
Predicates relate values to other values:
p_f(x,y,z)
: "predicate p_ makes a relation/connection/links values (x,y,z) such that z = f(x,y)"
So to pipeline evaluation (mathematical notation (g°f)(x,y) )
g(f(x,y))
you have to write (not respecting the Prolog convention that 'variables' are written in uppercase here):
p_f(x,y,a),p_g(a,b)
And think in terms of information flowing into this expression through p_f(x,y,_)
, getting transferred to p_g/2
via p_f(_,_,a), p_g(a,_)
and flowing out of the expression via p_g(a,b)
.
And p_f/3 or p_g/2 will fail (return false, not in any of their arguments, but as a whole) if they are unable to relate their arguments and there will be no result.
Using predicates has the advantage that for p_f(x,y) you can request x if y is known, y if x is known, or pairs of valid (x,y) (as long as that is computationally possible and the predicate has been correctly coded). Or for a predicate add/3
:
- add(2,3,X) -> X = 5
- add(2,3,5) -> true
- add(X,3,5) -> X = 2
- add(1,3,5) -> false
- add(X,Y,5) -> X = 2, Y = 3; X = 3, Y = 2; ... ad infinitum
- add(X,Y,Z) -> same as above only even more unrestrained
See also: Prolog ~ Splitting a number into a list