Constraint blocks are class members just like variables, functions and tasks and have unique names within a class. These blocks of expressions are typically used to limit the values of random variables within certain values as specified within the constraint block.
Expressions listed within the curly braces specify the conditions a solver has to take into account when assigning random values for the variables. It is not necessary to have a single constraint for every variable nor is it required to restrict a constraint block to have conditions pertaining only to a single variable. However you cannot have conflicting constraints spread out in multiple blocks, unless they are turned off using constraint_mode() method which we'll see later.