:-lib(ic). :-lib(propia). :-lib(util). :-dynamic(box_index/2). %stack(+Ls,-Lp) is true if %Ls is a list of N boxes %Lp is a list of P stacks where the maximum height of the stacks is N/P stack(Ls,List):- length(Ls,N), between(1,N,P), Tmp is N/P, ceiling(Tmp,T2), integer(T2,H), stack(Ls,P,H,List),!. %stack(+Ls,+N,+H,-Lp) is true if %Ls is a list of boxes %N is the number of stacks we want to create %H is the maximum height of the stacks %Stacks is the list of stacks stack(Ls,N,H,Stacks):- retractall(box_index(_I,_B)), length(Ls,Nb), NbFakeBoxes is N*H - Nb, fill(Ls,NbFakeBoxes,La), PlaceInStacks is N*H, addIndex(La,1), length(List,PlaceInStacks), List :: [1..PlaceInStacks], createConstraints(List,1,H), alldifferent(List), (fromto(List,Vars,Rest,[]) do delete(Var,Vars,Rest,0,first_fail), indomain(Var,min) ), produceSolution(List,N,H,Stacks). %produceSolution(+Li,+N,+H,-Lb) is true if %Li is a list of box index %N is a number such that every box with a index < N will be ignored %H is the maximum height of the stacks %Lb is a list of stacks produceSolution([],_,_,[]):-!. produceSolution(Li,N,H,[L|Lb]):- produceStack(Li,N,H,L,Rs), produceSolution(Rs,N,H,Lb). %produceStack(+Li,+N,+H,-P,-Rs) is true if %Li is a list of box indexes %N is a number %H is the maximum height of the stack %P is a stack where every box in this stack have a index >= N %Rs is the list Li where we removed the H first values produceStack(Li,_,0,[],Li):-!. produceStack([I|Li],N,H,[C|P],R):- I>=N,!,box_index(I,C), H1 is H-1, produceStack(Li,N,H1,P,R). produceStack([_I|Li],N,H,P,R):- H1 is H-1, produceStack(Li,N,H1,P,R). %addIndex(+L,+I) is true if %L is a list of N boxes %I is a number %and facts were added in the knowledge base to assign an index to the boxes % of L. The index of J-th box in L will be I+J (J=0 for the first box) addIndex([],_I):-!. addIndex([C|L],I):- asserta(box_index(I,C)), I1 is I+1, addIndex(L,I1). %constraintBoxes(+I,+J) is true if %I and J are indexes of boxes %a constraint was stated that both width and length of box I are greater or % equal the width and length of box J constraintBoxes(I,J):- box_index(I,box(Wi,Li)) infers ic, box_index(J,box(Wj,Lj)) infers ic, Wi#>=Wj, Li#>=Lj. %createConstraint(+L,+I,+N) is true if %L is a list of length T of box indexes %I and N are numbers %and T+I%N = 1, and constraint where stated on L such that L represent a flatten %list of stack, where each stack has a height of N createConstraints([_],N,N):-!. createConstraints([_,B|Ls],N,N):-!, createConstraints([B|Ls],1,N). createConstraints([A,B|Ls],I,N):- I= 0 %Ls is the list L in wich we added I fake boxes at the beginning of he list fill(L,0,L):-!. fill(L,I,[box(0,0)|R]):-I>0, I1 is I-1, fill(L,I1,R).