Check the model for various errors. This method checks for the following
        errors. In the same time it also updates the cardinalities of all the
        random variables.

        * Check whether bipartite property of factor graph is still maintained
          or not.
        * Check whether factors are associated for all the random variables or not.
        * Check if factors are defined for each factor node or not.
        * Check if cardinality information for all the variables is availble or not.
        * Check if cardinality of random variable remains same across all the
          factors.

def check_model(self):
        """
        Check the model for various errors. This method checks for the following
        errors. In the same time it also updates the cardinalities of all the
        random variables.

        * Check whether bipartite property of factor graph is still maintained
          or not.
        * Check whether factors are associated for all the random variables or not.
        * Check if factors are defined for each factor node or not.
        * Check if cardinality information for all the variables is availble or not.
        * Check if cardinality of random variable remains same across all the
          factors.
        """
        variable_nodes = set([x for factor in self.factors for x in factor.scope()])
        factor_nodes = set(self.nodes()) - variable_nodes

        if not all(isinstance(factor_node, DiscreteFactor) for factor_node in factor_nodes):
            raise ValueError('Factors not associated for all the random variables')

        if (not (bipartite.is_bipartite(self)) or
            not (bipartite.is_bipartite_node_set(self, variable_nodes) or
                 bipartite.is_bipartite_node_set(self, variable_nodes))):
            raise ValueError('Edges can only be between variables and factors')

        if len(factor_nodes) != len(self.factors):
            raise ValueError('Factors not associated with all the factor nodes.')

        cardinalities = self.get_cardinality()
        if len(variable_nodes) != len(cardinalities):
            raise ValueError('Factors for all the variables not defined')

        for factor in self.factors:
            for variable, cardinality in zip(factor.scope(), factor.cardinality):
                if (cardinalities[variable] != cardinality):
                    raise ValueError('Cardinality of variable {var} not matching among factors'.format(var=variable))

        return True