// This file is part of AceWiki.
// Copyright 2008-2013, AceWiki developers.
//
// AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
// not, see http://www.gnu.org/licenses/.
package ch.uzh.ifi.attempto.chartparser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This class represents a chart (in the sense of a chart for a chart parser). A chart basically consists
* of a set of edges plus operations to add, remove, and retrieve edges. The edges stored by a chart represent
* (partial) analyses of certain ranges of a text.
*
* @author Tobias Kuhn
*/
class Chart {
private String[] usedFeatureNames;
// All edges are contained by this set:
private Set<Edge> edges = new HashSet<Edge>();
// This hashtable indexes the edges by their end positions:
private Map<Integer, List<Edge>> edgesByEndPos = new HashMap<Integer, List<Edge>>();
/**
* Creates an empty chart.
*
* @param grammar The grammar for the chart.
*/
public Chart(Grammar grammar) {
this.usedFeatureNames = grammar.getFeatureNamesArray();
}
/**
* Adds the given edge to the chart. If there is already an edge in the chart that is equivalent
* to the given edge then the chart remains unchanged and false is returned.
*
* @param edge The edge to be added to the chart.
* @return true if the edge was has been to the chart, or false if there is already an
* equivalent edge in the chart.
*/
public boolean addEdge(Edge edge) {
// Check whether the edge is new (i.e. not equivalent to an existing edge):
edge.calculateIdentifier(usedFeatureNames);
boolean isNewEdge = !edges.contains(edge);
if (isNewEdge) {
// Add the edge to the chart:
edges.add(edge);
// Update the end position hashtable:
getEdgesByEndPos(edge.getEndPos()).add(edge);
}
return isNewEdge;
}
/**
* Returns the size of the chart, i.e. the number of edges.
*
* @return The size of the chart.
*/
public int getSize() {
return edges.size();
}
/**
* Returns a list of all edges with the given end position. The returned list in an internal list
* that should never be changed from outside.
*
* @param endPos The end position of the edges to be returned.
* @return A list of all edges with the given end position.
*/
public List<Edge> getEdgesByEndPos(int endPos) {
List<Edge> l = edgesByEndPos.get(endPos);
if (l == null) {
l = new ArrayList<Edge>();
edgesByEndPos.put(endPos, l);
}
return l;
}
/**
* Removes all edges with the given end position from the chart.
*
* @param endPos The end position of the edges to be removed.
*/
public void removeEdgesWithEndPos(int endPos) {
List<Edge> l = edgesByEndPos.get(endPos);
if (l == null) return;
for (Edge e : l) {
edges.remove(e);
}
l.clear();
}
/**
* Removes all edges from the chart.
*/
public void clear() {
edges.clear();
edgesByEndPos.clear();
}
public String toString() {
String s = "";
for (Edge e : edges) {
s += e + "\n";
}
return s;
}
}