def declare_relation(self,
                       rel_name,
                       domain_type,
                       range_type,
                       trainable = False,
                       dense = False):
    """Declare the domain and range types for a relation.

    Args:
      rel_name: string naming a relation
      domain_type: string naming the type of subject entities for the relation
      range_type: string naming the type of object entities for the relation
      trainable: boolean, true if the weights for this relation will be trained
      dense: if true, store data as a dense tensor instead of a SparseTensor

    Raises:
      RelationNameError: If a relation with this name already exists.
    """
    if rel_name in self._declaration:
      raise RelationNameError(rel_name, 'Multiple declarations for relation.')
    reserved = dir(NeuralQueryExpression)
    if rel_name in reserved:
      logging.warn(
          'rel_name prohibits expr.%s() as it matches a reserved word in: %r',
          rel_name, reserved)
    self._declaration[rel_name] = RelationDeclaration(rel_name, domain_type,
                                                      range_type, trainable,
                                                      dense)
    for type_name in [domain_type, range_type]:
      if type_name not in self._symtab:
        self._symtab[type_name] = symbol.SymbolTable()
    self._rel_name_symtab.insert(rel_name)
Declare the domain and range types for a relation.

    Args:
      rel_name: string naming a relation
      domain_type: string naming the type of subject entities for the relation
      range_type: string naming the type of object entities for the relation
      trainable: boolean, true if the weights for this relation will be trained
      dense: if true, store data as a dense tensor instead of a SparseTensor

    Raises:
      RelationNameError: If a relation with this name already exists.
    
language/nql/nql/__init__.py