/* Global constraint in_relation and in_relation_index in Picat. From Global Constraint Catalogue http://www.emn.fr/x-info/sdemasse/gccat/Cin_relation.html """ in_relation (VARIABLES, TUPLES_OF_VALS) Purpose Enforce the tuple of variables VARIABLES to take its value out of a set of tuples of values TUPLES_OF_VALS. The value of a tuple of variables is a tuple of values if and only if V1=U1/\V2=U2/\.../\Vn=Un. Example ( <5, 3, 3>, < tuple-<5, 2, 3>, tuple-<5, 2, 6>, tuple-<5, 3, 3> > ) The in_relation constraint holds since its first argument <5, 3, 3> corresponds to the third item of the collection of tuples TUPLES_OF_VALS. """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. % % in_relation/2 % go ?=> N = 4, M = 3, Arr = new_array(N,M), Arr :: 1..6, V1 = new_list(M), V1 :: 1..6, V1 = [5,3,3], Arr = {{5, 2, 3}, {5, 2, 6}, {5, 3, 3}, {1, 3, 2}}, in_relation(V1, Arr), Vars = Arr.vars ++ V1, solve(Vars), println(arr=Arr), println(v1=V1), nl, fail, nl. go => true. % % in_relation_index/3 % go2 ?=> N = 4, M = 3, Arr = new_array(N,M), Arr :: 1..6, V1 = new_list(M), V1 :: 1..6, Pos :: 1..N, V1 = [5,3,3], V2 = [1,2,4], % Arr = {{5, 2, 3}, % {5, 2, 6}, % {5, 3, 3}, % {1, 3, 2}}, Pos1 #= 3, % Pos2 #= 4, in_relation_index(V1, Arr, Pos1), in_relation_index(V2, Arr, Pos2), Vars = Arr.vars ++ V1 ++ [Pos1,Pos2], solve(Vars), println(arr=Arr), println(v1=V1), println(pos1=Pos1), println(pos2=Pos2), nl, fail, nl. go2 => true. % % in_relation(VARIABLES, TUPLES_OF_VALS) % in_relation(V, A) => I :: 1..A.len, in_relation_index(V,A,I). % % adding an index parameter: in which position is v? % This is in effect the same as the global constraint cond_lex_cost % in_relation_index(V, A,Ix) => Ix :: 1..A.len, foreach(J in 1..V.len) matrix_element(A,Ix,J,V[J]) end.