All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.stanford.nlp.parser.lexparser.HookChart Maven / Gradle / Ivy

package edu.stanford.nlp.parser.lexparser;

import java.util.*;

import edu.stanford.nlp.util.Generics;

/**
 * A HookChart is a chart data structure designed for use with the efficient
 * O(n^4) chart parsing mechanisms targetted at lexicalized parsing, which
 * were introduced by Eisner and Satta.
 *
 * @author Dan Klein
 */
class HookChart {

  private Map> registeredPreHooks = Generics.newHashMap();
  private Map> registeredPostHooks = Generics.newHashMap();
  private Map> registeredEdgesByLeftIndex = Generics.newHashMap();
  private Map> registeredEdgesByRightIndex = Generics.newHashMap();

  private Map> realEdgesByL = Generics.newHashMap();
  private Map> realEdgesByR = Generics.newHashMap();
  private Set builtLIndexes = Generics.newHashSet();
  private Set builtRIndexes = Generics.newHashSet();

  private Interner interner = new Interner();

  private static class ChartIndex {
    public int state;
    public int head;
    public int tag;
    public int loc;  // either the start or end of an edge

    @Override
    public int hashCode() {
      return state ^ (head << 8) ^ (tag << 16) ^ (loc << 24);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o instanceof ChartIndex) {
        ChartIndex ci = (ChartIndex) o;
        return state == ci.state && head == ci.head && tag == ci.tag && loc == ci.loc;
      }
      return false;
    }

  } // end class ChartIndex

  private static class WeakChartIndex {
    public int state;
    public int loc;  // either the start or end of an edge

    @Override
    public int hashCode() {
      return state ^ (loc << 16);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o instanceof WeakChartIndex) {
        WeakChartIndex ci = (WeakChartIndex) o;
        return state == ci.state && loc == ci.loc;
      }
      return false;
    }
  }


  private static final Collection empty = Collections.emptyList();
  private static final Collection emptyHooks = Collections.emptyList();

  private ChartIndex tempIndex = new ChartIndex(); // used in many methods to decrease new's
  private WeakChartIndex tempWeakIndex = new WeakChartIndex();  // used to decrease new's


  public void registerEdgeIndexes(Edge edge) {
    tempIndex.state = edge.state;
    tempIndex.head = edge.head;
    tempIndex.tag = edge.tag;
    tempIndex.loc = edge.start;
    ChartIndex index = (ChartIndex) interner.intern(tempIndex);
    builtLIndexes.add(index);
    if (index == tempIndex) {
      tempIndex = new ChartIndex();
      tempIndex.state = edge.state;
      tempIndex.head = edge.head;
      tempIndex.tag = edge.tag;
    }
    //System.out.println("Edge registered: "+edge);
    tempIndex.loc = edge.end;
    index = (ChartIndex) interner.intern(tempIndex);
    if (index == tempIndex) {
      tempIndex = new ChartIndex();
    }
    builtRIndexes.add(index);
  }

  public void registerRealEdge(Edge edge) {
    tempWeakIndex.state = edge.state;
    tempWeakIndex.loc = edge.start;
    WeakChartIndex index = (WeakChartIndex) interner.intern(tempWeakIndex);
    insert(realEdgesByL, index, edge);
    if (index == tempWeakIndex) {
      tempWeakIndex = new WeakChartIndex();
      tempWeakIndex.state = edge.state;
    }
    tempWeakIndex.loc = edge.end;
    index = (WeakChartIndex) interner.intern(tempWeakIndex);
    insert(realEdgesByR, index, edge);
    if (index == tempWeakIndex) {
      tempWeakIndex = new WeakChartIndex();
    }
  }

  public boolean isBuiltL(int state, int start, int head, int tag) {
    tempIndex.state = state;
    tempIndex.head = head;
    tempIndex.tag = tag;
    tempIndex.loc = start;
    return builtLIndexes.contains(tempIndex);
  }

  public boolean isBuiltR(int state, int end, int head, int tag) {
    tempIndex.state = state;
    tempIndex.head = head;
    tempIndex.tag = tag;
    tempIndex.loc = end;
    return builtRIndexes.contains(tempIndex);
  }

  public Collection getRealEdgesWithL(int state, int start) {
    tempWeakIndex.state = state;
    tempWeakIndex.loc = start;
    Collection edges = realEdgesByL.get(tempWeakIndex);
    if (edges == null) {
      return empty;
    }
    return edges;
  }

  public Collection getRealEdgesWithR(int state, int end) {
    tempWeakIndex.state = state;
    tempWeakIndex.loc = end;
    Collection edges = realEdgesByR.get(tempWeakIndex);
    if (edges == null) {
      return empty;
    }
    return edges;
  }

  public Collection getPreHooks(Edge edge) {
    tempIndex.state = edge.state;
    tempIndex.head = edge.head;
    tempIndex.tag = edge.tag;
    tempIndex.loc = edge.end;
    Collection result = registeredPreHooks.get(tempIndex);
    if (result == null) {
      result = emptyHooks;
    }
    //System.out.println("For "+edge+" returning "+result.size()+" pre hooks");
    return result;
  }

  public Collection getPostHooks(Edge edge) {
    tempIndex.state = edge.state;
    tempIndex.head = edge.head;
    tempIndex.tag = edge.tag;
    tempIndex.loc = edge.start;
    Collection result = registeredPostHooks.get(tempIndex);
    if (result == null) {
      result = emptyHooks;
    }
    //System.out.println("For "+edge+" returning "+result.size()+" post hooks");
    return result;
  }

  public Collection getEdges(Hook hook) {
    tempIndex.state = hook.subState;
    tempIndex.head = hook.head;
    tempIndex.tag = hook.tag;
    Collection result;
    if (hook.isPreHook()) {
      tempIndex.loc = hook.start;
      result = registeredEdgesByRightIndex.get(tempIndex);
    } else {
      tempIndex.loc = hook.end;
      result = registeredEdgesByLeftIndex.get(tempIndex);
    }
    if (result == null) {
      result = empty;
    }
    //System.out.println("For "+hook+" returning "+result.size()+" edges");
    return result;
  }

  // This hacks up a CollectionValuedMap.  Maybe convert to using that class?
  private static  void insert(Map> map, K index, V item) {
    List list = map.get(index);
    if (list == null) {
      // make default size small: many only ever contain 1 or 2 items
      list = new ArrayList<>(3);
      map.put(index, list);
    }
    list.add(item);
    // System.err.println("#### HookChart list length is " + list.size());
  }


  public void addEdge(Edge edge) {
    tempIndex.state = edge.state;
    tempIndex.head = edge.head;
    tempIndex.tag = edge.tag;
    // left index
    tempIndex.loc = edge.start;
    ChartIndex index = (ChartIndex) interner.intern(tempIndex);
    insert(registeredEdgesByLeftIndex, index, edge);
    if (index == tempIndex) {
      tempIndex = new ChartIndex();
      tempIndex.state = edge.state;
      tempIndex.head = edge.head;
      tempIndex.tag = edge.tag;
    }
    tempIndex.loc = edge.end;
    index = (ChartIndex) interner.intern(tempIndex);
    insert(registeredEdgesByRightIndex, index, edge);
    if (index == tempIndex) {
      tempIndex = new ChartIndex();
    }
  }

  public void addHook(Hook hook) {
    Map> map;
    tempIndex.state = hook.subState;
    tempIndex.head = hook.head;
    tempIndex.tag = hook.tag;
    if (hook.isPreHook()) {
      tempIndex.loc = hook.start;
      map = registeredPreHooks;
    } else {
      tempIndex.loc = hook.end;
      map = registeredPostHooks;
    }
    ChartIndex index = (ChartIndex) interner.intern(tempIndex);
    insert(map, index, hook);
    if (index == tempIndex) {
      tempIndex = new ChartIndex();
    }
  }

} // end class HookChart




© 2015 - 2024 Weber Informatics LLC | Privacy Policy