/* Some explorations of ISBN13 in Picat. See http://en.wikipedia.org/wiki/ISBN Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. % Test ISBN: % 978-0262720304: The OPL Optimization Programming Language % [9,7,8,0,2,6,2,7,2,0,3,0] % % isbn = 978-0262220774: Constraint-based Local Search % [9,7,8,0,2,6,2,2,2,0,7,7]; % Constraint Solving and Planning with Picat % book: http://www.springer.com/gp/book/9783319258812 % [9,7,8,3,3,1,9,2,5,8,8,1,2] % Ebook: [9,7,8,3,3,1,9,2,5,8,8,3,6] main => go. go ?=> N = 13, % Mult0 = 3, % Mult1 = 1, % test ISBN % ISBN = [9,7,8,0,2,6,2,7,2,0,3,0,_], % get check digit % ISBN = [9,7,8,0,2,_,2,7,2,0,3,0,4], % get some other digit % ISBN = [9,7,8,0,2,_,_,7,2,0,3,0,4], % get some other digit % ISBN = [9,7,8,0,2,6,2,_,_,_,_,_,_], % Picat book: http://www.springer.com/gp/book/9783319258812 ISBN = [9,7,8,3,3,1,9,2,5,8,8,_,_], isbn(N, ISBN,Mult0,Mult1,Check), writeln(isbn=ISBN), writeln(check=Check), writeln([mult0=Mult0,mult1=Mult1]), nl, fail. go => true. go2 => % The Picat book: http://www.springer.com/gp/book/9783319258812 ISBN = [9,7,8,3,3,1,9,2,5,8,8,_,_], isbn2(ISBN), println(ISBN), fail, nl. isbn(N, ISBN,Mult0,Mult1,Check) => ISBN = new_list(N), ISBN :: 0..9, Mult0 :: 1..9, Mult1 :: 1..9, Mult0 #= 3, Mult1 #= 1, % Mult0 #\= Mult1, % extra constraint % The first N-1 digits, for the check sum N1 = N-1, TT = new_list(N1), TT :: 0..100, % ISBN starts with 978 or 979 ISBN[1] #= 9, ISBN[2] #= 7, ISBN[3] #>=8, % Prepare for the check sum foreach({T,C} in zip(TT,1..N1)) element(C,ISBN,I), if C mod 2 == 0 then T #= I*Mult0 else T #= I*Mult1 end end, sum(TT) #= TSum, % check digit Check #= ISBN[N], Check #= (10 - TSum mod 10) mod 10, Vars = ISBN ++ TT ++ [Mult0,Mult1,TSum], solve([ff],Vars). % % Simpler version: fixed Mult0 and Mult1 % isbn2(ISBN) => N=13, ISBN = new_list(N), ISBN :: 0..9, % The first N-1 digits, for the check sum N1 = N-1, TT = new_list(N1), TT :: 0..100, % ISBN starts with 978 or 979 ISBN[1] #= 9,ISBN[2] #= 7,ISBN[3] #>=8, % Prepare for the check sum foreach({T,C} in zip(TT,1..N1)) element(C,ISBN,I), if C mod 2 == 0 then T #= I*3 % I*Mult0 else T #= I*1 % I*Mult1 end end, sum(TT) #= TSum, Check #= ISBN[N], Check #= (10 - TSum mod 10) mod 10, Vars = ISBN ++ TT ++ [TSum], solve([ff,split],Vars).