def rule_satisfied(x, features, categories):
    """
    return a logical array representing whether entries in x satisfied the rules denoted by features and categories
    :param x: a categorical 2D array
    :param features: a list of feature indices
    :param categories: a list of categories
    :return:
    """
    satisfied = []
    if features[0] == -1 and len(features) == 1:
        # Default rule, all satisfied
        return np.ones(x.shape[0], dtype=bool)
    for idx, cat in zip(features, categories):
        # Every single condition needs to be satisfied.
        satisfied.append(x[:, idx] == cat)
    return functools.reduce(np.logical_and, satisfied)
return a logical array representing whether entries in x satisfied the rules denoted by features and categories
    :param x: a categorical 2D array
    :param features: a list of feature indices
    :param categories: a list of categories
    :return: