code: package edu.cmu.ml.rtw.pra.features;
  
  import java.util.Map;
  
  import com.mattg.util.ObjectParser;
  
  /**
   * A PathTypeFactory's main job is to take a Path - a sequence of (node, edge, node, edge, ...,
   * node) and return a (set of) strings that represent the "path type" of that sequence.
   *
   * The point is that the sequence that includes nodes cannot be used as a general feature, as the
   * feature would be specific to only one row in the feature matrix (the row corresponding to the
   * first and last node in the sequence).  At the very least, you would have to drop the initial and
   * final nodes to get a useful feature.  But you could do a lot more than that.  The default is to
   * just drop all the nodes and use the edge sequence as the basic PathType.  But you could imagine
   * creating a PathTypeFactory that has a mapping from nodes to categories, and gives a sequence of
   * edges and categories.  Or one that has a mapping from edges to vectors, and returns a sequence
   * of vectors.
   */
  public interface PathTypeFactory extends ObjectParser<PathType> {
  
    /**
     * Converts the sequences of nodes and edges into the set of abstracted PathTypes that are
     * compatible with the observed sequence.
     *
     * This uses an array instead of a List for efficiency reasons, as this is used during walks in
     * the GraphChi code.
     */
    public PathType[] encode(Path path);
  
    /**
     * A PathType that is an identity with regards to the concatenatePathTypes and combinePathTypes
     * operations (the latter is in the CombiningPathTypeFactory interface).
     */
    public PathType emptyPathType();
  
    /**
     * Combines two path types that meet at an intermediate node.  The path from the target node is
     * reverses and inverted, then concatenated to the end of the path from the source node.  Given
     * that addToPathType now exists, this could probably use a more distinguishing name.
     */
    public PathType concatenatePathTypes(PathType pathToSource, PathType pathFromTarget);
  
    /**
     * For use in the PathFinderCompanion, where we need to combine paths from two nodes that met at
     * an intermediate node.  pathFromTarget should be reversed, then appended to pathToSource.
     */
    public PathType addToPathType(PathType pathType, int relation, int node, boolean reverse);
  
    /**
     * Because this extends ObjectParser<PathType> it already defines a fromString() method (and it
     * extends ObjectParser<PathType> for legacy reasons that possibly could be changed...).  That
     * method parses a representation generated by PathType.encodeAsString(), and is used in some
     * tests.  This method parses a representation generated by
     * PathType.encodeAsHumanReadableString(), and is used in the FeatureMatcher code.
     */
    public PathType fromHumanReadableString(String string);
  }
  