Search code examples
prologswi-prologsicstus-prolog

Proper subsumes_term/2 in SWI-Prolog?


Lets assume SICStus Prolog is the benchmark for the implementation of certain predicates, even ISO core standard predicates. Especially in connection with attributed variables.

I then find these examples here. It's from SICStus 4 and not only SICStus 3:

?- when(nonvar(X), X=a), subsumes_term(X, b), X = a.
X = a ? 
yes

?- when(nonvar(X), X=a), subsumes_term(X, b), X = b.
no

When doing the same in SWI-Prolog I get different results:

?- when(nonvar(X), X=a), subsumes_term(X, b), X = a.
false.

?- when(nonvar(X), X=a), subsumes_term(X, b), X = b.
false.

How would one implement a workaround in SWI-Prolog? ROKs METUTL.PL probably doesn't help, since it uses normal unification.


Solution

  • Here is a suggestion (not actually tested in SWI-prolog):

    subsumes_term_sicstus(X, Y):-
        copy_term(X-Y, XC-YC, _),
        subsumes_term(XC, YC).
    

    The idea is simply to copy the two structures then use the original predicate on the copies, which do not have attributes or frozen goals attached.

    According to the documentation, it appears that copy_term/2 copies the attributes of attributed variables in SWI-prolog (but not in SICStus), so I am using copy_term/3 instead here. I see that there is also a copy_term_nat/2, which might be used instead.