Как запустить setarg_with_occurs_check/3 в Прологе?

Как можно было бы начать и начать setarg_with_occurs_check/3в
Прологе. Кажется, что в Prolog есть два способа создания циклических структур данных.
Это может сделать не только унификация, но и setarg / 3:

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

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

Допустим, я хочу аналог unify_with_occurs_check/2 для
setarg/3. Как можно было бы реализовать то же самое?

(Кстати, в некоторых системах Prolog setarg / 3 иногда
называется change_arg / 3, а у некоторых его вообще нет)

1 ответ

Я думаю, вы можете использовать предикат ISO acyclic_term/1. Таким образом, в SWI-Prolog вы можете определить:

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

Примеры:

      ?- 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.
Другие вопросы по тегам