001package org.maltparser.parser.guide.decision;
002
003import org.maltparser.core.exception.MaltChainedException;
004import org.maltparser.core.feature.FeatureModel;
005import org.maltparser.core.feature.FeatureVector;
006import org.maltparser.core.syntaxgraph.DependencyStructure;
007import org.maltparser.parser.guide.ClassifierGuide;
008import org.maltparser.parser.guide.GuideException;
009import org.maltparser.parser.guide.instance.AtomicModel;
010import org.maltparser.parser.guide.instance.FeatureDivideModel;
011import org.maltparser.parser.guide.instance.InstanceModel;
012import org.maltparser.parser.history.action.GuideDecision;
013import org.maltparser.parser.history.action.MultipleDecision;
014import org.maltparser.parser.history.action.SingleDecision;
015/**
016*
017* @author Johan Hall
018**/
019public class OneDecisionModel implements DecisionModel {
020        private final ClassifierGuide guide;
021        private final String modelName;
022//      private final FeatureModel featureModel;
023        private final int decisionIndex;
024        private final DecisionModel prevDecisionModel;
025        private final String branchedDecisionSymbols;
026        private InstanceModel instanceModel;
027        
028        public OneDecisionModel(ClassifierGuide _guide) throws MaltChainedException {
029                this.branchedDecisionSymbols = "";
030                this.guide = _guide;
031//              this.featureModel = _featureModel;
032                this.decisionIndex = 0;
033                if (guide.getGuideName() == null || guide.getGuideName().equals("")) {
034                        this.modelName = "odm"+decisionIndex;
035                } else {
036                        this.modelName = guide.getGuideName()+".odm"+decisionIndex;
037                }
038                this.prevDecisionModel = null;
039        }
040        
041        public OneDecisionModel(ClassifierGuide _guide, DecisionModel _prevDecisionModel, String _branchedDecisionSymbol) throws MaltChainedException {
042                this.prevDecisionModel = _prevDecisionModel;
043                this.decisionIndex = prevDecisionModel.getDecisionIndex() + 1;
044                if (_branchedDecisionSymbol != null && _branchedDecisionSymbol.length() > 0) {
045                        this.branchedDecisionSymbols = _branchedDecisionSymbol;
046                        this.modelName = "odm"+decisionIndex+branchedDecisionSymbols;
047                } else {
048                        this.branchedDecisionSymbols = "";
049                        this.modelName = "odm"+decisionIndex;
050                }
051                this.guide = _guide;
052//              this.featureModel = prevDecisionModel.getFeatureModel();
053        }
054        
055        private final void initInstanceModel(FeatureModel featureModel, String subModelName) throws MaltChainedException {
056                if (featureModel.hasDivideFeatureFunction()) {
057                        instanceModel = new FeatureDivideModel(this);
058                } else {
059                        instanceModel = new AtomicModel(-1, this);
060                }
061        }
062        
063//      public void updateFeatureModel() throws MaltChainedException {
064//              featureModel.update();
065//      }
066
067        public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException {
068                if (instanceModel != null) {
069                        instanceModel.finalizeSentence(dependencyGraph);
070                }
071        }
072        
073        public void noMoreInstances(FeatureModel featureModel) throws MaltChainedException {
074                if (guide.getGuideMode() == ClassifierGuide.GuideMode.CLASSIFY) {
075                        throw new GuideException("The decision model could not create it's model. ");
076                }
077
078                if (instanceModel != null) {
079                        instanceModel.noMoreInstances(featureModel);
080                        instanceModel.train();
081                }
082        }
083
084        public void terminate() throws MaltChainedException {
085                if (instanceModel != null) {
086                        instanceModel.terminate();
087                        instanceModel = null;
088                }
089        }
090        
091        public void addInstance(FeatureModel featureModel, GuideDecision decision) throws MaltChainedException {
092                featureModel.update();
093                final SingleDecision singleDecision = (decision instanceof SingleDecision)?(SingleDecision)decision:((MultipleDecision)decision).getSingleDecision(decisionIndex);
094                
095                if (instanceModel == null) {
096                        initInstanceModel(featureModel, singleDecision.getTableContainer().getTableContainerName());
097                }
098                instanceModel.addInstance(featureModel.getFeatureVector(branchedDecisionSymbols, singleDecision.getTableContainer().getTableContainerName()), singleDecision);
099        }
100        
101        public boolean predict(FeatureModel featureModel, GuideDecision decision) throws MaltChainedException {
102                featureModel.update();
103                final SingleDecision singleDecision = (decision instanceof SingleDecision)?(SingleDecision)decision:((MultipleDecision)decision).getSingleDecision(decisionIndex);
104
105                if (instanceModel == null) {
106                        initInstanceModel(featureModel, singleDecision.getTableContainer().getTableContainerName());
107                }
108                return instanceModel.predict(featureModel.getFeatureVector(branchedDecisionSymbols, singleDecision.getTableContainer().getTableContainerName()), singleDecision);
109        }
110        
111        public FeatureVector predictExtract(FeatureModel featureModel, GuideDecision decision) throws MaltChainedException {
112                featureModel.update();
113                final SingleDecision singleDecision = (decision instanceof SingleDecision)?(SingleDecision)decision:((MultipleDecision)decision).getSingleDecision(decisionIndex);
114
115                if (instanceModel == null) {
116                        initInstanceModel(featureModel, singleDecision.getTableContainer().getTableContainerName());
117                }
118                return instanceModel.predictExtract(featureModel.getFeatureVector(branchedDecisionSymbols, singleDecision.getTableContainer().getTableContainerName()), singleDecision);
119        }
120        
121        public FeatureVector extract(FeatureModel featureModel) throws MaltChainedException {
122                featureModel.update();
123                return null; //instanceModel.extract(featureModel.getFeatureVector(branchedDecisionSymbols, singleDecision.getTableContainer().getTableContainerName()));
124        }
125        
126        public boolean predictFromKBestList(FeatureModel featureModel, GuideDecision decision) throws MaltChainedException {
127                if (decision instanceof SingleDecision) {
128                        return ((SingleDecision)decision).updateFromKBestList();
129                } else {
130                        return ((MultipleDecision)decision).getSingleDecision(decisionIndex).updateFromKBestList();
131                }
132        }
133        
134        public ClassifierGuide getGuide() {
135                return guide;
136        }
137
138        public String getModelName() {
139                return modelName;
140        }
141
142        public int getDecisionIndex() {
143                return decisionIndex;
144        }
145
146        public DecisionModel getPrevDecisionModel() {
147                return prevDecisionModel;
148        }
149        
150        public String toString() {              
151                return modelName;
152        }
153}