docs: 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