/* Global constraints common and used_by in Picat. From Global Constraint Catalogue: common: http://www.emn.fr/x-info/sdemasse/gccat/Ccommon.html """ NCOMMON1 is the number of variables of the collection of variables VARIABLES1 taking a value in VARIABLES2. NCOMMON2 is the number of variables of the collection of variables VARIABLES2 taking a value in VARIABLES1. Example: common(3, 4, <1, 9, 1, 5>, <2, 1, 9, 9, 6, 9>) The common constraint holds since: * Its first argument NCOMMON1 = 3 corresponds to the number of values of the collection <1, 9, 1, 5> that occur within <2, 1, 9, 9, 6, 9>. * Its second argument NCOMMON2 = 4 corresponds to the number of values of the collection <2, 1, 9, 9, 6, 9> that occur within <1, 9, 1, 5>. """ used_by: http://www.emn.fr/x-info/sdemasse/gccat/Cused_by.html """ All the values of the variables of collection VARIABLES2 are used by the variables of collection VARIABLES1. Example: used_by([1, 9, 1, 5, 2, 1], [1, 1, 2, 5]) """" 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. % % Testing common/4 % go ?=> X = new_list(4), X :: 1..9, Y = new_list(6), Y :: 1..9, A :: 0..10, B :: 0..10, X = [1,9,1,5], Y = [2,1,9,9,6,9], common(A, B, X, Y), % The "reverse problem" works as well, i.e. letting x and y be unknown % and fix a and b. % A #= 3, % B #= 4, % increasing(X), % increasing(Y), Vars = X ++ Y ++ [A,B], solve(Vars), println(x=X), println(y=Y), println(a=A), println(b=B), nl, fail, nl. go => true. % % Testing used_by/2 % go2 ?=> X = new_list(4), X :: 1..9, Y = new_list(6), Y :: 1..9, X = [1,9,1,5], % Y = [2,1,9,9,6,9], used_by(X, Y), used_by(Y, X), Vars = X ++ Y, solve(Vars), println(x=X), println(y=Y), nl, fail, nl. go2 => true. % % common(a, b, x, y) % - a is the number of values of x that are in y % - b is the number of values of y that are in x % common(A, B, X, Y) => A #= sum([sum([X[I] #= Y[J] : J in 1..Y.len]) #>= 1 : I in 1..X.len]), B #= sum([sum([X[I] #= Y[J] : I in 1..X.len]) #>= 1 : J in 1..Y.len]). % % used_by(x, y) % % _All_ values in x are in y.. % used_by(X, Y) => common(A, _B, X, Y), A #= X.len.