docs: def addConstraint(self, constraint, variables=None):
          """
          Add a constraint to the problem
  
          Example:
  
          >>> problem = Problem()
          >>> problem.addVariables(["a", "b"], [1, 2, 3])
          >>> problem.addConstraint(lambda a, b: b == a+1, ["a", "b"])
          >>> solutions = problem.getSolutions()
          >>>
  
          @param constraint: Constraint to be included in the problem
          @type  constraint: instance a L{Constraint} subclass or a
                             function to be wrapped by L{FunctionConstraint}
          @param variables: Variables affected by the constraint (default to
                            all variables). Depending on the constraint type
                            the order may be important.
          @type  variables: set or sequence of variables
          """
          if not isinstance(constraint, Constraint):
              if callable(constraint):
                  constraint = FunctionConstraint(constraint)
              else:
                  msg = "Constraints must be instances of subclasses " "of the Constraint class"
                  raise ValueError(msg)
          self._constraints.append((constraint, variables))