Re: [eclipse-clp-users] List to arrays

From: Joachim Schimpf <jschimpf_at_...311...>
Date: Fri, 1 Jul 2016 13:02:46 +0100
On 30/06/16 15:01, Annick Fron wrote:
> Hi,
>
> 	Your mail helped me a lot.
> 	I rewrote the program , but got some problems to define that all  columns must be different.
 > I wrote something, but which gives me sometimes the same columns.
> What is wrong with it ?
...
>
> differentcols(M,Nb,N):-
>     (for(I,1,Nb),param(M,N,Nb) do
>         Col1 is M[I],
>         Iplus1 is I + 1,
>         (for(J,Iplus1,Nb),param(M,Col1,N) do
>             Col2 is M[J],
>             not(equalcol(Col1,Col2)))).
>
> equalcol(X,Y,N):-dim(X,[N]),dim(Y,[N]),X#::0..1, Y#::0..1,
> ( for(J,1,N),param(X,Y) do A is X[J], B is Y[J], A#=B).


Two problems:

1. you are confusing rows and columns (M[I] is the Ith row)
2. you cannot use Prolog negation (not/1 or \+/1) to negate constraints


You could do the following:

diff_cols(A) :-
         dim(A, [M,N]),
         ( for(J,1,N-1), param(A,M,N) do
             ( for(K,J+1,N), param(A,M,J) do
                 % compare columns J and K
                 ( for(I,1,M), foreach(B,Bs), param(A,J,K) do
                     B #= (A[I,J] #\= A[I,K])
                 ),
                 sum(Bs) #> 0    % at least one different element
             )
         ).


However, depending on your actual problem, it might be better to
have a constraint that requires not only that the columns are different,
but that they are lexicographically ordered.  This will eliminate
symmetric solutions, i.e. solutions that differ only in that the
columns are permuted.  Of course this is only correct if your problem
is indeed symmetric with regard to the column order.

To impose such an order (which subsumes the difference constraint), use:

ordered_cols(A) :-
         dim(A, [M,N]),
         ( for(J,1,N-1), param(A,M) do
             lex_lt(A[1..M,J], A[1..M,J+1])
         ).


-- Joachim
Received on Fri Jul 01 2016 - 12:02:57 CEST

This archive was generated by hypermail 2.2.0 : Mon Jul 09 2018 - 02:05:30 CEST