001package org.maltparser.parser.history.action;
002
003import java.util.ArrayList;
004
005import org.maltparser.core.exception.MaltChainedException;
006import org.maltparser.parser.history.GuideUserHistory;
007import org.maltparser.parser.history.HistoryException;
008import org.maltparser.parser.history.container.ActionContainer;
009import org.maltparser.parser.history.container.CombinedTableContainer;
010import org.maltparser.parser.history.kbest.ScoredKBestList;
011
012/**
013*
014* @author Johan Hall
015**/
016public class ComplexDecisionAction implements GuideUserAction, MultipleDecision {
017        private final GuideUserHistory history;
018        private final ArrayList<SimpleDecisionAction> decisions;
019        
020        public ComplexDecisionAction(GuideUserHistory history) throws MaltChainedException {
021                this.history = history;
022                this.decisions = new ArrayList<SimpleDecisionAction>(history.getDecisionTables().size());
023                for (int i=0, n = history.getDecisionTables().size(); i < n; i++) {
024                        decisions.add(new SimpleDecisionAction(history.getKBestSize(), history.getDecisionTables().get(i)));
025                }
026        }
027        
028        /* GuideUserAction interface */
029        public void addAction(ArrayList<ActionContainer> actionContainers) throws MaltChainedException {
030                if (actionContainers == null || actionContainers.size() != history.getActionTables().size()) {
031                        throw new HistoryException("The action containers does not exist or is not of the same size as the action table. ");
032                }
033                int j = 0;
034                for (int i = 0, n = history.getDecisionTables().size(); i < n; i++) {
035                        if (history.getDecisionTables().get(i) instanceof CombinedTableContainer) {
036                                CombinedTableContainer tableContainer = (CombinedTableContainer)history.getDecisionTables().get(i);
037                                int nContainers = tableContainer.getNumberContainers();
038                                decisions.get(i).addDecision(tableContainer.getCombinedCode(actionContainers.subList(j, j + nContainers)));
039                                j = j + nContainers;
040                        } else {
041                                decisions.get(i).addDecision(actionContainers.get(j).getActionCode());
042                                j++;
043                        }
044                }
045        }
046        
047        public void getAction(ArrayList<ActionContainer> actionContainers) throws MaltChainedException {
048                if (actionContainers == null || actionContainers.size() != history.getActionTables().size()) {
049                        throw new HistoryException("The action containers does not exist or is not of the same size as the action table. ");
050                }
051                int j = 0;
052                for (int i = 0, n=history.getDecisionTables().size(); i < n; i++) {
053                        if (history.getDecisionTables().get(i) instanceof CombinedTableContainer) {
054                                CombinedTableContainer tableContainer = (CombinedTableContainer)history.getDecisionTables().get(i);
055                                int nContainers = tableContainer.getNumberContainers();
056                                tableContainer.setActionContainer(actionContainers.subList(j, j + nContainers), decisions.get(i).getDecisionCode());
057                                j = j + nContainers;
058                        } else {
059                                actionContainers.get(j).setAction(decisions.get(i).getDecisionCode());
060                                j++;
061                        }
062                }
063        }
064        
065        public void addAction(ActionContainer[] actionContainers) throws MaltChainedException {
066                if (actionContainers == null || actionContainers.length != history.getActionTables().size()) {
067                        throw new HistoryException("The action containers does not exist or is not of the same size as the action table. ");
068                }
069                int j = 0;
070                for (int i = 0, n = history.getDecisionTables().size(); i < n; i++) {
071                        if (history.getDecisionTables().get(i) instanceof CombinedTableContainer) {
072                                CombinedTableContainer tableContainer = (CombinedTableContainer)history.getDecisionTables().get(i);
073                                int nContainers = tableContainer.getNumberContainers();
074                                decisions.get(i).addDecision(tableContainer.getCombinedCode(actionContainers, j));
075                                j = j + nContainers;
076                        } else {
077                                decisions.get(i).addDecision(actionContainers[j].getActionCode());
078                                j++;
079                        }
080                }
081        }
082        
083        public void getAction(ActionContainer[] actionContainers) throws MaltChainedException {
084                if (actionContainers == null || actionContainers.length != history.getActionTables().size()) {
085                        throw new HistoryException("The action containers does not exist or is not of the same size as the action table. ");
086                }
087                int j = 0;
088                for (int i = 0, n=history.getDecisionTables().size(); i < n; i++) {
089                        if (history.getDecisionTables().get(i) instanceof CombinedTableContainer) {
090                                CombinedTableContainer tableContainer = (CombinedTableContainer)history.getDecisionTables().get(i);
091                                int nContainers = tableContainer.getNumberContainers();
092                                tableContainer.setActionContainer(actionContainers, j, decisions.get(i).getDecisionCode());
093                                j = j + nContainers;
094                        } else {
095                                actionContainers[j].setAction(decisions.get(i).getDecisionCode());
096                                j++;
097                        }
098                }
099        }
100        
101        
102        public void getKBestLists(ArrayList<ScoredKBestList> kbestListContainers) throws MaltChainedException {
103//              if (kbestListContainers == null || kbestListContainers.size() != history.getActionTables().size()) {
104//                      throw new HistoryException("The action containers does not exist or is not of the same size as the action table. ");
105//              }
106                kbestListContainers.clear();
107                for (int i = 0, n=decisions.size(); i < n; i++) {
108                        kbestListContainers.add((ScoredKBestList)decisions.get(i).getKBestList());
109                }
110        }
111        
112        public void getKBestLists(ScoredKBestList[] kbestListContainers) throws MaltChainedException {
113                for (int i = 0, n=decisions.size(); i < n; i++) {
114                        kbestListContainers[0] = (ScoredKBestList)decisions.get(i).getKBestList();
115                }
116        }
117        
118        public int numberOfActions() {
119                return history.getActionTables().size();
120        }
121        
122        public void clear() {
123                for (int i=0, n = decisions.size(); i < n;i++) {
124                        decisions.get(i).clear();
125                }
126        }
127        
128        /* MultipleDecision */
129        public SingleDecision getSingleDecision(int decisionIndex) throws MaltChainedException {
130                return decisions.get(decisionIndex);
131        }
132
133        /* GuideDecision */
134        public int numberOfDecisions() {
135                return history.getDecisionTables().size();
136        }
137        
138        public boolean equals(Object obj) {
139                if (this == obj)
140                        return true;
141                if (obj == null)
142                        return false;
143                if (getClass() != obj.getClass())
144                        return false;
145                ComplexDecisionAction other = (ComplexDecisionAction) obj;
146                if (decisions == null) {
147                        if (other.decisions != null)
148                                return false;
149                } else if (decisions.size() != other.decisions.size()) {
150                        return false;
151                } else {
152                        for (int i = 0; i < decisions.size(); i++) {
153                                try {
154                                        if (decisions.get(i).getDecisionCode() != other.decisions.get(i).getDecisionCode()) {
155                                                return false;
156                                        }
157                                } catch (MaltChainedException e) {
158                                        System.err.println("Error in equals. ");
159                                }
160                        }
161                }
162                
163                return true;
164        }
165
166        public String toString() {
167                StringBuilder sb = new StringBuilder();
168                for (int i = 0, n = decisions.size(); i < n; i++) {
169                        sb.append(decisions.get(i));
170                        sb.append(';');
171                }
172                if (sb.length() > 0) {
173                        sb.setLength(sb.length()-1);
174                }
175                return sb.toString();
176        }
177}