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 }