/*-------------------------------------------------------------------------*/ /* Benchmark (Finite Domain) */ /* */ /* Name : magic.pl */ /* Title : magic series */ /* Original Source: W.J. Older and F. Benhamou - Programming in CLP(BNR) */ /* (in Position Papers of PPCP'93) */ /* Adapted by : Daniel Diaz for GNU Prolog */ /* Date : May 1993 */ /* */ /* A magic serie is a sequence x0, x1, ..., xN-1 such that each xi is the */ /* number of occurences of i in the serie. */ /* N-1 */ /* ie xi = Sum (xj=i) where (xj=i) is 1 if x=y and 0 if x<>y */ /* i=0 */ /* */ /* two redundant constraints are used: */ /* N-1 N-1 */ /* Sum i = N and Sum i*xi = N */ /* i=0 i=0 */ /* */ /* Note: in the Pascal's original version the length of a magic serie is */ /* N+1 (x0, x1, ..., XN) instead of N (x0, x1, ..., xN-1). Finding such a */ /* serie (for N) only corresponds to find a serie for N+1 in this version. */ /* Also the original version only used one redundant constraint. */ /* */ /* Solution: */ /* N=1,2,3 and 6 none */ /* N=4 [1,2,1,0] and [2,0,2,0] */ /* N=5 [2,1,2,0,0] */ /* N=7 [3,2,1,1,0,0,0] (for N>=7 [N-4,2,1,<N-7 0's>,1,0,0,0]) */ /*-------------------------------------------------------------------------*/ q:- get_fd_labeling(Lab), write('N ?'), read_integer(N), statistics(runtime,_), magic(N,L,Lab), statistics(runtime,[_,Y]), write(L), nl, write('time : '), write(Y), nl. magic(N,L,Lab):- fd_set_vector_max(N), length(L,N), fd_domain(L,0,N), constraints(L,L,0,N,N), lab(Lab,L). constraints([],_,_,0,0). constraints([X|Xs],L,I,S,S2):- sum(L,I,X), I1 is I+1, S1+X#=S, % redundant constraint 1 (I=0 -> S3=S2 ; I*X+S3#=S2), % redundant constraint 2 constraints(Xs,L,I1,S1,S3). sum([],_,0). sum([X|Xs],I,S):- sum(Xs,I,S1), X#=I #<=> B, S #= B+S1. lab(normal,L):- fd_labeling(L). lab(ff,L):- fd_labelingff(L). get_fd_labeling(Lab):- argument_counter(C), get_labeling1(C,Lab). get_labeling1(1,normal). get_labeling1(2,Lab):- argument_value(1,Lab). :- initialization(q).