karthi
karthi

Reputation: 2911

handling relations in prolog

rel(X,Y) :- dep(X,Y).
rel(X,Y) :- aux(X,Y).
rel(X,Y) :- auxpass(X,Y).
rel(X,Y) :- cop(X,Y).
rel(X,Y) :- conj(X,Y).
rel(X,Y) :- cc(X,Y).
rel(X,Y) :- arg(X,Y).
rel(X,Y) :- subj(X,Y).
rel(X,Y) :- nsubj(X,Y).
rel(X,Y) :- nsubjpass(X,Y).
rel(X,Y) :- csubj(X,Y).
rel(X,Y) :- comp(X,Y).
rel(X,Y) :- obj(X,Y).
rel(X,Y) :- dobj(X,Y).
rel(X,Y) :- iobj(X,Y).
rel(X,Y) :- pobj(X,Y).
rel(X,Y) :- attr(X,Y).
rel(X,Y) :- ccomp(X,Y).
rel(X,Y) :- xcomp(X,Y).
rel(X,Y) :- compl(X,Y).
rel(X,Y) :- mark(X,Y).
rel(X,Y) :- acomp(X,Y).
rel(X,Y) :- agent1(X,Y).
rel(X,Y) :- ref1(X,Y).
rel(X,Y) :- expl(X,Y).
rel(X,Y) :- mod(X,Y).
rel(X,Y) :- advcl(X,Y).
rel(X,Y) :- purpcl(X,Y).
rel(X,Y) :- tmod(X,Y).
rel(X,Y) :- rcmod(X,Y).
rel(X,Y) :- amod(X,Y).
rel(X,Y) :- infmod(X,Y).
rel(X,Y) :- partmod(X,Y).
rel(X,Y) :- num(X,Y).
rel(X,Y) :- number(X,Y).
rel(X,Y) :- appos(X,Y).
rel(X,Y) :- nn(X,Y).
rel(X,Y) :- abbrev(X,Y).
rel(X,Y) :- advmod(X,Y).
rel(X,Y) :- neg(X,Y).
rel(X,Y) :- poss(X,Y).
rel(X,Y) :- possesive(X,Y).
rel(X,Y) :- prt(X,Y).
rel(X,Y) :- det(X,Y).
rel(X,Y) :- prep(X,Y).
rel(X,Y) :- sdep(X,Y).
rel(X,Y) :- xsubj(X,Y).

related(X,Z) :- rel(X,Y), rel(Y,Z).

but in the last relation i want the first "rel" to be different from the next "rel" how to check if they are distinct.. please help

Upvotes: 1

Views: 448

Answers (4)

false
false

Reputation: 10142

@Nir: As a general remark, instead of R1 =..[X,A,B], call(R1) it is often preferable to write call(X,A,B).

Upvotes: 2

Nir
Nir

Reputation: 61

I'm still a prolog newbie, but thought this was a nice problem. My solution has somesimilarities to the answer above, you could use something like this:

related(A,C,List):- member(X,List),
               member(Y,List),
               not(X=Y),
               R1=..[X,A,B],
               R2=..[Y,B,C],
               call(R1),
               call(R2).

You would then call it with isRelated(X,Y):-related(X,Y,[prt,det,.......])

Upvotes: 1

gusbro
gusbro

Reputation: 22585

You have at least two ways. If you are allowed to change the rel/2 predicates you might want to add a new argument to return also the relation involved. Instead of

rel(X,Y):- dep(X,Y).
rel(X,Y):- aux(X,Y).

put something like

rel(X,Y, dep):- dep(X,Y).
rel(X,Y, aux):- aux(X,Y).

and then in related/2 use something like this:

related(X,Z):- rel(X,Y, R1), rel(Y, Z, R2), R1 \= R2.

If you are not allowed to change the rel/2 predicate then you might do it with some other tricks, changing related/2 to something like:

related(X, Z):-
    clause(rel(X,Y), A), 
    clause(rel(Y,Z), B), 
    call(A), call(B), 
    functor(A,Fa,_), functor(B, Fb, _), 
    Fa \= Fb.

Upvotes: 3

Frank
Frank

Reputation: 10571

They are predicates, so they either hold or not. In Prolog you don't distinguish different occurences of them. So "different" can only apply to their arguments, which is easy to achieve by adding that they should be .. well.. different:

rel(X,Y), rel(Y,Z), rel(X,Y) \= rel(Y,Z)

Keep it mind that there are different operators available for "not equal". You'd have to give a clearer definition of what you want to determine the right one.

Edit: I just read the comments that you want the actual relation to differ. You should then somehow transport that relation upwards. Here's a suggestion:

Replace rel/2 by rel/3 like this: rel(X,Y, Type) :- Type = dep, dep(X,Y). Then you can ensure differing relations with rel(X,Y,Type1), rel(X,Y,Type2), Type1 \= Type2.

Upvotes: 3

Related Questions