transitive closure over a symmetric relation in prolog

前端 未结 2 799
挽巷
挽巷 2021-01-13 23:33

I am a prolog beginner and I want to create the \"brother\" relation.

The relation should be symmetric as in if brother(alin, alex) is true,

相关标签:
2条回答
  • 2021-01-14 00:12

    You can write the brother relation like this (exactly like the transitive definition)

    s_brother(X, Y) :- r_brother(X, Y);r_brother(Y, X).
    
    brother(X,Y) :- s_brother(X, Y).
    brother(X,Y) :- s_brother(X, Z),s_brother(Z, Y),X\=Y.
    

    which mean X is brother of Y if he is a symmetric brother, or they have a brother in common, and add the condition that they are different.

    try adding to X\=Y to your code to get rid of "alin" as a solution.

    0 讨论(0)
  • 2021-01-14 00:13

    I think the basic problem is that you do not check if L2 is already found in the first clause of t_brother/3. And the initial L1 should be added to the list in brother/2:

    brother(L1, L2) :-
      t_brother(L1, L2, [L1]).                   % <-- [L1] instead of []
    
    t_brother(L1, L2, IntermediateNodes) :-
      s_brother(L1, L2),
      \+ member(L2, IntermediateNodes).          % <-- added this check
    
    t_brother(L1, L2, IntermediateNodes) :-      % <-- this clause is unchanged
      s_brother(L1, L3),
      \+ member(L3, IntermediateNodes),
      t_brother(L3, L2, [L3 | IntermediateNodes]).
    

    You can still shorten the solution by using a disjunction:

    t_brother(L1, L2, IntermediateNodes) :-
      s_brother(L1, L3),
      \+ member(L3, IntermediateNodes),
      ( L2=L3
      ; t_brother(L3, L2, [L3 | IntermediateNodes])).
    
    0 讨论(0)
提交回复
热议问题