Each constraint is a little sub-program that attempts to reduce the
search space. They should only be run as required, i.e. when the
candidates of the variables they use were updated, though this has not
yet been implemented.
Constraints are traits so that puzzles may implement their own
specialised contraints as required. We have split the trait into an
"on_assigned" call and an "on_updated" call for clarity. The provided
methods simply return true, indicating no contradiction.