The SWI-prolog docs heavily recommend against using setarg/3:
This predicate may be used for destructive assignment to terms, using them as an extra-logical storage bin. Always try hard to avoid the use of setarg/3 as it is not supported by many Prolog systems and one has to be very careful about unexpected copying as well as unexpected noncopying of terms.
I'm not sure I understand, what is "extra-logical" about setarg/3? I understand that things such as cuts and findnsols are extra-logical because they rely on implicit knowledge of the search order Prolog uses, what's so bad about changing an argument of a term?
It is easy to see that using setarg/3 violates the most basic declarative properties we expect from predicates.
For example, consider the query:
?- T = f(a), T = f(b). false.
Declaratively, we expect that adding a constraint (i.e., goal) can at most reduce, certainly never extend, the set of solutions. Right?
Right??
Well, consider:
?- T = f(a), setarg(1, T, b), T = f(b). T = f(b).
So, adding a constraint has generalized the query: It previously failed, and now succeeds (unconditionally).
In everyday tasks, this is analogous to a situation like:
A: I would like to order a dessert please.
B: I am sorry, we are out of desserts.
A: OK, then I would like to order a dessert and a coffee please.
B: Here you are: A dessert and a coffee.
Surely most people would find such a conversation, if it were to occur in an actual restaurant, highly unusual.
Hence, setarg/3 is called an impure predicate: Monotonic first-order reasoning cannot be applied to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With