def caught_matrix(self, x):
        # type: (np.ndarray) -> np.ndarray
        """
        compute the caught matrix of x
        Each rule has an array of bools, showing whether each instances is caught by this rule
        :param x: 2D np.ndarray (n_instances, n_features) should be categorical data, must be of type int
        :return:
            a bool np.ndarray of shape (n_rules, n_instances)
        """
        un_satisfied = np.ones((x.shape[0],), dtype=np.bool)
        supports = np.zeros((self.n_rules, x.shape[0]), dtype=np.bool)
        for i, rule in enumerate(self._rule_list):
            is_satisfied = rule.is_satisfied(x)
            satisfied = np.logical_and(is_satisfied, un_satisfied)
            # marking new satisfied instances as satisfied
            un_satisfied = np.logical_xor(satisfied, un_satisfied)
            supports[i, :] = satisfied
        return supports