How bootstrap setarg_with_occurs_check/3 in Prolog?

54 views Asked by At

How would one go about and bootstrap setarg_with_occurs_check/3 in
Prolog. It seems Prolog has two ways to create cyclic data structures.
Not only unification can do that, but also setarg/3:

/* SWI-Prolog 8.3.26 */
?- X = f(X).
X = f(X).

?- X = f(0), setarg(1,X,X).
X = f(X).

Lets say I want the analogue of unify_with_occurs_check/2 for
setarg/3. How would one go about and implement the same?

(BTW In some Prolog systems setarg/3 sometimes goes by the
name change_arg/3, and some even don't have it at all)

1

There are 1 answers

0
slago On

I think you can use the ISO predicate acyclic_term/1. Thus, in SWI-Prolog, you can define:

setarg_with_occurs_check(Arg, Term, Value) :-
    setarg(Arg, Term, Value),
    acyclic_term(Term).

Examples:

?- X = f(0), setarg_with_occurs_check(1,X,Y).
X = f(Y).

?- X = f(0), setarg_with_occurs_check(1,X,X).
false.

?- X = f(X), Y = g(Z), setarg_with_occurs_check(1,Y,X).
false.