0
votes

I am required to write my own version of all_different in SWI-Prolog. I've written a predicate that returns the same true/false on the inputs I'm giving as all_different does, but I'm having trouble finding online a way to actually apply this predicate as a constraint.. Here is my version of all_different.

distinct([]).
distinct([X|Xs]) :-
  different(X,Xs),
  distinct(Xs).

different(_,[]).
different(X,[Y|Ys]) :-
  (nonvar(X), nonvar(Y) -> X \= Y
   ;
   true
  ),
  different(X,Ys).

I need it to apply to a list of integers and _. Yes, this is the sudoku program project. Sorry if this is a dumb question, but I am still very new to Prolog, and I find it difficult to find sufficient documentation online. Please help!

1

1 Answers

2
votes

You have written a predicate and not a constraint. In a nutshell, predicates either succeed or fail, while constraints only express restrictions on the possible values. Constraints are being recorded by the constraints' solver that does some black magic to simplify them and to indicate ranges of possible values for the variables involved. Hence, you cannot apply your predicate as a constraint.

You can either reconsider the original problem and check whether you need a constraint, or modify your implementation above as follows (I'm using SWI-Prolog):

different(X,[Y|Ys]) :-
  X#\= Y,
  different(X,Ys).

#\= indicates that the disequality expression is a constraint.

You might like to check http://www.swi-prolog.org/man/clpfd.html and specifically differences between all_different/1 and all_distinct/1.