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 * LeftBiasedAlternative implements the the asymmetric choice operator operator <+. It is similar
018 * to + but prefers its left argument.
019 *
020 * @author Arnold Lankamp
021 */
022 public class LeftBiasedAlternative extends ProcessExpression implements StateElement{
023 private final int LEFT = 0;
024 private final int RIGHT = 1;
025
026 private ProcessInstance processInstance;
027
028 private final ProcessExpression[] expr;
029
030 private final State[] state;
031 private final State mergeState;
032
033 private boolean leftLast = false;
034
035 public LeftBiasedAlternative(ProcessExpression left, ProcessExpression right, TBTermFactory tbfactory, PositionInformation posInfo){
036 super(tbfactory, posInfo);
037
038 expr = new ProcessExpression[2];
039 expr[LEFT] = left;
040 expr[RIGHT] = right;
041
042 state = new State[2];
043 mergeState = new State();
044 mergeState.addElement(this);
045 }
046
047 protected void computeFirst(){
048 expr[LEFT].computeFirst();
049 expr[RIGHT].computeFirst();
050 }
051
052 protected void compile(ProcessInstance processInstance, Stack<String> calls, State follows) throws ToolBusException{
053 this.processInstance = processInstance;
054
055 expr[LEFT].compile(processInstance, calls, follows);
056 state[LEFT] = expr[LEFT].getFirst();
057
058 expr[RIGHT].compile(processInstance, calls, follows);
059 state[RIGHT] = expr[RIGHT].getFirst();
060 setFollow(follows);
061 }
062
063 protected void replaceFormals(Environment env) throws ToolBusException{
064 expr[LEFT].replaceFormals(env);
065 expr[RIGHT].replaceFormals(env);
066 }
067
068 protected ProcessExpression copy(){
069 return new LeftBiasedAlternative(expr[LEFT].copy(), expr[RIGHT].copy(), tbfactory, getPosInfo());
070 }
071
072 public AtomList getAtoms(){
073 return expr[LEFT].getAtoms().union(expr[RIGHT].getAtoms());
074 }
075
076 public State getFirst(){
077 return mergeState;
078 }
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 if(leftLast) return state[LEFT].gotoNextStateAndActivate();
103
104 return state[RIGHT].gotoNextStateAndActivate();
105 }
106
107 public State gotoNextStateAndActivate(StateElement se){
108 if(state[LEFT].contains(se)) return state[LEFT].gotoNextStateAndActivate(se);
109
110 return state[RIGHT].gotoNextStateAndActivate(se);
111 }
112
113 public void activate(){
114 state[LEFT].activate();
115 state[RIGHT].activate();
116 }
117
118 public boolean execute() throws ToolBusException{
119 if(state[LEFT].execute()){
120 leftLast = true;
121 return true;
122 }else if(state[RIGHT].execute()){
123 leftLast = false;
124 return true;
125 }else return false;
126 }
127
128 public ProcessInstance[] debugExecute() throws ToolBusException{
129 ExecutionResult er;
130 if((er = state[LEFT].debugExecute()) != null){
131 leftLast = true;
132 return er.partners;
133 }else if((er = state[RIGHT].debugExecute()) != null){
134 leftLast = false;
135 return er.partners;
136 }
137
138 return null;
139 }
140
141 public String toString(){
142 return "LeftBiasedAlternative(" + state[LEFT] + "; " + state[RIGHT] + ")";
143 }
144 }