language ESSENCE 1.2.0
$prob116.essence: Vellino's Problem$ Problem details available in:
$The OPL Optimization Programming Language$   Pascal Van Hentenryck
$MIT Press, January 1999.$
$27 July 2007$

given maxMaterial : int

$Material: there are five different types of materials$ Colour: there are three different types of bin, distinguished by colour
letting Material be new type enum {glass,plastic,steel,wood,copper},
Colour be new type enum {red,green,blue}

$quantity: the amount of each material that is required to be placed in bins$ capacity: each bin type (colour) has a certain capacity
given quantity : function (total) Material --> int(0..),
capacity : function (total) Colour --> int(0..)

$Bin: bins are represented by an unnamed type. the number of values is the same$      as the total amount of material that is required
letting Bin be new type of size (sum m : Material . quantity(m))

$colour: each bin is assigned a colour$ contents: the contents of each bin is a multiset of materials
find colour : function Bin --> Colour,
$The size of each mset returned by contents is <= some value returned by capacity (given) contents : function Bin --> mset (maxOccur maxMaterial, maxSize max(range(capacity))) of Material$ minimise the number of bins that have colours & materials assigned to them
minimising |defined(colour)|

such that
$every bin that has a colour, must also have a contents, and vice versa forAll b : Bin . b in defined(colour) <-> b in defined(contents),$ the correct amount of each material is spread across all the bins
forAll m : Material . (sum b in defined(contents) . freq(contents(b),m))
= quantity(m),
$the amount of material in each bin does not exceed its capacity forAll b in defined(colour) . |contents(b)| <= capacity(colour(b)),$ red bins cannot contain plastic or steel
forAll b in defined(colour) . colour(b) = red ->
!(plastic in contents(b)) /\
!(steel in contents(b)),
$blue bins cannot contain wood or plastic forAll b in defined(colour) . colour(b) = blue -> !(wood in contents(b)) /\ !(plastic in contents(b)),$ green bins cannot contain steel or glass
forAll b in defined(colour) . colour(b) = green ->
!(steel in contents(b)) /\
!(glass in contents(b)),
$red bins contain at most one wooden component forAll b in defined(colour) . colour(b) = red -> freq(contents(b),wood) <= 1,$ green bins contain at most two wooden components
forAll b in defined(colour) . colour(b) = green ->
freq(contents(b),wood) <= 2,
$wood requires plastic forAll b in defined(colour) . wood in contents(b) -> plastic in contents(b),$ glass excludes copper
forAll b in defined(colour) . glass in contents(b) ->
!(copper in contents(b)),
\$ copper excludes plastic
forAll b in defined(colour) . copper in contents(b) ->
!(plastic in contents(b))