@classmethod
def less_or_equal_constraint(cls, variables, upperbound):
    """Clauses encoding a "less than or equal to" constraint
     
        E.g. X1 + X2 + X3 + X4 <= 2
     
        (~X1 v ~X2 v ~X3)
        (~X1 v ~X2 v ~X4)
        (~X1 v ~X3 v ~X4)
        (~X2 v ~X3 v ~X4)
     
        Parameters
        ----------
        variables : list of variables
           variables in the constraint
        upperbound: int
           upper bound of the constraint
     
        Returns
        -------
            a list of clauses
     
        Examples
        --------
        >>> list(CNF.less_than_constraint(['a','b','c'],3)) == list(CNF.less_or_equal_constraint(['a','b','c'],2))
        True
        >>> list(CNF.less_or_equal_constraint(['a','b','c'],1))
        [[(False, 'a'), (False, 'b')], [(False, 'a'), (False, 'c')], [(False, 'b'), (False, 'c')]]
        >>> list(CNF.less_or_equal_constraint(['a','b'],0))
        [[(False, 'a')], [(False, 'b')]]
        >>> list(CNF.less_or_equal_constraint(['a','b','c'],-1))
        [[]]
        >>> list(CNF.less_or_equal_constraint(['a','b','c'],10))
        []
        """
    return cls._inequality_constraint_builder(variables, upperbound + 1,
        greater=False)
