Term Inspection & Construction

?- functor(point(1, 2), Name, Arity).    % Name = point, Arity = 2
?- functor(T, point, 3).                 % T = point(_, _, _)
?- arg(2, point(1, 2), A).               % A = 2
?- point(1, 2) =.. L.                    % L = [point, 1, 2]   ("univ")
?- T =.. [foo, a, b].                    % T = foo(a, b)
?- copy_term(f(X, Y, X), C).             % C = f(_A, _B, _A) — fresh variables
?- term_variables(f(X, g(Y, X)), Vs).    % Vs = [X, Y]
?- setarg(1, T, new).                    % destructive (backtrackable) — use sparingly
?- nb_setarg(1, T, new).                 % non-backtrackable
?- term_to_atom(f(X, b), A).             % A = 'f(_123,b)'
?- term_string(T, "foo(bar)").           % parse a string into a term
?- numbervars(f(X, Y), 0, End), print(f(X, Y)).   % f(A, B)
?- subsumes_term(f(_), f(a)).            % true: general subsumes specific
?- term_size(f(a, b), S).
?- tab(4), write(x).

15.1 Generic term traversal

% Count atoms anywhere inside a term
count_atoms(T, 1) :- atom(T), !.
count_atoms(T, 0) :- \+ compound(T), !.
count_atoms(T, N) :-
    T =.. [_|Args],
    foldl([A, N0, N1]>>(count_atoms(A, C), N1 is N0 + C), Args, 0, N).

% Substitute one subterm for another
subst(Old, New, Old, New) :- !.
subst(Old, New, T, R) :- compound(T), !, T =.. [F|As], maplist(subst(Old, New), As, Rs), R =.. [F|Rs].
subst(_, _, T, T).