/* This file is part of the Joshua Machine Translation System. * * Joshua 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 2.1 * of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package joshua.decoder.hypergraph; import java.util.ArrayList; import java.util.List; import joshua.corpus.vocab.SymbolTable; import joshua.decoder.ff.tm.Rule; /** * @author Zhifei Li, <zhifei.work@gmail.com> * @version $LastChangedDate: 2010-01-14 21:11:52 -0600 (Thu, 14 Jan 2010) $ */ public class ViterbiExtractor { // get one-best string under item public static String extractViterbiString(SymbolTable symbolTable, HGNode node) { StringBuffer res = new StringBuffer(); HyperEdge edge = node.bestHyperedge; Rule rl = edge.getRule(); if (null == rl) { // deductions under "goal item" does not have rule if (edge.getAntNodes().size() != 1) { throw new RuntimeException("deduction under goal item have not equal one item"); } return extractViterbiString(symbolTable, edge.getAntNodes().get(0)); } int[] english = rl.getEnglish(); for (int c = 0; c < english.length; c++) { if (symbolTable.isNonterminal(english[c])) { int id = symbolTable.getTargetNonterminalIndex(english[c]); HGNode child = (HGNode)edge.getAntNodes().get(id); res.append(extractViterbiString(symbolTable, child)); } else { res.append(symbolTable.getWord(english[c])); } if (c < english.length-1) res.append(' '); } return res.toString(); } // ######## find 1best hypergraph############# public static HyperGraph getViterbiTreeHG(HyperGraph hg_in) { HyperGraph res = new HyperGraph(cloneNodeWithBestHyperedge(hg_in.goalNode), -1, -1, hg_in.sentID, hg_in.sentLen); // TODO: number of items/deductions get1bestTreeNode(res.goalNode); return res; } private static void get1bestTreeNode(HGNode it) { HyperEdge dt = it.bestHyperedge; if (null != dt.getAntNodes()) { for (int i = 0; i < dt.getAntNodes().size(); i++) { HGNode antNode = dt.getAntNodes().get(i); HGNode newNode = cloneNodeWithBestHyperedge(antNode); dt.getAntNodes().set(i, newNode); get1bestTreeNode(newNode); } } } // TODO: tbl_states private static HGNode cloneNodeWithBestHyperedge(HGNode inNode) { List<HyperEdge> hyperedges = new ArrayList<HyperEdge>(1); HyperEdge cloneEdge = cloneHyperedge(inNode.bestHyperedge); hyperedges.add(cloneEdge); return new HGNode(inNode.i, inNode.j, inNode.lhs, hyperedges, cloneEdge, inNode.dpStates); } private static HyperEdge cloneHyperedge(HyperEdge inEdge) { List<HGNode> antNodes = null; if (null != inEdge.getAntNodes()) { antNodes = new ArrayList<HGNode>(inEdge.getAntNodes());//l_ant_items will be changed in get_1best_tree_item } HyperEdge res = new HyperEdge(inEdge.getRule(), inEdge.bestDerivationLogP, inEdge.getTransitionLogP(false), antNodes, inEdge.getSourcePath()); return res; } //###end }