

The specification should probably be
setarg(+Arg, !Term, +Value)
Position is 1-based and the predicate fails if Value is out-of-bounds:
?- X=f(a,b,c,d), setarg(0,X,foo). false. ?- X=f(a,b,c,d), setarg(1,X,foo). X = f(foo, b, c, d). ?- X=f(a,b,c,d), setarg(4,X,foo). X = f(a, b, c, foo). ?- X=f(a,b,c,d), setarg(5,X,foo). false.
Otherwise, works as expected:
?- X=f(a,Y,Y,d), setarg(2,X,Y). X = f(a, Y, Y, d).
?- X=f(a,Y,Y,d), setarg(2,X,f(Y)). X = f(a, f(Y), Y, d).
We need more information about unexpected copying as well as unexpected noncopying of terms.