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);
}
