View source with raw comments or as raw
    1% $domain(0..mv).
    2cspvar(nWeight(N),0,MV) :-      coloredPos(N),  max_total_weight(MV).
    3
    4color(red).
    5color(blue).
    6color(green).
    7
    8leaf(L) :- leafWeightCardinality(L,W,C).
    9
   10% We mostly care about the lesser of weight and cardinality.
   11% Just call it leafWeight
   12leafCost(L,W) :- leaf(L), leafWeightCardinality(L,W,C), W <= C.
   13leafCost(L,C) :- leaf(L), leafWeightCardinality(L,W,C), C < W.
   14
   15% locations go from 1 till N-1: assumption is that leafs are numbered 1 through N
   16coloredPos(L) :- leaf(L),L!=N, num(N).
   17
   18% Each leaf will have a location in our sequence
   19% locations go from 0 till N-1
   20location(0). 
   21location(L) :- leaf(L),L!=N, num(N).
   22
   23% Give each leaf a location in the sequence
   241{ leafPos(L,N) : location(N) }1 :- leaf(L).
   25
   26% No sharing locations
   27:- leafPos(L1, N), leafPos(L2, N), location(N), L1 != L2.
   28
   29
   30%%%% COLORS %%%%
   31
   32
   33
   34% coloredPos(1) has a special case, look at locations 1 and 2 in leafPos to
   35% to determine color
   36
   37% green if (weight(right) + card(right)) < (weight(left) + leafCost(right))
   38posColor(1,green) :- leafPos(L1,0), leafPos(L2,1), leafWeightCardinality(L1,WL,CL),
   39            leafWeightCardinality(L2,WR,CR), leafCost(L2,W3), W1=WR+CR, W2=WL+W3, W1 < W2.
   40% blue if not green and card(right) < weight(right)
   41posColor(1,blue) :- leafPos(L2,1), leafWeightCardinality(L2,W,C), C < W, 
   42            not posColor(1,green).
   43% red if not green and weight(right) < card(right)
   44posColor(1,red) :- leafPos(L2,1), leafWeightCardinality(L2,W,C), W <= C, 
   45            not posColor(1,green).
   46
   47% Give each colored pos above 1 a unique color
   481{ posColor(P,N) : color(N) }1 :- coloredPos(P), P>1.
   49
   50% if nWeight(N-1)>WR+CR-W2 then posColor(N,green) must be green
   51%required(nWeight(N-1)<=WR+CR-W2):- 
   52required(nWeight(N2)<=WR+CR-W2):-     not posColor(N,green), N>1, coloredPos(N), leafPos(L,N), leafWeightCardinality(L,WR,CR),    leafCost(L,W2),    N2=N-1.
   65%%%% WEIGHTS %%%%
   66
   67% nWeight for first coloredPos
   68required(nWeight(1)==W):- posColor(1,green), leafPos(L,1), leafWeightCardinality(L,WR,CR),
   69            W=WR+CR.
   70required(nWeight(1)==W) :- not posColor(1,green), leafPos(L1,0), leafPos(L2,1), 
   71            leafWeightCardinality(L1,WL,CL), leafCost(L2,WR), W=WL+WR.
   72
   73% define nWeight/2
   74% green
   75required(nWeight(N)==W) :- coloredPos(N), N>1, posColor(N,green), leafPos(L,N), 
   76            leafWeightCardinality(L,WR,CR), W=WR+CR.
   77
   78% not green
   79%required(nWeight(N)==nWeight(N-1)+WR)  :- coloredPos(N), N>1, not posColor(N,green), leafPos(L,N), 
   80required(nWeight(N)==nWeight(N2)+WR)  :- coloredPos(N), N>1, not posColor(N,green), leafPos(L,N), 
   81            leafCost(L,WR),
   82            N2=N-1.
   83
   84%sum of nWeights should be less than mv
   85required(sum([nWeight/1],<=,MV)) :-
   86    max_total_weight(MV).
   87
   88label_order(nWeight(N),1) :-coloredPos(N).
   89required(nWeight(Nm1)> W+C-W2):- not posColor(N,blue), N>1, coloredPos(N), leafPos(L,N), leafWeightCardinality(L,W,C), C < W,Nm1=N-1, leafCost(L,W2).
   90
   91
   92%%
   93% If it's not  green and accords red color restrictions it must be red
   94required(nWeight(Nm1)> W+C-W2):- not posColor(N,red), N>1, coloredPos(N), leafPos(L,N), leafWeightCardinality(L,W,C), C >= W,Nm1=N-1, leafCost(L,W2).
   95
   96%% + enforce sorted order of nongreen blocks
   97%%
   98:-not posColor(N,green), not posColor(N-1,green), coloredPos(N-1),
   99leafPos(L1,N-1),  leafPos(L2,N), leafCost(L1,C1), leafCost(L2,C2), C1>C2.
  100
  101:-not posColor(N,green), not posColor(N-1,green), coloredPos(N-1),leafPos(L1,N-1),  leafPos(L2,N), leafCost(L1,C), leafCost(L2,C), L1>L2.
  106:- leafPos(L1,P1),  leafPos(L2,P2), 
  107   posColor(P1,green), posColor(P2,green), 
  108   L1<L2, P1>P2.