A free variable is a variable that does not yet have a value. A bound is one that has (and in the absence of backtracking after a variable receives a value it is bound to it forever, not being able to assign it another value).
Example:
?- member(X, Y).
Y = [X|_G3168] .
When calling member/2
, both X
and Y
were free variables. After the call, Y
is now linked to a list (started with X
and finished with anything). X
is still free, so you can assign it the value you want:
?- member(X, Y), X = 42.
X = 42,
Y = [42|_G3116] .
While Y
is no longer free, if you try to unify it with something other than it is (a list with at least one element) the execution will fail (causing a backtrack ) :
?- member(X, Y), !, Y = 42.
false.
(The cut is to avoid an infinite loop, since member/2
would continue to generate new Y
s, failing and returning)
Note that because content of Y
contains free variables, you can unify it with another list that is compatible with it. You would not be changing your value - the list would remain the same. Only its elements (head and tail) that were previously free and will cease to be:
?- member(X, Y), Y = [1,2,3,4,5].
X = 1,
Y = [1, 2, 3, 4, 5] .
(at this point you could ask for "more solutions" to get the other values of X
, but in the end would also fall into an infinite loop).
Checking whether or not a variable is free
If you want to know whether or not a variable has a value, it's no use comparing it with something else - since comparing it will eventually unify it with that thing and therefore bind it. Instead, use the var/1
and nonvar/1
faults that succeed if the variable is free / bound respectively:
?- member(X, Y), var(X), nonvar(Y).
Y = [X|_G4611629] .
?- member(X, Y), !, var(Y).
false.
?- member(X, Y), !, nonvar(X).
false.