/* Global/general constraint first_pos/3 and first_pos_all/3 in Picat. * first_pos(Val, Y, Ix) finds the first position (Ix) where Val is in Y. Note: Here we assume that Val is in Y (somewhere). * first_pos_all(Vals, Y, Ixs) Finds the first position (Ixs[I]) of Vals[I] in Y. 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. go ?=> N = 5, X = new_list(N), X :: 1..N, Val :: 1..N, Ix :: 1..N, Ix #= 3, first_pos(Val,X,Ix), Vars = X ++ [Val,Ix], solve(Vars), println(x=X), println(val=Val), println(ix=Ix), nl, fail, nl. go => true. % % First pos for all values % go2 ?=> N = 5, Max = 4, X = new_list(N), X :: 1..Max, FirstPos = new_list(Max), FirstPos :: 1..N, first_pos_all(1..Max,X,FirstPos), % increasing(FirstPos), Vars = X ++ FirstPos, solve(Vars), println(x=X), println(firstPos=FirstPos), nl, fail, nl. go2 => true. % % Find the first position of value Val in the list Y. % Note that we assume that Val is in the list. % first_pos(Val, Y, Ix) => N = Y.len, Ix :: 1..N, sum([ Y[I] #= Val #/\ Ix #= I #/\ sum([Y[J] #= Val : J in 1..I-1]) #= 0 : I in 1..N]) #= 1. % % Find the first position (FirstPos[I]) of value Vals[I] in the list Y. % Note that we assume that Val is in the list. % first_pos_all(Vals,Y,FirstPos) => foreach({I,V} in zip(1..Vals.len,Vals)) first_pos(V, Y, FirstPos[I]) end.