6
votes

I am using SICStus Prolog and have a set of facts:

student('John Henry', 'Maths').
student('Jim Henry', 'Maths').
student('John Alan', 'Maths').
student('Alan Smith', 'Computing').
student('Gary Henry', 'Maths'). 

I want to get the shared subject of two students where both students are different, so I got:

sharedSubject(S1, S2, Sub) :- S1 \== S2, student(S1, Sub), student(S2, Sub).

However, when I enter:

sharedSubject('John Henry', F, E).                     

I get F = 'John Henry'. Can someone point out where I am going wrong and what I need to do? Thanks.

2
Both good answers. I picked Paulo's one because of the explanation. I did not think about the instantiation before.Hydar77

2 Answers

8
votes

Use dif/2 instead, or set the \== at the end of the rule - which is not as safe as dif/2. See also:

Difference between X\=Y and dif(X,Y)

What is the logical 'not' in Prolog?

Using \==/2 or dif/2

7
votes

You must move the S1 \== S2 goal to the end as. If you call your sharedSubject/3 predicate with the second argument not instantiated, as in your sharedSubject('John Henry', F, E), the S1 \== S2 goal will always be true:

?- 'John Henry' \== S2.
true.

Also:

?- S1 \== S2.
true.

See the documentation of the standard (\==)/2 built-in predicate in your Prolog system documentation. In a nutshell, unless you want to test if two variables are the same, be sure that both arguments are instantiated when calling this term equality predicate.