/* Global constraint table in Picat. From MiniZinc's global.mzn (or rather table_int.mzn) """ A table constraint: table(x, t) represents the constraint x in t where we consider each row in t to be a tuple and t as a set of tuples. """ Note: Picat has a table constraint, e.g. (I1,I2,I3) in Allowed. Here is a simple variant (poor man's table), not using the "in" construct. And we call it tablex/2 or tablex/3 to not conflict with the built-in table declaration. Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. % using table/3 go ?=> % the table (1) T = [[1,2,1], [1,2,3], [1,3,3], [2,1,3], [2,3,4], [2,5,2], [3,4,4], [4,1,3], [6,5,1]], Rows = T.length, X :: 1..6, Y :: 1..6, Z :: 1..6, X #!= Y, Z #< 3, Ix :: 1..Rows, tablex([X,Y,Z], T, Ix), Vars = [X,Y,Z,Ix], solve(Vars), writeln([X,Y,Z]), writeln(ix=Ix), nl, fail. go => true. % using table/2 go2 ?=> % the table (2) T = [[1,2,1], [1,2,3], [1,3,3], [2,1,3], [2,3,4], [2,5,2], [3,4,4], [4,1,3], [6,5,1]], X :: 1..6, Y :: 1..6, Z :: 1..6, X #!= Y, Z #< 3, tablex([X,Y,Z], T), Vars = [X,Y,Z], solve(Vars), writeln([X,Y,Z]), nl, fail. go2 => true. % % table/3 % There is some Ix which is the index % of Table and is = X. % % Note: This use freeze(Ix,Goal). % tablex(X, Table,Ix) => foreach(I in 1..Table[1].length) freeze(Ix,Table[Ix,I] #= X[I]) end. % % table/2 % % There is some Ix which is the index % of Table and is X % Here Ix is inside the predicate and we use solve/1 % to fix it. % tablex(X, Table) => R = Table.length, CLen = Table[1].length, Ix :: 1..R, foreach(I in 1..CLen) freeze(Ix,Table[Ix,I] #= X[I]) end, solve([Ix]).