001package org.maltparser.parser.guide;
002
003import java.net.MalformedURLException;
004import java.net.URL;
005import java.io.File;
006
007import org.maltparser.core.exception.MaltChainedException;
008import org.maltparser.core.feature.FeatureModel;
009import org.maltparser.core.feature.FeatureVector;
010import org.maltparser.core.syntaxgraph.DependencyStructure;
011import org.maltparser.parser.AlgoritmInterface;
012import org.maltparser.parser.DependencyParserConfig;
013import org.maltparser.parser.guide.decision.BranchedDecisionModel;
014import org.maltparser.parser.guide.decision.DecisionModel;
015import org.maltparser.parser.guide.decision.OneDecisionModel;
016import org.maltparser.parser.guide.decision.SeqDecisionModel;
017import org.maltparser.parser.history.action.GuideDecision;
018import org.maltparser.parser.history.action.MultipleDecision;
019import org.maltparser.parser.history.action.SingleDecision;
020import 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*/
029public class SingleGuide implements ClassifierGuide {
030        private final DependencyParserConfig configuration;
031        private final GuideMode guideMode;
032        private final FeatureModel featureModel2;
033        private DecisionModel decisionModel = null;
034        private String guideName;
035        
036        public SingleGuide(AlgoritmInterface algorithm, GuideMode guideMode) throws MaltChainedException {
037                this.configuration = algorithm.getManager();
038                this.guideMode = guideMode;
039
040                String featureModelFileName = getConfiguration().getOptionValue("guide", "features").toString().trim();
041//              if (getConfiguration().isLoggerInfoEnabled()) {
042//                      
043//                      getConfiguration().logDebugMessage("  Feature model        : " + featureModelFileName+"\n");
044//                      if (getGuideMode() == ClassifierGuide.GuideMode.BATCH) {
045//                              getConfiguration().logDebugMessage("  Learner              : " + getConfiguration().getOptionValueString("guide", "learner").toString()+"\n");
046//                      } else {
047//                              getConfiguration().logDebugMessage("  Classifier           : " + getConfiguration().getOptionValueString("guide", "learner")+"\n");     
048//                      }
049//              }
050                String dataSplitColumn = getConfiguration().getOptionValue("guide", "data_split_column").toString().trim();
051                String dataSplitStructure = getConfiguration().getOptionValue("guide", "data_split_structure").toString().trim();
052                featureModel2 = getConfiguration().getFeatureModelManager().getFeatureModel(findURL(featureModelFileName, getConfiguration()), 0, algorithm.getParserRegistry(), dataSplitColumn, dataSplitStructure);
053//              if (getGuideMode() == ClassifierGuide.GuideMode.BATCH) {
054//                              getConfiguration().writeInfoToConfigFile("\nFEATURE MODEL\n");
055//                              getConfiguration().writeInfoToConfigFile(featureModel.toString());
056//              }
057        }
058                
059        public void addInstance(FeatureModel featureModel,GuideDecision decision) throws MaltChainedException {
060                if (decisionModel == null) {
061                        if (decision instanceof SingleDecision) {
062                                initDecisionModel((SingleDecision)decision);
063                        } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) {
064                                initDecisionModel(((MultipleDecision)decision).getSingleDecision(0));
065                        }
066                }
067                decisionModel.addInstance(featureModel,decision);
068        }
069        
070        public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException {
071                if (decisionModel != null) {
072                        decisionModel.finalizeSentence(dependencyGraph);
073                }
074        }
075        
076        public void noMoreInstances() throws MaltChainedException {
077                if (decisionModel != null) {
078                        decisionModel.noMoreInstances(featureModel2);
079                } else {
080                        configuration.logDebugMessage("The guide cannot create any models because there is no decision model. ");
081                }
082        }
083        
084        public void terminate() throws MaltChainedException {
085                if (decisionModel != null) {
086                        decisionModel.terminate();
087                        decisionModel = null;
088                }
089        }
090
091        public void predict(FeatureModel featureModel,GuideDecision decision) throws MaltChainedException {
092                if (decisionModel == null) {
093                        if (decision instanceof SingleDecision) {
094                                initDecisionModel((SingleDecision)decision);
095                        } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) {
096                                initDecisionModel(((MultipleDecision)decision).getSingleDecision(0));
097                        }
098                }
099                decisionModel.predict(featureModel,decision);
100        }
101
102        public FeatureVector predictExtract(FeatureModel featureModel,GuideDecision decision) throws MaltChainedException {
103                if (decisionModel == null) {
104                        if (decision instanceof SingleDecision) {
105                                initDecisionModel((SingleDecision)decision);
106                        } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) {
107                                initDecisionModel(((MultipleDecision)decision).getSingleDecision(0));
108                        }
109                }
110                return decisionModel.predictExtract(featureModel,decision);
111        }
112        
113        public FeatureVector extract(FeatureModel featureModel) throws MaltChainedException {
114                return decisionModel.extract(featureModel);
115        }
116        
117        public boolean predictFromKBestList(FeatureModel featureModel, GuideDecision decision) throws MaltChainedException {
118                if (decisionModel != null) {
119                        return decisionModel.predictFromKBestList(featureModel,decision);
120                } else {
121                        throw new GuideException("The decision model cannot be found. ");
122                }
123        }
124        
125        public DecisionModel getDecisionModel() {
126                return decisionModel;
127        }
128
129        public DependencyParserConfig getConfiguration() {
130                return configuration;
131        }
132        
133        public GuideMode getGuideMode() {
134                return guideMode;
135        }
136        
137        protected void initDecisionModel(SingleDecision decision) throws MaltChainedException {
138                if (decision.getRelationToNextDecision() == RelationToNextDecision.SEQUANTIAL) {
139                        decisionModel = new SeqDecisionModel(this);
140                } else if (decision.getRelationToNextDecision() == RelationToNextDecision.BRANCHED) {
141                        decisionModel = new BranchedDecisionModel(this);
142                } else if (decision.getRelationToNextDecision() == RelationToNextDecision.NONE) {
143                        decisionModel = new OneDecisionModel(this);
144                }
145        }
146        
147        public String getGuideName() {
148                return guideName;
149        }
150
151        public void setGuideName(String guideName) {
152                this.guideName = guideName;
153        }
154
155        public static URL findURL(String specModelFileName, DependencyParserConfig config) throws MaltChainedException {
156                URL url = null;
157                File specFile = config.getFile(specModelFileName);
158                if (specFile != null && specFile.exists()) {
159                        try {
160                                url = new URL("file:///"+specFile.getAbsolutePath());
161                        } catch (MalformedURLException e) {
162                                throw new MaltChainedException("Malformed URL: "+specFile, e);
163                        }
164                } else {
165                        url = config.getConfigFileEntryURL(specModelFileName);
166                }
167                return url;
168        }
169        
170        public String toString() {
171                final StringBuilder sb = new StringBuilder();
172                return sb.toString();
173        }
174}