3

Let allDifferent(A, B, C, D, E, F) be true if and only if ∀i, j in {1, 2, 3, 4, 5, 6}, the i-th and j-th arguments unify if and only if i = j.

Thus allDifferent(3, 1, 4, 1, 5, 9) is false, but allDifferent(3, 1, 4, 2, 5, 9) is true.

How does one implement allDifferent/6 in Prolog?

In particular, is there a way to express it that does not require listing the 6-choose-2 = 15 non-equalities AB, AC, ..., EF (or, rather, their Prolog rendition)?

kjo
  • 33,683
  • 52
  • 148
  • 265
  • 1
    Note that as it stands, your definition has to be `false` all the time! Here is why `∀ X, Y ∈ {A, B, C, D, E, F}` never holds: Consider `X = A, Y = A`! – false Feb 25 '17 at 14:52
  • @false: Nice pick! I'll fix it pronto. BTW, I included `swi-prolog` as a tag because, as I understand it, particular implementations may provide syntactic extensions that are not part of standard Prolog, and one such extension may apply to my question. – kjo Feb 25 '17 at 14:54
  • 1
    SWI is here as good as SICStus, YAP, B, IF, ... So it is not specific to SWI at all. – false Feb 25 '17 at 14:56
  • 1
    Consider `allDifferent(A, A, c, d, e, f)`. It's the same variable, isn't it? Still you expect it to fail. – false Feb 25 '17 at 14:58
  • @false, I'm not sure I understand your last comment. FWIW, the first sentence of my post refers exclusively to the expression `allDifferent(A, B, C, D, E, F)`. – kjo Feb 25 '17 at 15:00
  • 1
    then how do you explain the case I gave? (The point of this is: at first glance, mathematical/logical notation looks more elegant than Prolog, but this is a case where in mathematical notation you would ultimately have to introduce another device like indices to express what can be expressed in Prolog without.) – false Feb 25 '17 at 15:02
  • [Related](http://stackoverflow.com/q/22950154/772868). – false Feb 25 '17 at 15:07
  • 1
    @false: Point taken. I've made a third attempt to get the problem statement right. (I did this before I read your comment, but it seems like this third version goes in the direction you alluded.) – kjo Feb 25 '17 at 15:08
  • @false: BTW, I really appreciate your comments. Thank you! – kjo Feb 25 '17 at 15:08

1 Answers1

2

If you accept that allDifferent receive a list of values (instead of six values) I can propose the following solution

isDifferent(_, []).

isDifferent(X, [H | T]) :-
  X \= H,
  isDifferent(X, T).

allDifferent([]).

allDifferent([H | T]) :-
  isDifferent(H, T),
  allDifferent(T).

-- EDIT --

As suggested by False, you can use dif/2 instead of \= (if your Prolog provide it) so the main isDifferent/2 can be

isDifferent(X, [H | T]) :-
  dif(X, H),
  isDifferent(X, T).

Anyway... hoping this is obvious... but if you really want a allDifferent/6 instead a allDifferent/1 that receive a list, you can define your allDifferent/6 as follows

allDifferent(A, B, C, D, E, F) :-
  allDifferent([A, B, C, D, E, F]). 
max66
  • 65,235
  • 10
  • 71
  • 111