A free variable is a variable that does not yet have a value. A linked variable is one that has (and in the absence of backtracking after a variable receives a value it is linked to it forever, it is not possible to assign another value to it).
Example:
?- member(X, Y).
Y = [X|_G3168] .
By calling member/2
, so much X
how much Y
were free variables. After the call, Y
is now linked to a list (started with X
and finished with anything). X
continues free, so that 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 what it is (a list with at least one element) the execution will fail (triggering a backtrack):
?- member(X, Y), !, Y = 42.
false.
(the cut is to avoid an infinite loop because member/2
would continue to generate new Y
s, failing and returning)
Note that like the contents of Y
contains free variables, you can unify it with another compatible list. You wouldn’t be changing your value - the list would remain the same. Only its elements (head and tail) that before were free and will cease to be:
?- member(X, Y), Y = [1,2,3,4,5].
X = 1,
Y = [1, 2, 3, 4, 5] .
(at that point you could ask for "more solutions" to get the other values of X
, but in the end it would also fall into an infinite loop).
Checking whether a variable is free or not
If you want to know whether a variable has a value or not, it is no use comparing it with something else - since comparing it will end up unifying it with that thing and therefore making it turned on. Instead, use the predicates var/1
and nonvar/1
which are successful if the variable is free/on respectively:
?- member(X, Y), var(X), nonvar(Y).
Y = [X|_G4611629] .
?- member(X, Y), !, var(Y).
false.
?- member(X, Y), !, nonvar(X).
false.