/* Global constraint change in Picat. From Global Constraint Catalogue: http://www.emn.fr/x-info/sdemasse/gccat/Cchange.html """ NCHANGE is the number of times that constraint CTR holds on consecutive variables of the collection VARIABLES. Example (3, <4, 4, 3, 4, 1>, !=) (1, <1, 2, 4, 3, 7>, > ) In the first example the changes are located between values 4 and 3, 3 and 4, 4 and 1. Consequently, the corresponding change constraint holds since its first argument NCHANGE is fixed to value 3. In the second example the unique change occurs between values 4 and 3. Consequently, the corresponding change constraint holds since its first argument NCHANGE is fixed to 1. """ Here we also implement change/4 which contains where the changes are. 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. % % Using change/3 % go ?=> N = 5, X = new_list(N), X :: 1..4, Y = new_list(N), Y :: 1..7, CX :: 0..N, CY :: 0..N, X = [4,4,3,4,1], Y = [1,2,4,3,7], change(CX, X, #!=), change(CY, Y, #>), Vars = X ++ Y ++ [CX,CY], solve(Vars), println(x=X), println(cx=CX), nl, println(y=Y), println(cy=CY), nl, fail, nl. go => true. % % using change/4 % go2 ?=> N = 5, X = new_list(N), X :: 1..4, Y = new_list(N), Y :: 1..7, CX :: 0..N, CY :: 0..N, X = [4,4,3,4,1], Y = [1,2,4,3,7], change(CX, X, #!=, BX), change(CY, Y, #>, BY), Vars = X ++ Y ++ BX ++ BY ++ [CX,CY], solve(Vars), println(x=X), println(cx=CX), println(bx=BX), nl, println(y=Y), println(cy=CY), println(by=BY), nl, fail, nl. go2 => true. % % using change/4 and let X be free. % go3 ?=> N = 5, X = new_list(N), X :: 1..4, CX :: 0..N, % X = [4,4,3,4,1], CX #= 2, change(CX, X, #>, BX), Vars = X ++ BX ++ [CX], solve(Vars), println(x=X), println(cx=CX), println(bx=BX), nl, fail, nl. go3 => true. % % change/3 % change(Changes, X, Op) => change(Changes, X, Op,_Bs). % % change/4 % Also output the booleans where the changes are. % % change(Changes, X, Op,Bs) => Len = X.len, Bs = new_list(Len-1), Bs :: 0..1, foreach(I in 2..Len) cmp(Op,X[I-1], X[I], Bs[I-1]) end, Changes #= sum(Bs). cmp(#= ,S,T,B) => B :: 0..1, S #= T #<=> B #= 1. cmp(#!=,S,T,B) => B :: 0..1, S #!= T #<=> B #= 1. cmp(#< ,S,T,B) => B :: 0..1, S #< T #<=> B #= 1. cmp(#=<,S,T,B) => B :: 0..1, S #=< T #<=> B #= 1. cmp(#> ,S,T,B) => B :: 0..1, S #> T #<=> B #= 1. cmp(#>=,S,T,B) => B :: 0..1, S #>= T #<=> B #= 1.