| 1 | package de.uka.ipd.sdq.pcmsolver.transformations.pcm2regex; |
| 2 | |
| 3 | import java.util.ArrayList; |
| 4 | import java.util.LinkedList; |
| 5 | import java.util.List; |
| 6 | |
| 7 | import org.apache.log4j.Logger; |
| 8 | import org.eclipse.emf.common.util.EList; |
| 9 | |
| 10 | import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition; |
| 11 | import de.uka.ipd.sdq.pcm.seff.AbstractInternalControlFlowAction; |
| 12 | import de.uka.ipd.sdq.pcm.seff.BranchAction; |
| 13 | import de.uka.ipd.sdq.pcm.seff.CollectionIteratorAction; |
| 14 | import de.uka.ipd.sdq.pcm.seff.ExternalCallAction; |
| 15 | import de.uka.ipd.sdq.pcm.seff.InternalAction; |
| 16 | import de.uka.ipd.sdq.pcm.seff.LoopAction; |
| 17 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingBehaviour; |
| 18 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF; |
| 19 | import de.uka.ipd.sdq.pcm.seff.SetVariableAction; |
| 20 | import de.uka.ipd.sdq.pcm.seff.StartAction; |
| 21 | import de.uka.ipd.sdq.pcm.seff.StopAction; |
| 22 | import de.uka.ipd.sdq.pcm.seff.seff_performance.ParametricResourceDemand; |
| 23 | import de.uka.ipd.sdq.pcm.seff.util.SeffSwitch; |
| 24 | import de.uka.ipd.sdq.pcmsolver.transformations.ContextWrapper; |
| 25 | import de.uka.ipd.sdq.pcmsolver.visitors.EMFQueryHelper; |
| 26 | import de.uka.ipd.sdq.pcmsolver.visitors.ExpressionHelper; |
| 27 | import de.uka.ipd.sdq.probfunction.ProbabilityDensityFunction; |
| 28 | import de.uka.ipd.sdq.probfunction.ProbabilityFunction; |
| 29 | import de.uka.ipd.sdq.probfunction.SamplePDF; |
| 30 | import de.uka.ipd.sdq.probfunction.math.IProbabilityFunctionFactory; |
| 31 | import de.uka.ipd.sdq.probfunction.math.ISamplePDF; |
| 32 | import de.uka.ipd.sdq.probfunction.math.IUnit; |
| 33 | import de.uka.ipd.sdq.probfunction.math.PDFConfiguration; |
| 34 | import de.uka.ipd.sdq.probfunction.math.exception.ConfigurationNotSetException; |
| 35 | import de.uka.ipd.sdq.probfunction.math.exception.UnknownPDFTypeException; |
| 36 | import de.uka.ipd.sdq.spa.expression.Alternative; |
| 37 | import de.uka.ipd.sdq.spa.expression.Expression; |
| 38 | import de.uka.ipd.sdq.spa.expression.ExpressionFactory; |
| 39 | import de.uka.ipd.sdq.spa.expression.Option; |
| 40 | import de.uka.ipd.sdq.spa.expression.Sequence; |
| 41 | import de.uka.ipd.sdq.spa.expression.Symbol; |
| 42 | import de.uka.ipd.sdq.spa.resourcemodel.ResourceModelFactory; |
| 43 | import de.uka.ipd.sdq.spa.resourcemodel.ResourceUsage; |
| 44 | import de.uka.ipd.sdq.stoex.Atom; |
| 45 | import de.uka.ipd.sdq.stoex.DoubleLiteral; |
| 46 | import de.uka.ipd.sdq.stoex.IntLiteral; |
| 47 | import de.uka.ipd.sdq.stoex.NumericLiteral; |
| 48 | import de.uka.ipd.sdq.stoex.ProbabilityFunctionLiteral; |
| 49 | |
| 50 | public class TransformSeffVisitor extends SeffSwitch{ |
| 51 | |
| 52 | private static Logger logger = Logger.getLogger(TransformSeffVisitor.class.getName()); |
| 53 | |
| 54 | private ExpressionFactory expFactory = ExpressionFactory.eINSTANCE; |
| 55 | private ResourceModelFactory resFactory = ResourceModelFactory.eINSTANCE; |
| 56 | private IProbabilityFunctionFactory pfFactory = IProbabilityFunctionFactory.eINSTANCE; |
| 57 | |
| 58 | private ContextWrapper myContextWrapper; |
| 59 | |
| 60 | public TransformSeffVisitor(ContextWrapper ctxWrapper){ |
| 61 | myContextWrapper = ctxWrapper; |
| 62 | } |
| 63 | |
| 64 | @Override |
| 65 | public Object caseResourceDemandingSEFF(ResourceDemandingSEFF object) { |
| 66 | ResourceDemandingBehaviour rdb = (ResourceDemandingBehaviour) object; |
| 67 | return doSwitch(getStartAction(rdb)); |
| 68 | } |
| 69 | |
| 70 | @Override |
| 71 | public Object caseResourceDemandingBehaviour(ResourceDemandingBehaviour object) { |
| 72 | return doSwitch(getStartAction(object)); |
| 73 | } |
| 74 | |
| 75 | @Override |
| 76 | public Object caseStartAction(StartAction object) { |
| 77 | Symbol sym = expFactory.createSymbol(); |
| 78 | sym.setName("Start_"+object.getId()); |
| 79 | |
| 80 | Sequence seq = expFactory.createSequence(); |
| 81 | seq.setLeftRegExp(sym); |
| 82 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor_AbstractAction())); |
| 83 | return seq; |
| 84 | } |
| 85 | |
| 86 | @Override |
| 87 | public Object caseStopAction(StopAction object) { |
| 88 | Symbol sym = expFactory.createSymbol(); |
| 89 | sym.setName("Stop_"+object.getId()); |
| 90 | return sym; |
| 91 | } |
| 92 | |
| 93 | @Override |
| 94 | public Object caseInternalAction(InternalAction object) { |
| 95 | return handleSymbol(object); |
| 96 | } |
| 97 | |
| 98 | @Override |
| 99 | public Object caseSetVariableAction(SetVariableAction object) { |
| 100 | return handleSymbol(object); |
| 101 | } |
| 102 | |
| 103 | @Override |
| 104 | public Object caseExternalCallAction(ExternalCallAction object) { |
| 105 | |
| 106 | ResourceDemandingSEFF seff = (ResourceDemandingSEFF)myContextWrapper.getNextSEFF(object); |
| 107 | if (seff == null){ |
| 108 | // this is a system external call |
| 109 | // we continue with the internal action added after this action |
| 110 | return doSwitch(object.getSuccessor_AbstractAction()); |
| 111 | } else { |
| 112 | ContextWrapper oldContextWrapper = (ContextWrapper)myContextWrapper.clone(); |
| 113 | |
| 114 | List<ContextWrapper> contextWrapperList = myContextWrapper.getContextWrapperFor(object); |
| 115 | List<Option> optionsPerContextWrapperList = new LinkedList<Option>(); |
| 116 | for (ContextWrapper contextWrapper : contextWrapperList) { |
| 117 | myContextWrapper = contextWrapper; |
| 118 | //Sequence seq = expFactory.createSequence(); |
| 119 | //seq.setLeftRegExp((Expression)doSwitch(seff)); |
| 120 | |
| 121 | Option option = expFactory.createOption(); |
| 122 | option.setRegexp((Expression)doSwitch(seff)); |
| 123 | option.setProbability(1/contextWrapperList.size()); |
| 124 | optionsPerContextWrapperList.add(option); |
| 125 | } |
| 126 | Expression exp = null; |
| 127 | if (optionsPerContextWrapperList.size() == 1){ |
| 128 | exp = optionsPerContextWrapperList.get(0).getRegexp(); |
| 129 | } else { |
| 130 | exp = Pcm2RegexHelper.createAlternativesForExpressions(optionsPerContextWrapperList); |
| 131 | } |
| 132 | |
| 133 | myContextWrapper = oldContextWrapper; |
| 134 | Sequence seq = expFactory.createSequence(); |
| 135 | seq.setLeftRegExp(exp); |
| 136 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor_AbstractAction())); |
| 137 | |
| 138 | return seq; |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | @Override |
| 143 | public Object caseBranchAction(BranchAction object) { |
| 144 | List<Option> optionsForBranches = new LinkedList<Option>(); |
| 145 | |
| 146 | for (AbstractBranchTransition branch : object.getBranches_Branch()) { |
| 147 | Option option = expFactory.createOption(); |
| 148 | option.setProbability(myContextWrapper.getBranchProbability(branch)); |
| 149 | Expression branchExpression = (Expression)doSwitch(branch.getBranchBehaviour_BranchTransition()); |
| 150 | option.setRegexp(branchExpression); |
| 151 | |
| 152 | optionsForBranches.add(option); |
| 153 | } |
| 154 | Expression alt = Pcm2RegexHelper.createAlternativesForExpressions(optionsForBranches); |
| 155 | |
| 156 | Sequence seq = expFactory.createSequence(); |
| 157 | seq.setLeftRegExp(alt); |
| 158 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor_AbstractAction())); |
| 159 | |
| 160 | return seq; |
| 161 | } |
| 162 | |
| 163 | @Override |
| 164 | public Object caseCollectionIteratorAction(CollectionIteratorAction object) { |
| 165 | de.uka.ipd.sdq.spa.expression.Loop loop = expFactory.createLoop(); |
| 166 | loop.setIterationsString(myContextWrapper.getLoopIterations(object).toString()); |
| 167 | loop.setRegExp((Expression)doSwitch(object.getBodyBehaviour_Loop())); |
| 168 | |
| 169 | Sequence seq = expFactory.createSequence(); |
| 170 | seq.setLeftRegExp(loop); |
| 171 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor_AbstractAction())); |
| 172 | |
| 173 | return seq; |
| 174 | } |
| 175 | |
| 176 | |
| 177 | @Override |
| 178 | public Object caseLoopAction(LoopAction object) { |
| 179 | de.uka.ipd.sdq.spa.expression.Loop loop = expFactory.createLoop(); |
| 180 | loop.setIterationsString(myContextWrapper.getLoopIterations(object).toString()); |
| 181 | loop.setRegExp((Expression)doSwitch(object.getBodyBehaviour_Loop())); |
| 182 | |
| 183 | Sequence seq = expFactory.createSequence(); |
| 184 | seq.setLeftRegExp(loop); |
| 185 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor_AbstractAction())); |
| 186 | |
| 187 | return seq; |
| 188 | } |
| 189 | |
| 190 | private Object handleSymbol(AbstractInternalControlFlowAction object){ |
| 191 | Symbol sym = expFactory.createSymbol(); |
| 192 | sym.setName(object.getEntityName()); |
| 193 | |
| 194 | EList<ParametricResourceDemand> prdList = object.getResourceDemand_Action(); |
| 195 | for (ParametricResourceDemand prd : prdList){ |
| 196 | |
| 197 | String spec = myContextWrapper.getTimeConsumptionAsPDF(prd).toString(); |
| 198 | |
| 199 | Atom resDemExpression = (Atom)ExpressionHelper.parseToExpression(spec); |
| 200 | ProbabilityDensityFunction pdf = null; |
| 201 | if (resDemExpression instanceof NumericLiteral){ |
| 202 | NumericLiteral resDemNumeric = (NumericLiteral)resDemExpression; |
| 203 | pdf = getPDFForNumericLiteral(pdf, resDemNumeric); |
| 204 | } else if (resDemExpression instanceof ProbabilityFunctionLiteral){ |
| 205 | ProbabilityFunctionLiteral probFuncLiteral = (ProbabilityFunctionLiteral) resDemExpression; |
| 206 | ProbabilityFunction probFunc = probFuncLiteral |
| 207 | .getFunction_ProbabilityFunctionLiteral(); |
| 208 | if (probFunc instanceof ProbabilityDensityFunction){ |
| 209 | pdf = (ProbabilityDensityFunction)probFunc; |
| 210 | } else{ |
| 211 | logger.error("Invalid Resource Demand: ("+probFunc.getClass().getSimpleName()+"). Only DoublePDF is valid."); |
| 212 | return null; |
| 213 | } |
| 214 | } else { |
| 215 | logger.error("Invalid Resource Demand: ("+resDemExpression.getClass().getSimpleName()+"). Only DoublePDF is valid."); |
| 216 | return null; |
| 217 | } |
| 218 | |
| 219 | ResourceUsage ru = resFactory.createResourceUsage(); |
| 220 | ru.setUsageTime(pdf); |
| 221 | |
| 222 | sym.getResourceUsages().add(ru); |
| 223 | } |
| 224 | |
| 225 | Sequence seq = expFactory.createSequence(); |
| 226 | seq.setLeftRegExp(sym); |
| 227 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor_AbstractAction())); |
| 228 | return seq; |
| 229 | } |
| 230 | |
| 231 | private ProbabilityDensityFunction getPDFForNumericLiteral( |
| 232 | ProbabilityDensityFunction pdf, NumericLiteral resDemNumeric) { |
| 233 | |
| 234 | PDFConfiguration config = null; |
| 235 | try { |
| 236 | config = PDFConfiguration.getCurrentConfiguration(); |
| 237 | } catch (ConfigurationNotSetException e) { |
| 238 | e.printStackTrace(); |
| 239 | } |
| 240 | |
| 241 | double distance = config.getDistance(); |
| 242 | int numOfSamples = config.getNumSamplingPoints(); |
| 243 | IUnit unit = config.getUnit(); |
| 244 | |
| 245 | double value = 0; |
| 246 | if (resDemNumeric instanceof DoubleLiteral){ |
| 247 | value = ((DoubleLiteral) resDemNumeric).getValue() ; |
| 248 | } else if (resDemNumeric instanceof IntLiteral){ |
| 249 | value = ((IntLiteral) resDemNumeric).getValue(); |
| 250 | } |
| 251 | value = value / distance; |
| 252 | |
| 253 | if (value != 0.0){ |
| 254 | if (value > numOfSamples){ |
| 255 | numOfSamples = (int)value+1; |
| 256 | PDFConfiguration.setCurrentConfiguration(numOfSamples, distance, unit); |
| 257 | logger.debug("Reset PDFConfiguration: numOfSamples=" + |
| 258 | numOfSamples+", distance="+distance+", unit="+unit.getUnitName()); |
| 259 | } else if (value < distance){ |
| 260 | PDFConfiguration.setCurrentConfiguration(numOfSamples, value, unit); |
| 261 | logger.debug("Reset PDFConfiguration: numOfSamples=" + |
| 262 | numOfSamples+", distance="+value+", unit="+unit.getUnitName()); |
| 263 | |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | List<Double> sampleList = new ArrayList<Double>(); |
| 268 | for (int i=0; i<numOfSamples; i++){ |
| 269 | if (i == (int)value){ |
| 270 | sampleList.add(new Double(1.0)); |
| 271 | } else { |
| 272 | sampleList.add(new Double(0.0)); |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | ISamplePDF iSamplePDF = pfFactory.createSamplePDFFromDouble(distance, sampleList, unit); |
| 277 | try { |
| 278 | SamplePDF samplePDF = pfFactory.transformToModelSamplePDF(iSamplePDF); |
| 279 | pdf = samplePDF; |
| 280 | } catch (UnknownPDFTypeException e) { |
| 281 | e.printStackTrace(); |
| 282 | } |
| 283 | return pdf; |
| 284 | } |
| 285 | |
| 286 | |
| 287 | private StartAction getStartAction(ResourceDemandingBehaviour behaviour) { |
| 288 | StartAction startAction = (StartAction) EMFQueryHelper.getObjectByType( |
| 289 | behaviour.getSteps_Behaviour(), StartAction.class); |
| 290 | return startAction; |
| 291 | } |
| 292 | |
| 293 | } |