1
votes

I'm very new to prolog. I am trying to implement the predicate occurs(Variable, Term) that succeeds if the prolog variable Variable occurs in the prolog term Term, and fails otherwise.

occurs(Variable,Term) :-
    Term =.. List.
occurs(Variable, List).
occurs(Variable,[_|L]) :- 
    occurs(Variable,L).

I tried converting Term into list and then comparing, it always returns true.

any kind of help would be appreciated.

1
it's can be done by calling the goal ground/1 which checks if some predicate doesn't contain vars - Anton Danilov

1 Answers

1
votes

Your occurs/2 check will succeed, regardless what the term is, since you wrote a occurs(Variable, List). fact that will satisfy all values.

Basically there are two cases we need to consider:

  1. the term is a variable, and that variable is equal to the one we are querying; and
  2. the term is a functor, and one of the arguments contains that variable.

We thus can implement this as:

occurs(Variable, Variable) :-
    var(Variable).
occurs(Variable, Term) :-
    \+ var(Term),
    Term =.. [_|Args],
    occurring(Args, Variable).

occurring([H|_], Variable) :-
    occurs(Variable, H).
occurring([_|T], Variable) :-
    occurring(T, Variable).

We can however make use of term_variables/2 [swi-doc], and thus perform a member/2 [swi-doc] to enumerate over the list:

occurs(Variable, Term) :-
    term_variables(Term, Vars),
    member(Variable, Vars).