1

I'd like to simulate the equivalence in Prolog with the properties of being commutative and transitive, here is what I did: equal/2 will be supplying as facts.

symmetricEqual(A,B):- equal(A,B). 
symmetricEqual(A,B):- equal(B,A).

transitiveEqualPath(A,B,_) :- symmetricEqual(A,B).

transitiveEqualPath(B,C,IntermediateNodes) :- 
    symmetricEqual(A,B), 
    \+ member(C,IntermediateNodes), 
    transitiveEqualPath(A,C,[B|IntermediateNodes]), B\==C.

transitiveEqual(A,B) :- transitiveEqualPath(A,B,[]).

But I am running into performance issues with the above solution to try to compute transitiveEqual/2 (it has taken roughly 20mins), I have around 2K symmetricalEqual/2 facts computed pretty fast from equal/2, so it must be the cause of rules for transitiveEqual/2, anybody can suggest any improvement on this?

Thanks very much.

false
  • 10,264
  • 13
  • 101
  • 209
user1935724
  • 554
  • 1
  • 6
  • 18

1 Answers1

0

Courtesy of the approach from here:

symmetricEquals(X,Y) :- equal(X,Y). 
symmetricEquals(X,Y) :- equal(Y,X). 

transitiveEqual(A, B) :-
    % look for an equality path from A to B
    path(A, B, _Path). 

path(A, B, Path) :-
    % build a path from A to B
    path(A, B, [A], Path).

path(A, B, _Acc, [B]) :-
    symmetricEquals(A, B).

path(A, B, Visited, [C|Path]) :-
    symmetricEquals(A, C),
    C \== B,
    \+ memberchk(C, Visited), 
    path(C, B, [C|Visited], Path). 

Note that path/3,4 will backtrack to enumerate all possible paths between any ground or variable A to B. This could be quite expensive if the graph implied by your equal/2 facts is large, contains many disconnected components, and/or you're looking for all combinations.

  • Thanks for the suggestion, however, it did not produce anything after I used your code in SWI-Prolog, after querying about ?-transitiveEqual(A,B). I always got A=B as the output. Any idea? – user1935724 Jan 11 '13 at 18:46
  • Ah, I'd incorrectly assumed you were using the predicates to _test_ for bound values of `A` and `B`, instead of using them to enumerate bindings on backtracking. I'll update my answer to handle both cases. –  Jan 12 '13 at 01:09