/*
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]).