001    package toolbus.process;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    import java.util.Stack;
006    import toolbus.AtomList;
007    import toolbus.State;
008    import toolbus.StateElement;
009    import toolbus.TBTermFactory;
010    import toolbus.environment.Environment;
011    import toolbus.exceptions.ToolBusException;
012    import toolbus.parsercup.PositionInformation;
013    import toolbus.process.debug.ExecutionResult;
014    import aterm.ATerm;
015    
016    /**
017     * @author paulk, May 30, 2007 RightBiasedAlternative implements the the asymmetric choice operator
018     *         operator +>. It is similar to + but prefers its right argument.
019     */
020    public class RightBiasedAlternative extends ProcessExpression implements StateElement{
021            private final int LEFT = 0;
022            private final int RIGHT = 1;
023            
024            private ProcessInstance processInstance;
025            
026            private final ProcessExpression[] expr;
027            
028            private final State[] state;
029            private final State mergeState;
030            
031            private boolean rightLast = false;
032            
033            public RightBiasedAlternative(ProcessExpression left, ProcessExpression right, TBTermFactory tbfactory, PositionInformation posInfo){
034                    super(tbfactory, posInfo);
035                    
036                    expr = new ProcessExpression[2];
037                    expr[LEFT] = left;
038                    expr[RIGHT] = right;
039                    
040                    state = new State[2];
041                    mergeState = new State();
042                    mergeState.addElement(this);
043            }
044            
045            protected void computeFirst(){
046                    expr[LEFT].computeFirst();
047                    expr[RIGHT].computeFirst();
048            }
049            
050            protected void compile(ProcessInstance processInstance, Stack<String> calls, State follows) throws ToolBusException{
051                    this.processInstance = processInstance;
052                    
053                    expr[LEFT].compile(processInstance, calls, follows);
054                    state[LEFT] = expr[LEFT].getFirst();
055                    
056                    expr[RIGHT].compile(processInstance, calls, follows);
057                    state[RIGHT] = expr[RIGHT].getFirst();
058                    setFollow(follows);
059            }
060            
061            protected void replaceFormals(Environment env) throws ToolBusException{
062                    expr[LEFT].replaceFormals(env);
063                    expr[RIGHT].replaceFormals(env);
064            }
065            
066            protected ProcessExpression copy(){
067                    return new RightBiasedAlternative(expr[LEFT].copy(), expr[RIGHT].copy(), tbfactory, getPosInfo());
068            }
069            
070            public AtomList getAtoms(){
071                    return expr[LEFT].getAtoms().union(expr[RIGHT].getAtoms());
072            }
073            
074            public State getFirst(){
075                    return mergeState;
076            }
077            
078            // Implementation of the StateElement interface
079            
080            public boolean contains(StateElement a){
081                    return state[LEFT].contains(a) || state[RIGHT].contains(a);
082            }
083            
084            public ProcessInstance getProcess(){
085                    return processInstance;
086            }
087            
088            public void setTest(ATerm test, Environment env) throws ToolBusException{
089                    state[LEFT].setTest(test, env);
090                    state[RIGHT].setTest(test, env);
091            }
092            
093            public List<ATerm> getTests(){
094                    return new ArrayList<ATerm>(0);
095            }
096            
097            public boolean isEnabled(){
098                    return state[LEFT].isEnabled() || state[RIGHT].isEnabled();
099            }
100            
101            public State gotoNextStateAndActivate(){
102                    // System.err.println("RightBiasedAlternative.getNextState: " +
103                    // leftLast + " ; follow = " + follow);
104                    // System.err.println("state[LEFT] =" + state[LEFT]);
105                    // System.err.println("state[RIGHT] =" + state[RIGHT]);
106                    
107                    if(rightLast){
108                            return state[RIGHT].gotoNextStateAndActivate();
109                    }
110                    return state[LEFT].gotoNextStateAndActivate();
111            }
112            
113            public State gotoNextStateAndActivate(StateElement se){
114                    // System.err.println("RightBiasedAlternative.getNextState2: " +
115                    // leftLast + "; " + se + " ; follow = " + follow);
116                    // System.err.println("state[LEFT] =" + state[LEFT]);
117                    // System.err.println("state[RIGHT] =" + state[RIGHT]);
118                    
119                    if(state[RIGHT].contains(se)){
120                            return state[RIGHT].gotoNextStateAndActivate(se);
121                    }
122                    return state[LEFT].gotoNextStateAndActivate(se);
123                    
124            }
125            
126            public void activate(){
127                    state[LEFT].activate();
128                    state[RIGHT].activate();
129            }
130            
131            public boolean execute() throws ToolBusException{
132                    if(state[RIGHT].execute()){
133                            rightLast = true;
134                            return true;
135                    }else if(state[LEFT].execute()){
136                            rightLast = false;
137                            return true;
138                    }else return false;
139            }
140            
141            public ProcessInstance[] debugExecute() throws ToolBusException{
142                    ExecutionResult er;
143                    if((er = state[RIGHT].debugExecute()) != null){
144                            rightLast = true;
145                            return er.partners;
146                    }else if((er = state[LEFT].debugExecute()) != null){
147                            rightLast = false;
148                            return er.partners;
149                    }
150                    
151                    return null;
152            }
153            
154            public String toString(){
155                    return "RightBiasedAlternative(" + state[LEFT] + "; " + state[RIGHT] + ")";
156            }
157    }