## 10.7 Weight Constraints

Another constraint between sets and integers is the weight/3 constraint.
It allows the association of weights to set elements, and can help when
solving problems of the knapsack or bin packing type.
The constraint takes a set and an array of element weights and
constrains the weight of the whole set:
?- ic_sets:(Container :: [] .. [1, 2, 3, 4, 5]),
Weights = [](20, 34, 9, 12, 19),
weight(Container, Weights, W).
Container = Container{([] .. [1, 2, 3, 4, 5]) : _2127{0 .. 5}}
Weights = [](20, 34, 9, 12, 19)
W = W{0 .. 94}
There is 1 delayed goal.
Yes (0.01s cpu)

By adding a capacity limit and a search primitive, we can solve a
knapsack problem:
?- ic_sets:(Container :: [] .. [1, 2, 3, 4, 5]),
Weights = [](20, 34, 9, 12, 19),
weight(Container, Weights, W),
W #=< 50,
insetdomain(Container,_,_,_).
Weights = [](20, 34, 9, 12, 19)
W = 41
Container = [1, 3, 4]
More (0.00s cpu)

By using the heuristic options provided by insetdomain, we can
implement a greedy heuristic, which finds the optimal solution
(in terms of greatest weight) straight away:
?- ic_sets:(Container :: [] .. [1, 2, 3, 4, 5]),
Weights = [](20, 34, 9, 12, 19),
weight(Container, Weights, W),
W #=< 50,
insetdomain(Container,decreasing,heavy_first(Weights),_).
W = 48
Container = [1, 3, 5]
Weights = [](20, 34, 9, 12, 19)
More (0.00s cpu)

Figure 10.5: Set Weight Constraint