% Old mag steeds door New vervangen worden
mib(Old, New, Old, New).

% Een term blijft enkel behouden als het een attoom is
% (dat is, niet compound), en als het niet Old is
mib(Old, _, Term, Term) :-
    atomic(Term),
    Term \= Old.

% Voor een samengestelde Term
mib(Old, New, Pre, Post) :-
    compound(Pre),
    functor(Pre,  F, N), % Pre heeft naam F en arriteit N
    functor(Post, F, N), % Post is term met zelfde naam (F) en arriteit (N)
    mib(N, Old, New, Pre, Post).

% Extra predicaat om de argumenten te vervangen van een samengestelde term
%
% N = het nr van het argument (strikt positief)
mib(0, _, _, _, _) :- !. % Argument 0 bestaat niet, als we hier komen zijn we klaar.

mib(N, Old, New, Pre, Post) :-
    arg(N, Pre, ArgPre),            % neem het N-de argument
    mib(Old, New, ArgPre, ArgPost), % vertaal het
    arg(N, Post, ArgPost),          % unificeer het met het N-de argument van output
    N1 is N-1,
    mib(N1, Old, New, Pre, Post).   % Herhaal voor argument N-1

example1 :-
    mib(a, b, a, Result),
    write(Result), nl.
example2 :-
    mib(a, b, f(a), Result),
    write(Result), nl.
example3 :-
    mib(b, a, f(g(a, b), h(c, d), i(e, f)), Result),
    write(Result), nl,
    mib(d, c, Result, Result2),
    write(Result2), nl,
    mib(f, e, Result2, Result3),
    write(Result3), nl.

main :-
    example1,
    example2,
    example3.

:- initialization(main).
