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 | } |