Hiere is an adaptation of my answer of the previous question. It shows the use of when/2 instead of freeze/2. freeze/2 only follows a nonvar/1 condition on the first argument. when/2 can follow more complex conditions.
lead(X, Y) :- var(X), !, freeze(X, lead(X,Y)).
lead([X|Y], Z) :- \+ ground(X), !, when(ground(X), lead([X|Y],Z)).
lead([s(s(0))|X], Y) :- !, lead(X, Y).
lead(X, X).
Here are some example runs, I am picking similar examples as in my answer I gave to the previous answer. We see how when/2 adapts its own condition when the list argument gets gradually instantiated:
?- lead([s(0),s(s(0)),s(s(0)),s(0)],Y).
Y = [s(0), s(s(0)), s(s(0)), s(0)].
?- lead([s(s(0)),s(s(0)),s(s(0)),s(0)],Y).
Y = [s(0)].
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(_).
X = s(_G3686),
when(ground(_G3686), lead([s(_G3686), s(s(0)), s(s(0)), s(0)], Y)).
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(0).
X = s(0),
Y = [s(0), s(s(0)), s(s(0)), s(0)].
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(s(_)).
X = s(s(_G3713)),
when(ground(_G3713), lead([s(s(_G3713)), s(s(0)), s(s(0)), s(0)], Y)).
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(s(0)).
X = s(s(0)),
Y = [s(0)].
freeze/2 and when/2 are corouting primitives. Their pureness is well documented in the literature. According to this source the first Prolog system with corouting was Prolog-II with its geler/2 primitive. The source also mentions the importance of corouting to bootstrap constraint solvers.
Assume pureness is tested with commutativity, here is a sample test:
?- lead([X,s(s(0)),s(s(0)),s(0)],Y), X=s(s(0)).
X = s(s(0)),
Y = [s(0)].
?- X=s(s(0)), lead([X,s(s(0)),s(s(0)),s(0)],Y).
X = s(s(0)),
Y = [s(0)].
But freeze/2 and when/2 not necesserely guarantee completeness, as I already wrote in my first answer we might need to do something 'at the end'. Means after a query we might have a set of floundering goals. In constraint programming we would then start labeling.
Also freeze/2 and when/2 cannot find early fails by combining goals, as constraint solvers can do.
The above eexample runs with SWI-Prolog without some import, and in Jekejeke Prolog use the Minlog Extension and import library(term/suspend).