Stack overflow while defining transitive relation and symmetric relation in Prolog

59 views Asked by At

I am trying to define rules that make relation brother/2 symmetric and transistive as follows -

brother(X,Y):-brother(Y,X).
brother(X,Y):-brother(X,Z),brother(Z,Y).

I have the following facts -

brother(tom,jerry).
brother(jerry,jeff).

I then create a query

?- brother(tom,jeff).

I expect the interpreter to evaluate to True but get the following output

ERROR: Stack limit (1.0Gb) exceeded
ERROR:   Stack sizes: local: 1.0Gb, global: 58Kb, trail: 0Kb
ERROR:   Stack depth: 7,062,903, last-call: 0%, Choice points: 7,062,896
ERROR:   In:
ERROR:     [7,062,903] user:brother(jeff, tom)
ERROR:     [7,062,902] user:brother(tom, jeff)
ERROR:     [7,062,901] user:brother(jeff, tom)
ERROR:     [7,062,900] user:brother(tom, jeff)
ERROR:     [7,062,899] user:brother(jeff, tom)
ERROR: 
ERROR: Use the --stack_limit=size[KMG] command line option or
ERROR: ?- set_prolog_flag(stack_limit, 2_147_483_648). to double the limit.
   Exception: (7,058,422) brother(tom, jeff) ? creep
   Exception: (7,058,421) brother(jeff, tom) ? creep
   Exception: (7,058,420) brother(tom, jeff) ? creep
   Exception: (7,058,419) brother(jeff, tom) ? 

Any ideas to circumvent this ?

(Note: The prolog implementation I am using is swiprolog)

1

There are 1 answers

0
false On

Using closure/3:

sym(G_2, A, B) :-
   (  call(G_2, A, B)
   ;  call(G_2, B, A)
   ).

brother(tom,jerry).
brother(jerry,jeff).

?- closure(sym(brother), A, B).
   A = tom, B = jerry
;  A = tom, B = jeff
;  A = jerry, B = jeff
;  A = jerry, B = tom
;  A = jeff, B = jerry
;  A = jeff, B = tom
;  false.