001 package org.maltparser.parser.guide; 002 003 004 import java.io.IOException; 005 import java.lang.reflect.Constructor; 006 import java.lang.reflect.InvocationTargetException; 007 008 import org.maltparser.core.exception.MaltChainedException; 009 import org.maltparser.core.feature.FeatureModel; 010 import org.maltparser.core.feature.FeatureModelManager; 011 import org.maltparser.core.feature.system.FeatureEngine; 012 import org.maltparser.core.plugin.PluginLoader; 013 import org.maltparser.core.syntaxgraph.DependencyStructure; 014 import org.maltparser.parser.DependencyParserConfig; 015 import org.maltparser.parser.guide.decision.DecisionModel; 016 import org.maltparser.parser.history.GuideHistory; 017 import org.maltparser.parser.history.action.GuideDecision; 018 import org.maltparser.parser.history.action.MultipleDecision; 019 import org.maltparser.parser.history.action.SingleDecision; 020 import org.maltparser.parser.history.container.TableContainer.RelationToNextDecision; 021 022 023 /** 024 * The guide is used by a parsing algorithm to predict the next parser action during parsing and to 025 * add a instance to the training instance set during learning. 026 027 @author Johan Hall 028 @since 1.0 029 */ 030 public class SingleGuide implements Guide { 031 private DependencyParserConfig configuration; 032 private GuideHistory history; 033 private DecisionModel decisionModel = null; 034 private GuideMode guideMode; 035 private FeatureModelManager featureModelManager; 036 private FeatureModel featureModel; 037 038 public SingleGuide(DependencyParserConfig configuration, GuideHistory history, GuideMode guideMode) throws MaltChainedException { 039 setConfiguration(configuration); 040 setHistory(history); 041 setGuideMode(guideMode); 042 initFeatureModelManager(); 043 initHistory(); 044 initFeatureModel(); 045 featureModel.updateCardinality(); 046 } 047 048 public void addInstance(GuideDecision decision) throws MaltChainedException { 049 if (decisionModel == null) { 050 if (decision instanceof SingleDecision) { 051 initDecisionModel((SingleDecision)decision); 052 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) { 053 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0)); 054 } 055 } 056 decisionModel.addInstance(decision); 057 } 058 059 public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException { 060 if (decisionModel != null) { 061 decisionModel.finalizeSentence(dependencyGraph); 062 } 063 } 064 065 public void noMoreInstances() throws MaltChainedException { 066 if (decisionModel != null) { 067 decisionModel.noMoreInstances(); 068 } else { 069 configuration.getConfigLogger().debug("The guide cannot create any models because there is no decision model. "); 070 } 071 } 072 073 public void terminate() throws MaltChainedException { 074 if (decisionModel != null) { 075 decisionModel.terminate(); 076 decisionModel = null; 077 } 078 } 079 080 public void predict(GuideDecision decision) throws MaltChainedException { 081 if (decisionModel == null) { 082 if (decision instanceof SingleDecision) { 083 initDecisionModel((SingleDecision)decision); 084 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) { 085 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0)); 086 } 087 } 088 decisionModel.predict(decision); 089 } 090 091 public boolean predictFromKBestList(GuideDecision decision) throws MaltChainedException { 092 if (decisionModel != null) { 093 return decisionModel.predictFromKBestList(decision); 094 } else { 095 throw new GuideException("The decision model cannot be found. "); 096 } 097 } 098 099 public DecisionModel getDecisionModel() { 100 return decisionModel; 101 } 102 103 public DependencyParserConfig getConfiguration() { 104 return configuration; 105 } 106 107 public GuideHistory getHistory() { 108 return history; 109 } 110 111 public GuideMode getGuideMode() { 112 return guideMode; 113 } 114 115 public FeatureModelManager getFeatureModelManager() { 116 return featureModelManager; 117 } 118 119 protected void setConfiguration(DependencyParserConfig configuration) { 120 this.configuration = configuration; 121 } 122 123 protected void setHistory(GuideHistory actionHistory) { 124 this.history = actionHistory; 125 } 126 127 protected void setGuideMode(GuideMode guideMode) { 128 this.guideMode = guideMode; 129 } 130 131 protected void initHistory() throws MaltChainedException { 132 Class<?> kBestListClass = null; 133 int kBestSize = 1; 134 if (guideMode == Guide.GuideMode.CLASSIFY) { 135 kBestListClass = (Class<?>)getConfiguration().getOptionValue("guide", "kbest_type"); 136 kBestSize = ((Integer)getConfiguration().getOptionValue("guide", "kbest")).intValue(); 137 } 138 history.setKBestListClass(kBestListClass); 139 history.setKBestSize(kBestSize); 140 history.setSeparator(getConfiguration().getOptionValue("guide", "classitem_separator").toString()); 141 } 142 143 protected void initDecisionModel(SingleDecision decision) throws MaltChainedException { 144 Class<?> decisionModelClass = null; 145 if (decision.getRelationToNextDecision() == RelationToNextDecision.SEQUANTIAL) { 146 decisionModelClass = org.maltparser.parser.guide.decision.SeqDecisionModel.class; 147 } else if (decision.getRelationToNextDecision() == RelationToNextDecision.BRANCHED) { 148 decisionModelClass = org.maltparser.parser.guide.decision.BranchedDecisionModel.class; 149 } else if (decision.getRelationToNextDecision() == RelationToNextDecision.NONE) { 150 decisionModelClass = org.maltparser.parser.guide.decision.OneDecisionModel.class; 151 } 152 153 if (decisionModelClass == null) { 154 throw new GuideException("Could not find an appropriate decision model for the relation to the next decision"); 155 } 156 157 try { 158 Class<?>[] argTypes = { org.maltparser.parser.guide.Guide.class, org.maltparser.core.feature.FeatureModel.class }; 159 Object[] arguments = new Object[2]; 160 arguments[0] = this; 161 arguments[1] = featureModel; 162 Constructor<?> constructor = decisionModelClass.getConstructor(argTypes); 163 decisionModel = (DecisionModel)constructor.newInstance(arguments); 164 } catch (NoSuchMethodException e) { 165 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 166 } catch (InstantiationException e) { 167 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 168 } catch (IllegalAccessException e) { 169 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 170 } catch (InvocationTargetException e) { 171 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 172 } 173 } 174 175 protected void initFeatureModelManager() throws MaltChainedException { 176 final FeatureEngine system = new FeatureEngine(configuration); 177 system.load("/appdata/features/ParserFeatureSystem.xml"); 178 system.load(PluginLoader.instance()); 179 featureModelManager = new FeatureModelManager(system, configuration.getRegistry()); 180 } 181 182 protected void initFeatureModel() throws MaltChainedException { 183 getFeatureModelManager().loadSpecification(getConfiguration().getOptionValue("guide", "features").toString()); 184 featureModel = getFeatureModelManager().getFeatureModel(getConfiguration().getOptionValue("guide", "features").toString(), 0); 185 if (getGuideMode() == Guide.GuideMode.TRAIN) { 186 try { 187 getConfiguration().getConfigurationDir().getInfoFileWriter().write("\nFEATURE MODEL\n"); 188 getConfiguration().getConfigurationDir().getInfoFileWriter().write(featureModel.toString()); 189 getConfiguration().getConfigurationDir().getInfoFileWriter().flush(); 190 } catch (IOException e) { 191 throw new GuideException("Could not write feature model specification to configuration information file. ", e); 192 } 193 } 194 } 195 196 public String toString() { 197 final StringBuilder sb = new StringBuilder(); 198 return sb.toString(); 199 } 200 }