def declare_entity_type(self,
                          type_name,
                          fixed_vocab = None,
                          unknown_marker = '<UNK>',
                          fixed_vocab_size = 0):
    """Declare an entity type.

    Declared entity types can be used as domain and ranges for relations.

    There are three flavors of entity types.  By default, entity types will have
    an open-ended vocabulary - any string can be used as an entity name, and ids
    will be allocated for new strings as they are needed.  One can also fix
    either the vocabulary size or the vocabulary.  Entity names used as domains
    or ranges declare_relation are of this variety.

    If the vocabulary size is fixed to N, there will always be exactly N id's
    allocated for this entity type, which means matrices defining relations
    involving this type will have predictable shapes. (Eg a relation with this
    as the domain_type will have N rows.)  You can add strings to a type with
    fixed vocabulary size, but an error will be raised if you add too many.
    Entity types with fixed vocabulary size are useful for sets of 'object ids',
    like question_ids, which are not used in modeling, but are related to 'real
    objects', eg features of questions: the intended use case is to set up a
    type, load in the objects for a minibatch, and then reset the entity type
    before loading in the next set of objects.

    If the vocabulary is fixed, then the set of entity names is also fixed.
    Entities with names not in the vocabulary will be mapped to a special
    'unknown_entity' id, which has the name given by the unknown_marker argument
    given above.  If the unknown_marker is None then an error is raised when
    entity names outside the fixed vocabulary are inserted.

    Args:
      type_name: string name of this type
      fixed_vocab: an list of strings
      unknown_marker: a string or None
      fixed_vocab_size: a positive integer

    Raises:
      TypeNameError: If the type has already been declared.
      ValueError: If both fixed vocab and fixed vocab size are specified.
    """
    if type_name in self._symtab:
      raise TypeNameError(type_name, 'Type is already declared.')
    symtab = self._symtab[type_name] = symbol.SymbolTable()
    if fixed_vocab:
      if fixed_vocab_size:
        raise ValueError(
            'Fixed vocab and fixed vocab size are mutually exclusive')
      for entity_name in fixed_vocab:
        symtab.insert(entity_name)
      symtab.freeze(unknown_marker=unknown_marker)
    if fixed_vocab_size:
      symtab.pad_to_vocab_size(fixed_vocab_size)
      symtab.reset()
Declare an entity type.

    Declared entity types can be used as domain and ranges for relations.

    There are three flavors of entity types.  By default, entity types will have
    an open-ended vocabulary - any string can be used as an entity name, and ids
    will be allocated for new strings as they are needed.  One can also fix
    either the vocabulary size or the vocabulary.  Entity names used as domains
    or ranges declare_relation are of this variety.

    If the vocabulary size is fixed to N, there will always be exactly N id's
    allocated for this entity type, which means matrices defining relations
    involving this type will have predictable shapes. (Eg a relation with this
    as the domain_type will have N rows.)  You can add strings to a type with
    fixed vocabulary size, but an error will be raised if you add too many.
    Entity types with fixed vocabulary size are useful for sets of 'object ids',
    like question_ids, which are not used in modeling, but are related to 'real
    objects', eg features of questions: the intended use case is to set up a
    type, load in the objects for a minibatch, and then reset the entity type
    before loading in the next set of objects.

    If the vocabulary is fixed, then the set of entity names is also fixed.
    Entities with names not in the vocabulary will be mapped to a special
    'unknown_entity' id, which has the name given by the unknown_marker argument
    given above.  If the unknown_marker is None then an error is raised when
    entity names outside the fixed vocabulary are inserted.

    Args:
      type_name: string name of this type
      fixed_vocab: an list of strings
      unknown_marker: a string or None
      fixed_vocab_size: a positive integer

    Raises:
      TypeNameError: If the type has already been declared.
      ValueError: If both fixed vocab and fixed vocab size are specified.
    
language/nql/nql/__init__.py