EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.stoex.analyser.visitors]

COVERAGE SUMMARY FOR SOURCE FILE [ExpressionSolveVisitor.java]

nameclass, %method, %block, %line, %
ExpressionSolveVisitor.java0%   (0/2)0%   (0/43)0%   (0/1895)0%   (0/382)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ExpressionSolveVisitor0%   (0/1)0%   (0/41)0%   (0/1856)0%   (0/378)
$SWITCH_TABLE$de$uka$ipd$sdq$stoex$analyser$visitors$TypeEnum (): int [] 0%   (0/1)0%   (0/104)0%   (0/1)
<static initializer> 0%   (0/1)0%   (0/5)0%   (0/3)
ExpressionSolveVisitor (HashMap): void 0%   (0/1)0%   (0/15)0%   (0/7)
caseBoolLiteral (BoolLiteral): Object 0%   (0/1)0%   (0/22)0%   (0/6)
caseBooleanOperatorExpression (BooleanOperatorExpression): Object 0%   (0/1)0%   (0/44)0%   (0/9)
caseCompareExpression (CompareExpression): Object 0%   (0/1)0%   (0/80)0%   (0/17)
caseDoubleLiteral (DoubleLiteral): Object 0%   (0/1)0%   (0/2)0%   (0/1)
caseFunctionLiteral (FunctionLiteral): ProbabilityFunctionLiteral 0%   (0/1)0%   (0/127)0%   (0/24)
caseIfElseExpression (IfElseExpression): Object 0%   (0/1)0%   (0/113)0%   (0/22)
caseIntLiteral (IntLiteral): Object 0%   (0/1)0%   (0/2)0%   (0/1)
caseNotExpression (NotExpression): Object 0%   (0/1)0%   (0/26)0%   (0/6)
caseParenthesis (Parenthesis): Object 0%   (0/1)0%   (0/8)0%   (0/2)
casePowerExpression (PowerExpression): Object 0%   (0/1)0%   (0/30)0%   (0/7)
caseProbabilityFunctionLiteral (ProbabilityFunctionLiteral): Object 0%   (0/1)0%   (0/2)0%   (0/1)
caseProductExpression (ProductExpression): Object 0%   (0/1)0%   (0/60)0%   (0/12)
caseStringLiteral (StringLiteral): Object 0%   (0/1)0%   (0/2)0%   (0/1)
caseTermExpression (TermExpression): Object 0%   (0/1)0%   (0/51)0%   (0/10)
caseVariable (Variable): Object 0%   (0/1)0%   (0/2)0%   (0/1)
createLiteralForIPDF (IProbabilityDensityFunction): Expression 0%   (0/1)0%   (0/28)0%   (0/11)
createLiteralForIPMF (IProbabilityMassFunction): ProbabilityFunctionLiteral 0%   (0/1)0%   (0/14)0%   (0/6)
extractDoubleFromLiteral (Expression): double 0%   (0/1)0%   (0/20)0%   (0/6)
extractIPDFFromLiteral (Expression): IProbabilityDensityFunction 0%   (0/1)0%   (0/28)0%   (0/11)
extractIPMFFromLiteral (Expression): IProbabilityMassFunction 0%   (0/1)0%   (0/56)0%   (0/12)
extractIntFromLiteral (Expression): int 0%   (0/1)0%   (0/4)0%   (0/1)
extractStringFromLiteral (Expression): String 0%   (0/1)0%   (0/4)0%   (0/1)
getDoubleFromNumericLiteral (Expression): double 0%   (0/1)0%   (0/26)0%   (0/8)
getFunctionType (Expression): TypeEnum 0%   (0/1)0%   (0/2)0%   (0/1)
handle (IProbabilityDensityFunction, IProbabilityDensityFunction, TermProduct... 0%   (0/1)0%   (0/32)0%   (0/12)
handle (IProbabilityDensityFunction, double, TermProductOperation): Expression 0%   (0/1)0%   (0/18)0%   (0/6)
handle (IProbabilityMassFunction, IProbabilityMassFunction, TermProductOperat... 0%   (0/1)0%   (0/23)0%   (0/7)
handle (IProbabilityMassFunction, double, TermProductOperation): ProbabilityF... 0%   (0/1)0%   (0/18)0%   (0/6)
handle (double, double, TermProductOperation): DoubleLiteral 0%   (0/1)0%   (0/14)0%   (0/4)
handle (int, int, TermProductOperation): IntLiteral 0%   (0/1)0%   (0/14)0%   (0/4)
handleComparison (Expression, Expression, CompareOperation): Object 0%   (0/1)0%   (0/140)0%   (0/24)
handleComputation (TypeEnum, Expression, Expression, TermProductOperation): E... 0%   (0/1)0%   (0/474)0%   (0/79)
handleLogical (Expression, Expression, LogicalOperation): Object 0%   (0/1)0%   (0/28)0%   (0/6)
isIntDouble (Expression): boolean 0%   (0/1)0%   (0/10)0%   (0/1)
isProbFunc (Expression): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isString (Expression): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
resolveActualType (TypeEnum, Expression): TypeEnum 0%   (0/1)0%   (0/43)0%   (0/13)
truncPMFFromBoxedPDF (BoxedPDF, FunctionLiteral): ProbabilityFunctionLiteral 0%   (0/1)0%   (0/159)0%   (0/27)
     
class UnsupportedComputationException0%   (0/1)0%   (0/2)0%   (0/39)0%   (0/4)
UnsupportedComputationException (Expression, Expression, TermProductOperation... 0%   (0/1)0%   (0/24)0%   (0/2)
UnsupportedComputationException (Expression, String): void 0%   (0/1)0%   (0/15)0%   (0/2)

1package de.uka.ipd.sdq.stoex.analyser.visitors;
2 
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6 
7import org.apache.log4j.Logger;
8 
9import de.uka.ipd.sdq.probfunction.BoxedPDF;
10import de.uka.ipd.sdq.probfunction.ContinuousSample;
11import de.uka.ipd.sdq.probfunction.ProbabilityDensityFunction;
12import de.uka.ipd.sdq.probfunction.ProbabilityFunction;
13import de.uka.ipd.sdq.probfunction.ProbabilityMassFunction;
14import de.uka.ipd.sdq.probfunction.ProbfunctionFactory;
15import de.uka.ipd.sdq.probfunction.Sample;
16import de.uka.ipd.sdq.probfunction.math.IProbabilityDensityFunction;
17import de.uka.ipd.sdq.probfunction.math.IProbabilityFunctionFactory;
18import de.uka.ipd.sdq.probfunction.math.IProbabilityMassFunction;
19import de.uka.ipd.sdq.probfunction.math.ISample;
20import de.uka.ipd.sdq.probfunction.math.ISamplePDF;
21import de.uka.ipd.sdq.probfunction.math.exception.DifferentDomainsException;
22import de.uka.ipd.sdq.probfunction.math.exception.DomainNotNumbersException;
23import de.uka.ipd.sdq.probfunction.math.exception.DoubleSampleException;
24import de.uka.ipd.sdq.probfunction.math.exception.FunctionNotInTimeDomainException;
25import de.uka.ipd.sdq.probfunction.math.exception.FunctionsInDifferenDomainsException;
26import de.uka.ipd.sdq.probfunction.math.exception.IncompatibleUnitsException;
27import de.uka.ipd.sdq.probfunction.math.exception.ProbabilitySumNotOneException;
28import de.uka.ipd.sdq.probfunction.math.exception.UnknownPDFTypeException;
29import de.uka.ipd.sdq.stoex.BoolLiteral;
30import de.uka.ipd.sdq.stoex.BooleanOperatorExpression;
31import de.uka.ipd.sdq.stoex.CompareExpression;
32import de.uka.ipd.sdq.stoex.DoubleLiteral;
33import de.uka.ipd.sdq.stoex.Expression;
34import de.uka.ipd.sdq.stoex.FunctionLiteral;
35import de.uka.ipd.sdq.stoex.IfElseExpression;
36import de.uka.ipd.sdq.stoex.IntLiteral;
37import de.uka.ipd.sdq.stoex.NotExpression;
38import de.uka.ipd.sdq.stoex.NumericLiteral;
39import de.uka.ipd.sdq.stoex.Parenthesis;
40import de.uka.ipd.sdq.stoex.PowerExpression;
41import de.uka.ipd.sdq.stoex.ProbabilityFunctionLiteral;
42import de.uka.ipd.sdq.stoex.ProductExpression;
43import de.uka.ipd.sdq.stoex.StoexFactory;
44import de.uka.ipd.sdq.stoex.StringLiteral;
45import de.uka.ipd.sdq.stoex.TermExpression;
46import de.uka.ipd.sdq.stoex.Variable;
47import de.uka.ipd.sdq.stoex.analyser.operations.AddOperation;
48import de.uka.ipd.sdq.stoex.analyser.operations.AndOperation;
49import de.uka.ipd.sdq.stoex.analyser.operations.CompareOperation;
50import de.uka.ipd.sdq.stoex.analyser.operations.DivOperation;
51import de.uka.ipd.sdq.stoex.analyser.operations.EqualsOperation;
52import de.uka.ipd.sdq.stoex.analyser.operations.GreaterEqualOperation;
53import de.uka.ipd.sdq.stoex.analyser.operations.GreaterOperation;
54import de.uka.ipd.sdq.stoex.analyser.operations.LessEqualOperation;
55import de.uka.ipd.sdq.stoex.analyser.operations.LessOperation;
56import de.uka.ipd.sdq.stoex.analyser.operations.LogicalOperation;
57import de.uka.ipd.sdq.stoex.analyser.operations.ModOperation;
58import de.uka.ipd.sdq.stoex.analyser.operations.MultOperation;
59import de.uka.ipd.sdq.stoex.analyser.operations.NotEqualOperation;
60import de.uka.ipd.sdq.stoex.analyser.operations.OrOperation;
61import de.uka.ipd.sdq.stoex.analyser.operations.SubOperation;
62import de.uka.ipd.sdq.stoex.analyser.operations.TermProductOperation;
63import de.uka.ipd.sdq.stoex.analyser.probfunction.ProbfunctionHelper;
64import de.uka.ipd.sdq.stoex.util.StoexSwitch;
65 
66/**
67 * A visitor for stochastic expressions, which evaluates
68 * the operations within a expression and returns the
69 * resulting expression, which does not contain any operation
70 * any more.
71 * For example, when a stochastic expression contains a 
72 * division operation between a INT_PMF and a constant it
73 * returns an INT_PMF divided by the constant.
74 * The visitor is invoked as usual via the 
75 * doSwitch(Expression toSolve) command. It returns the solved
76 * expression. 
77 * This class uses the operations in 
78 * de.uka.ipd.sdq.stoex.analyser.operations as an interface
79 * to the probability function package.
80 * 
81 * @author koziolek
82 */
83public class ExpressionSolveVisitor extends StoexSwitch<Object> {
84 
85        private static Logger logger = Logger
86                        .getLogger(ExpressionSolveVisitor.class.getName());
87        
88        /**
89         * For the Trunc function with a DoublePDF parameter, the DoublePDF is 
90         * transformed into an IntPMF. Here, a sample is generated for each 
91         * integer lying in the range of the DoublePDF. This can easily cause an
92         * OutOfMemoryException, thus, we constraint the maximum number of samples here. 
93         * Then, only each e.g. third integer value is used if the interval is too large 
94         */
95        private static final int MAX_NUMBER_OF_SAMPLES_FOR_TRUNC =1000;
96 
97        protected IProbabilityFunctionFactory iProbFuncFactory = 
98                IProbabilityFunctionFactory.eINSTANCE;
99 
100        protected ProbfunctionFactory probFuncFactory = ProbfunctionFactory.eINSTANCE;
101 
102        protected StoexFactory stocFactory = StoexFactory.eINSTANCE;
103 
104        protected HashMap<Expression, TypeEnum> typeAnnotation;
105 
106        /**
107         * Constructor storing the evaluated type annotations.
108         * @param typeAnn
109         */
110        public ExpressionSolveVisitor(HashMap<Expression, TypeEnum> typeAnn) {
111                this.typeAnnotation = typeAnn;
112        }
113 
114        /**
115         * Performs compare operations.
116         */
117        public Object caseCompareExpression(CompareExpression expr){
118                String opName = expr.getOperation().getName();
119                CompareOperation op;
120                if (opName.equals("GREATER"))
121                        op = new GreaterOperation();
122                else if(opName.equals("EQUALS"))
123                        op = new EqualsOperation();
124                else if(opName.equals("LESS"))
125                        op = new LessOperation();
126                else if(opName.equals("NOTEQUAL"))
127                        op = new NotEqualOperation();
128                else if(opName.equals("GREATEREQUAL"))
129                        op = new GreaterEqualOperation();
130                else if(opName.equals("LESSEQUAL"))
131                        op = new LessEqualOperation();
132                else
133                        throw new UnsupportedOperationException();
134                
135                Expression left = (Expression) doSwitch(expr.getLeft());
136                Expression right = (Expression) doSwitch(expr.getRight());
137                
138                return handleComparison(left, right, op);
139        }
140 
141        /**
142         * Performs logical operations (AND, OR).
143         */
144        public Object caseBooleanOperatorExpression(BooleanOperatorExpression expr) {
145 
146                String opName = expr.getOperation().getName();
147                LogicalOperation op;
148                if (opName.equals("AND"))
149                        op = new AndOperation();
150                else if(opName.equals("OR"))
151                        op = new OrOperation();
152                else
153                        throw new UnsupportedOperationException();
154 
155                Expression left = (Expression) doSwitch(expr.getLeft());
156                Expression right = (Expression) doSwitch(expr.getRight());
157 
158                return handleLogical(left, right, op);
159        }
160 
161        /**
162         * Performs term operations (ADD, SUB)
163         */
164        public Object caseTermExpression(TermExpression expr) {
165                String opName = expr.getOperation().getName();
166                TermProductOperation op;
167                if (opName.equals("ADD"))
168                        op = new AddOperation();
169                else if (opName.equals("SUB"))
170                        op = new SubOperation();
171                else
172                        throw new UnsupportedOperationException();
173 
174                Expression left = (Expression) doSwitch(expr.getLeft());
175                Expression right = (Expression) doSwitch(expr.getRight());
176                TypeEnum exprType = this.typeAnnotation.get(expr); 
177 
178                return handleComputation(exprType, left, right, op);
179        }
180        
181        /**
182         * Performs product operations (MULT, DIV, MOD).
183         */
184        public Object caseProductExpression(ProductExpression expr) {
185                String opName = expr.getOperation().getName();
186                TermProductOperation op;
187                if (opName.equals("MULT"))
188                        op = new MultOperation();
189                else if (opName.equals("DIV"))
190                        op = new DivOperation();
191                else if (opName.equals("MOD"))
192                        op = new ModOperation();
193                else 
194                        throw new UnsupportedOperationException();
195 
196                Expression left = (Expression) doSwitch(expr.getLeft());
197                Expression right = (Expression) doSwitch(expr.getRight());
198                TypeEnum exprType = this.typeAnnotation.get(expr); 
199                        
200 
201                return handleComputation(exprType, left, right, op);
202        }
203        
204        @Override
205        public Object caseIfElseExpression(IfElseExpression expr) {
206 
207                // first get the probability function from the condition expression and determine the if-probability
208                ProbabilityFunctionLiteral conditionExpr = (ProbabilityFunctionLiteral) doSwitch(expr.getConditionExpression());
209                ProbabilityMassFunction pmf = (ProbabilityMassFunction)conditionExpr.getFunction_ProbabilityFunctionLiteral();
210                 
211                double ifProb = 1.0;
212                List<Sample> points = pmf.getSamples();
213                for (Sample point : points) {
214                        String bool = point.getValue().toString();
215                        if (bool.toLowerCase().equals("true")) {
216                                ifProb = point.getProbability();
217                        }
218                }
219                
220                // now build a new DoublePMF to replace the IfElseExpression
221                Expression ifExpr = (Expression) doSwitch(expr.getIfExpression());
222                Expression elseExpr = (Expression) doSwitch(expr.getElseExpression());
223                
224                if (ifExpr instanceof NumericLiteral && elseExpr instanceof NumericLiteral){
225                        // we only support NumericLiterals here, i.e., INT or DOUBLE. 
226                        List<ISample> newPoints = new ArrayList<ISample>();
227                        double ifValue = getDoubleFromNumericLiteral(ifExpr);
228                        newPoints.add(iProbFuncFactory.createSample(ifValue, ifProb));
229                        double elseValue = getDoubleFromNumericLiteral(elseExpr);
230                        newPoints.add(iProbFuncFactory.createSample(elseValue, 1-ifProb));
231                        
232                        IProbabilityMassFunction iPMF = iProbFuncFactory.createProbabilityMassFunction(newPoints, null, false);
233                        ProbabilityMassFunction resultPMF = iProbFuncFactory.transformToModelPMF(iPMF);
234                        ProbabilityFunctionLiteral resultPMFLiteral = stocFactory.createProbabilityFunctionLiteral();
235                        resultPMFLiteral.setFunction_ProbabilityFunctionLiteral(resultPMF);
236                        return resultPMFLiteral;
237                } else 
238                        // any probability functions involved are not supported:
239                        throw new UnsupportedOperationException();
240        }
241 
242        /** 
243         * Forwards the visitor to the inner expression within the parenthesis.
244         */
245        public Object caseParenthesis(Parenthesis parenthesis) {
246                Expression child = (Expression)doSwitch(parenthesis.getInnerExpression());
247                return child;
248        }
249 
250        /** 
251         * Skips variables. This visitor cannot handle variables. Use the
252         * PCM Solver to handle variables in stochastic expressions.
253         */
254        public Object caseVariable(Variable var){
255                // Cannot handle variables! Use inheritance to add this.
256                return var;
257        }
258        
259        /**
260         * Creates a BoolPMF for the given BoolLiteral.
261         */
262        public Object caseBoolLiteral(BoolLiteral bl) {
263                EqualsOperation eo = new EqualsOperation();
264                IProbabilityMassFunction iPMF = null;
265                if (bl.isValue()){
266                        iPMF = eo.getBoolPMF(1.0);
267                } else {
268                        iPMF = eo.getBoolPMF(0.0);
269                }
270                return createLiteralForIPMF(iPMF);
271        }
272 
273        /**
274         * Just returns the given int literal.
275         */
276        public Object caseIntLiteral(IntLiteral il) {
277                return il;
278        }
279 
280        /**
281         * Just returns the given double literal.
282         */
283        public Object caseDoubleLiteral(DoubleLiteral dl) {
284                return dl;
285        }
286 
287        
288        @Override
289        public Object caseStringLiteral(StringLiteral object) {
290                // TODO Auto-generated method stub
291                return object;
292        }
293 
294        /**
295         * Just returns the given probfunction literal.
296         */
297        public Object caseProbabilityFunctionLiteral(
298                        ProbabilityFunctionLiteral probFuncLit) {
299                return probFuncLit;
300        }
301 
302        /**
303         * Performs a power operation (only for constants).
304         */
305        public Object casePowerExpression(PowerExpression expr) {
306                Expression base = (Expression) doSwitch(expr.getBase());
307                Expression exponent = (Expression) doSwitch(expr.getExponent());
308                
309                double baseValue = getDoubleFromNumericLiteral(base);
310                double exponentValue = getDoubleFromNumericLiteral(exponent);
311                
312                DoubleLiteral doubleLiteral = StoexFactory.eINSTANCE.createDoubleLiteral();
313                doubleLiteral.setValue(Math.pow(baseValue, exponentValue));
314                
315                return doubleLiteral;
316        }
317        
318        @Override
319        public ProbabilityFunctionLiteral caseFunctionLiteral(FunctionLiteral object) {
320                for (Expression e : object.getParameters_FunctionLiteral())
321                        doSwitch(e);
322                
323                List<Expression> parameterList = new ArrayList<Expression>();
324                for (Expression parameter : object.getParameters_FunctionLiteral()) {
325                        parameterList.add((Expression)doSwitch(parameter));
326                }
327                
328                if (ProbfunctionHelper.isFunctionID(object.getId())){
329                        ProbabilityFunction func = ProbfunctionHelper.createFunction(parameterList, object.getId(), probFuncFactory);
330                        ProbabilityFunctionLiteral literal = StoexFactory.eINSTANCE.createProbabilityFunctionLiteral();
331                        literal.setFunction_ProbabilityFunctionLiteral(func);
332                        return literal;
333                } else        if (object.getId().equals("Trunc")) {
334                        //Create an equivalent ProbabilityMassFunction or Integer from the given expression.
335                        
336                        //Trunc must only have one parameter 
337                        if (object.getParameters_FunctionLiteral().size() == 1){
338                                Expression solvedParam = parameterList.get(0);
339                                //Parameter for Trunc must can be a DoublePDF or a DoubleLiteral? 
340                                if (solvedParam instanceof ProbabilityFunctionLiteral){
341                                        ProbabilityFunctionLiteral pfl = (ProbabilityFunctionLiteral)solvedParam;
342                                        ProbabilityFunction insideFunction = pfl.getFunction_ProbabilityFunctionLiteral();
343                                        if (insideFunction instanceof BoxedPDF){
344                                                //create a ProbabilityMassFunction for this BoxedPDF
345                                                return truncPMFFromBoxedPDF((BoxedPDF)insideFunction, object);
346                                        }
347                                } else if (solvedParam instanceof DoubleLiteral) {
348                                                IntLiteral intLit = StoexFactory.eINSTANCE.createIntLiteral();
349                                                intLit.setValue((int)Math.round(((DoubleLiteral)solvedParam).getValue()));
350                                } else
351                                        throw new ExpressionSolvingFailedException("Function Trunc is only supported supported for a DoublePDF or a single double parameter!", object);
352                        }
353                }  else 
354                        throw new UnsupportedOperationException("Function "+object.getId()+" not supported!");
355                return null;
356        }
357 
358        /**
359         * Returns the result of interpreting the object as an instance of '<em>Not Expression</em>'.
360         * <!-- begin-user-doc -->
361         * This implementation casts the result of its inner expression to boolean and returns the 
362         * resulting values. If it cannot be cast to Boolean or BoolPMF, an exception is thrown. 
363         * <!-- end-user-doc -->
364         * @param notExpression the target of the switch.
365         * @return the result of interpreting the object as an instance of '<em>Not Expression</em>'.
366         * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
367         * @generated
368         */
369        @Override
370        public Object caseNotExpression(NotExpression notExpression) {
371                Expression child = (Expression)doSwitch(notExpression.getInner());
372                
373                if (child instanceof ProbabilityFunctionLiteral){
374                        IProbabilityMassFunction massFunction = extractIPMFFromLiteral(child);
375                        IProbabilityMassFunction invertedFunction = CompareOperation.invertBoolPMF(massFunction);
376                        return createLiteralForIPMF(invertedFunction);
377                        
378                } else {
379                        throw new UnsupportedComputationException(notExpression, "NOT");
380                }
381 
382        }
383 
384 
385        /**
386         * Converts a PDF to an IntPMF for the Trunc function. This is just a rough estimates. Especially for small values, it is far from the original. 
387         * 
388         * The Boundaries of the PDF are rounded down to the next integer. Then, the possible integer values are evenly distributed with the probability of the respective ContinousSample.
389         * If no integer value exists between two ContinousSamples, their probabilities are added. 
390         * 
391         * In this way, the distribution is changed a lot for small values. For large values, it does not matter. 
392         * 
393         * If the range of the whole PDF is too small, the closest surrounding integers is used with probability one.   
394         *   
395         * Maybe this should be moved in the probfunction package. 
396         * 
397         * @param pdf
398         * @param object
399         * @return
400         */
401        @SuppressWarnings("unchecked")
402        private ProbabilityFunctionLiteral truncPMFFromBoxedPDF(BoxedPDF pdf, FunctionLiteral object) {
403                
404                List<ContinuousSample> samples = pdf.getSamples();
405                
406                if (samples.size() == 0){
407                        throw new ExpressionSolvingFailedException("Cannot handle an empty DoublePDF for Trunc.",object);
408                }
409                double leftBorder = samples.get(0).getProbability() > 0 ? samples.get(0).getValue() : 0;
410                int range = (int)Math.ceil(samples.get(samples.size()-1).getValue() - leftBorder);
411                
412                int distance = range / MAX_NUMBER_OF_SAMPLES_FOR_TRUNC + 1;
413                
414                ISamplePDF samplePDF = null;
415                try {
416                        samplePDF = iProbFuncFactory.transformToSamplePDF(iProbFuncFactory.transformToPDF(pdf),distance);
417                } catch (Exception e) {
418                        throw new ExpressionSolvingFailedException(object, e);
419                } 
420                
421                if (samplePDF.getLowerDomainBorder() < 0){
422                        throw new ExpressionSolvingFailedException("Cannot Trunc a DoublePDF with negative values.",object);
423                }
424                if (samplePDF.getDistance() != distance){
425                        throw new ExpressionSolvingFailedException("Bug! Distance of SamplePDF is not "+distance, object);
426                }
427                
428                ProbabilityMassFunction pmf = this.probFuncFactory.createProbabilityMassFunction();
429                
430                pmf.setOrderedDomain(true);
431                List<Double> probabilities = samplePDF.getValuesAsDouble();
432                
433                //TODO: There is a bug in the probfunction stuff
434                // input Trunc(DoublePDF[ (0.2; 0.30000000) (1.7; 0.20000000) (2.7; 0.50000000) ])
435                // results in IntPMF[ (0;1.0899999999999999) (1;0.13333333333333333) (2;0.4266666666666666) (3;0.10000000000000006) ]
436                // not too bad, but wrong. 
437                int numberOfSamples = samplePDF.numberOfSamples();
438                for (int i = 0; i < numberOfSamples; i++){
439                        Sample sample = this.probFuncFactory.createSample();
440                        sample.setProbability(probabilities.get(i));
441                        sample.setValue(i*distance);
442                        pmf.getSamples().add(sample);
443                }
444                
445                ProbabilityFunctionLiteral literal = StoexFactory.eINSTANCE.createProbabilityFunctionLiteral();
446                literal.setFunction_ProbabilityFunctionLiteral(pmf);
447                
448                logger.debug("Trunc result: "+new StoExPrettyPrintVisitor().prettyPrint(literal));
449                
450                return literal;
451        }
452 
453        /**
454         * @param base
455         */
456        private double getDoubleFromNumericLiteral(Expression base) {
457                
458                if (base instanceof IntLiteral){
459                        IntLiteral intLiteral = (IntLiteral)base;
460                        Integer intValue = intLiteral.getValue();
461                        return intValue.doubleValue();
462                } else if (base instanceof DoubleLiteral){
463                        DoubleLiteral doubleLiteral = (DoubleLiteral)base;
464                        return doubleLiteral.getValue();
465                } else
466                        throw new UnsupportedOperationException();
467        }
468 
469        /**
470         * @param left
471         * @param right
472         * @param op
473         * @return
474         */
475        private Object handleComparison(Expression left, Expression right,
476                        CompareOperation op) {
477                IProbabilityMassFunction iPMF = null;
478 
479                if (isIntDouble(left) && isIntDouble(right))
480                        iPMF = op.compare(extractDoubleFromLiteral(left),
481                                        extractDoubleFromLiteral(right));
482                else if (isProbFunc(left) && isIntDouble(right))
483                        iPMF = op.compare(extractIPMFFromLiteral(left),
484                                        extractDoubleFromLiteral(right));
485                else if (isIntDouble(left) && isProbFunc(right))
486                        iPMF = op.compare(extractDoubleFromLiteral(left),
487                                        extractIPMFFromLiteral(right));
488                else if (isProbFunc(left) && isProbFunc(right))
489                        iPMF = op.compare(extractIPMFFromLiteral(left),
490                                        extractIPMFFromLiteral(right));
491                else if (isString(left) && isString(right))
492                        iPMF = op.compare(extractStringFromLiteral(left),
493                                        extractStringFromLiteral(right));
494                else if (isString(left) && isProbFunc(right))
495                        iPMF = op.compare(extractStringFromLiteral(left),
496                                        extractIPMFFromLiteral(right));
497                else if (isString(right) && isProbFunc(left))
498                        iPMF = op.compare(extractStringFromLiteral(right),
499                                        extractIPMFFromLiteral(left));
500                else
501                        throw new UnsupportedOperationException();
502                
503                return createLiteralForIPMF(iPMF);
504        }
505 
506        private Object handleLogical(Expression left, Expression right,
507                        LogicalOperation op) {
508                IProbabilityMassFunction iPMF = null;
509                if (isProbFunc(left) && isProbFunc(right))
510                        iPMF = op.evaluate(extractIPMFFromLiteral(left),
511                                        extractIPMFFromLiteral(right));
512                else
513                        throw new UnsupportedOperationException();
514                
515                return createLiteralForIPMF(iPMF);
516        }
517 
518        private String extractStringFromLiteral(Expression left) {
519                return ((StringLiteral)left).getValue();
520        }
521 
522        private boolean isString(Expression expr) {
523                return expr instanceof StringLiteral;
524        }
525 
526        /**
527         * @param expr
528         * @param op
529         * @return
530         * @throws ProbabilitySumNotOneException
531         */
532        private Expression handleComputation(TypeEnum exprType, Expression left,
533                        Expression right, TermProductOperation op) {
534 
535                if (exprType == TypeEnum.ANY_PMF){
536                        if (left instanceof ProbabilityFunctionLiteral){
537                                exprType = resolveActualType(exprType, left);
538                        } else if (right instanceof ProbabilityFunctionLiteral){
539                                exprType = resolveActualType(exprType, right);
540                        } else if (left instanceof FunctionLiteral){
541                                exprType = ProbfunctionHelper.isFunctionID(((FunctionLiteral)left).getId()) ? TypeEnum.CONTINOUS_PROBFUNCTION : TypeEnum.AUX_FUNCTION;
542                        } else if (right instanceof FunctionLiteral){
543                                exprType = ProbfunctionHelper.isFunctionID(((FunctionLiteral)right).getId()) ? TypeEnum.CONTINOUS_PROBFUNCTION : TypeEnum.AUX_FUNCTION;
544                        } else if (left instanceof IntLiteral && right instanceof IntLiteral){
545                                //both are integers
546                                exprType = TypeEnum.INT;
547                        } else if (left instanceof NumericLiteral && right instanceof NumericLiteral){
548                                //both are double, or one is int, the other double. 
549                                exprType = TypeEnum.DOUBLE;
550                        } else 
551                                throw new UnsupportedComputationException(right, left, op, exprType);
552                }
553                
554                switch (exprType) {
555                case INT:
556                        return handle(extractIntFromLiteral(left),
557                                        extractIntFromLiteral(right), op);
558                case DOUBLE:
559                        return handle(extractDoubleFromLiteral(left),
560                                        extractDoubleFromLiteral(right), op);
561                case ANY_PMF:
562                        throw new UnsupportedComputationException(right, left, op, exprType);
563                case INT_PMF:
564                        if (left instanceof IntLiteral && right instanceof IntLiteral){
565                                // this case can happen because the 
566                                // typeAnnotation assumes INT_PMF as type
567                                // for some parameter characterisations
568                                // where in fact they could be composed just out 
569                                // of INTs in an expression
570                                return handle(extractIntFromLiteral(left),
571                                                extractIntFromLiteral(right), op);
572                        } else if (left instanceof IntLiteral 
573                                        && right instanceof ProbabilityFunctionLiteral) {
574                                return handle(extractIPMFFromLiteral(right),extractIntFromLiteral(left), op);
575                        } else if (left instanceof ProbabilityFunctionLiteral 
576                                        && right instanceof IntLiteral) {
577                                return handle(extractIPMFFromLiteral(left),extractIntFromLiteral(right), op);
578                        } else if (left instanceof ProbabilityFunctionLiteral
579                                        && right instanceof ProbabilityFunctionLiteral) {
580                                return handle(extractIPMFFromLiteral(left),extractIPMFFromLiteral(right), op);
581                        } else 
582                                throw new UnsupportedComputationException(right, left, op, exprType);
583                case DOUBLE_PMF:
584                        if (left instanceof NumericLiteral && right instanceof NumericLiteral) {
585                                return handle(extractDoubleFromLiteral(left), extractDoubleFromLiteral(right), op);
586                        } else if(left instanceof ProbabilityFunctionLiteral
587                                && right instanceof NumericLiteral){
588                                return handle(extractIPMFFromLiteral(left),extractDoubleFromLiteral(right), op);                                        
589                        } else if(left instanceof NumericLiteral
590                                && right instanceof ProbabilityFunctionLiteral){
591                                return handle(extractIPMFFromLiteral(right),extractDoubleFromLiteral(left), op);
592                        } else if(left instanceof ProbabilityFunctionLiteral 
593                                && right instanceof ProbabilityFunctionLiteral){
594                                return handle(extractIPMFFromLiteral(left), extractIPMFFromLiteral(right), op);
595                        } else 
596                                throw new UnsupportedComputationException(right, left, op, exprType);
597                case DOUBLE_PDF:
598                        if (left instanceof ProbabilityFunctionLiteral){
599                                if (right instanceof IntLiteral){
600                                        return handle(extractIPDFFromLiteral(left), extractIntFromLiteral(right), op);
601                                } else if (right instanceof DoubleLiteral){
602                                        return handle(extractIPDFFromLiteral(left), extractDoubleFromLiteral(right), op);
603                                } else if (right instanceof ProbabilityFunctionLiteral){
604                                        return handle(extractIPDFFromLiteral(left),extractIPDFFromLiteral(right), op);
605                                } else
606                                        throw new UnsupportedComputationException(right, left, op, exprType);
607                        } else if (right instanceof ProbabilityFunctionLiteral){
608                                if (left instanceof IntLiteral){
609                                        return handle(extractIPDFFromLiteral(right), extractIntFromLiteral(left), op);        
610                                } else if (left instanceof DoubleLiteral){
611                                        return handle(extractIPDFFromLiteral(right), extractDoubleFromLiteral(left), op);
612                                } else
613                                        throw new UnsupportedComputationException(right, left, op, exprType);
614                        } else
615                                throw new UnsupportedComputationException(right, left, op, exprType);
616                case CONTINOUS_PROBFUNCTION:
617                        if (left instanceof FunctionLiteral){
618                                if (right instanceof IntLiteral) {
619                                        double rightDouble = ((IntLiteral)right).getValue();
620                                        return handle(extractIPDFFromLiteral(caseFunctionLiteral((FunctionLiteral) left)),rightDouble, op);
621                                } else if (right instanceof DoubleLiteral){
622                                        double rightDouble = ((DoubleLiteral)right).getValue();
623                                        return handle(extractIPDFFromLiteral(caseFunctionLiteral((FunctionLiteral) left)),rightDouble, op);
624                                }        else throw new UnsupportedOperationException("I can only apply operation "+op.getClass().getName()+" to a function and an number, not more.");
625                        } if (right instanceof FunctionLiteral){
626                                if (left instanceof IntLiteral){
627                                        double leftDouble = ((IntLiteral)left).getValue();
628                                        return handle(extractIPDFFromLiteral(caseFunctionLiteral((FunctionLiteral) right)),leftDouble, op);        
629                                } else if (left instanceof DoubleLiteral){
630                                        double leftDouble = ((DoubleLiteral)left).getValue();
631                                        return handle(extractIPDFFromLiteral(caseFunctionLiteral((FunctionLiteral) right)),leftDouble, op);
632                                } else throw new UnsupportedOperationException("I can only apply operation "+op.getClass().getName()+" to a function and an number, not more.");
633                        } else throw new UnsupportedComputationException(right, left, op, exprType);
634                case AUX_FUNCTION:
635                        //TODO: 
636                        throw new UnsupportedOperationException("It is not yet supported to do calculations with auxiliary functions.");
637                        
638                }
639                return null;
640 
641        }
642 
643        private TypeEnum getFunctionType(Expression right) {
644                // TODO Auto-generated method stub
645                return null;
646        }
647 
648        private Expression handle(IProbabilityDensityFunction iLeftPDF, double right, TermProductOperation op) {
649                IProbabilityDensityFunction resultIPDF = null;
650 
651                try {
652                        resultIPDF = op.compute(iLeftPDF, right);
653                } catch (DomainNotNumbersException e) {
654                        logger.error("Calculation with PDF and Literal failed!");
655                        e.printStackTrace();
656                }
657                return createLiteralForIPDF(resultIPDF);
658        }
659 
660        /**
661         * @param exprType
662         * @param expr
663         * @return
664         */
665        private TypeEnum resolveActualType(TypeEnum exprType, Expression expr) {
666                ProbabilityFunctionLiteral pfl = (ProbabilityFunctionLiteral)expr;
667                ProbabilityFunction probFunc = pfl.getFunction_ProbabilityFunctionLiteral();
668                
669                if (probFunc instanceof ProbabilityMassFunction){
670                        IProbabilityMassFunction iPMF = extractIPMFFromLiteral(expr);
671                        ISample samplePoint = iPMF.getSamples().get(0);
672                        
673                        if (samplePoint.getValue() instanceof Integer){
674                                exprType = TypeEnum.INT_PMF;
675                        } else if (samplePoint.getValue() instanceof Double){
676                                exprType = TypeEnum.DOUBLE_PMF;
677                        }
678                        return exprType;
679                } else if (probFunc instanceof ProbabilityDensityFunction){
680                        return TypeEnum.DOUBLE_PDF;
681                } else
682                        throw new UnsupportedOperationException();
683                
684        }
685 
686        /**
687         * @param iLeftPDF
688         * @param iRightPDF
689         * @param op
690         * @return
691         */
692        private Expression handle(IProbabilityDensityFunction iLeftPDF, IProbabilityDensityFunction iRightPDF, TermProductOperation op) {
693                IProbabilityDensityFunction resultIPDF = null;
694                
695                try {
696                        resultIPDF = op.compute(iLeftPDF, iRightPDF);
697                } catch (FunctionsInDifferenDomainsException e){
698                        logger.error("Calculation with two PDFs failed!");
699                        e.printStackTrace();
700                } catch (UnknownPDFTypeException e){
701                        logger.error("Calculation with two PDFs failed!");
702                        e.printStackTrace();
703                } catch (IncompatibleUnitsException e){
704                        logger.error("Calculation with two PDFs failed!");
705                        e.printStackTrace();
706                }
707                //logger.debug("Result: "+resultIPDF.toString());
708 
709                return createLiteralForIPDF(resultIPDF);
710 
711        }
712 
713        /**
714         * @param resultIPMF
715         * @return
716         */
717        private ProbabilityFunctionLiteral createLiteralForIPMF(
718                        IProbabilityMassFunction resultIPMF) {
719                ProbabilityMassFunction resultPMF = iProbFuncFactory
720                                .transformToModelPMF(resultIPMF);
721                ProbabilityFunctionLiteral resultPMFLiteral = stocFactory
722                                .createProbabilityFunctionLiteral();
723                resultPMFLiteral.setFunction_ProbabilityFunctionLiteral(resultPMF);
724        
725                return resultPMFLiteral;
726        }
727 
728        /**
729         * @param iPDF
730         * @return
731         */
732        private Expression createLiteralForIPDF(IProbabilityDensityFunction iPDF) {
733                ProbabilityDensityFunction pdf = null;
734                try {
735                        pdf = iProbFuncFactory.transformToModelPDF(iPDF);
736                } catch (UnknownPDFTypeException e) {
737                        e.printStackTrace();
738                } catch (DoubleSampleException e) {
739                        e.printStackTrace();
740                } catch (FunctionNotInTimeDomainException e) {
741                        e.printStackTrace();
742                }
743                
744                ProbabilityFunctionLiteral resultPDFLiteral = stocFactory.createProbabilityFunctionLiteral();
745                resultPDFLiteral.setFunction_ProbabilityFunctionLiteral(pdf);
746 
747                return resultPDFLiteral;
748        }
749 
750        /**
751         * @param iLeftPMF
752         * @param iRightPMF
753         * @param operation
754         * @return
755         */
756        private ProbabilityFunctionLiteral handle(IProbabilityMassFunction iLeftPMF,
757                        IProbabilityMassFunction iRightPMF, TermProductOperation operation) {
758                IProbabilityMassFunction resultIPMF = null;
759                try {
760                        resultIPMF = operation.compute(iLeftPMF, iRightPMF);
761                } catch (DifferentDomainsException e) {
762                        logger.error("Calculation with two PMFs failed!");
763                        e.printStackTrace();
764                        throw new RuntimeException(e);
765                }
766                //logger.debug("Result: "+resultIPMF.getSamples().toString());
767                return createLiteralForIPMF(resultIPMF);
768        }
769 
770 
771        /**
772         * @param iIntPMF
773         * @param doubleValue
774         * @param operation
775         * @return
776         */
777        private ProbabilityFunctionLiteral handle(IProbabilityMassFunction iIntPMF,
778                        double doubleValue, TermProductOperation operation) {
779                IProbabilityMassFunction resultIPMF = null;
780                try {
781                        resultIPMF = operation.compute(iIntPMF, doubleValue);
782                } catch (Exception e) {
783                        logger.error("Calculation with PMF and int failed!");
784                        e.printStackTrace();
785                }
786                //logger.debug("Result: "+resultIPMF.getSamples().toString());
787                return createLiteralForIPMF(resultIPMF);
788        }
789 
790 
791        /**
792         * @param leftValue
793         * @param rightValue
794         * @param operation
795         * @return
796         */
797        private DoubleLiteral handle(double leftValue, double rightValue,
798                        TermProductOperation operation) {
799                DoubleLiteral result = stocFactory.createDoubleLiteral();
800                double resultValue = operation.compute(leftValue, rightValue);
801                result.setValue(resultValue);
802                return result;
803        }
804 
805 
806        /**
807         * @param leftValue
808         * @param rightValue
809         * @param operation
810         * @return
811         */
812        private IntLiteral handle(int leftValue, int rightValue,
813                        TermProductOperation operation) {
814                IntLiteral result = stocFactory.createIntLiteral();
815                int resultValue = operation.compute(leftValue, rightValue);
816                result.setValue(resultValue);
817                return result;
818        }
819 
820        /**
821         * @param expr
822         * @return
823         */
824        private boolean isProbFunc(Expression expr) {
825                return (expr instanceof ProbabilityFunctionLiteral);
826        }
827 
828        /**
829         * @param expr
830         * @return
831         */
832        private boolean isIntDouble(Expression expr) {
833                return (expr instanceof IntLiteral || expr instanceof DoubleLiteral);                
834        }
835 
836        /**
837         * @param expr
838         * @return
839         */
840        private double extractDoubleFromLiteral(Expression expr) {
841                if (expr instanceof IntLiteral) {
842                        return (double) ((IntLiteral) expr).getValue();
843                } else if (expr instanceof DoubleLiteral) {
844                        return (double) ((DoubleLiteral) expr).getValue();
845                } else {
846                        logger.error("Could not get Double value from NumericLiteral!");
847                        return 0.0;
848                }
849        }
850 
851        /**
852         * @param expr
853         * @return
854         */
855        private int extractIntFromLiteral(Expression expr) {
856                return ((IntLiteral) expr).getValue();
857        }
858 
859        /**
860         * @param expr
861         * @return
862         */
863        private IProbabilityMassFunction extractIPMFFromLiteral(Expression expr) {
864                ProbabilityFunctionLiteral probFuncLiteral = (ProbabilityFunctionLiteral)expr;
865                ProbabilityFunction function = probFuncLiteral.getFunction_ProbabilityFunctionLiteral();
866                if (function instanceof ProbabilityMassFunction){
867                        ProbabilityMassFunction pmf = (ProbabilityMassFunction)function;
868                        return iProbFuncFactory.transformToPMF(pmf);
869                } else if (function instanceof ProbabilityDensityFunction){
870                        String msg = "Could not transform expression to PMF. Note that NUMBER_OF_ELEMENT and BYTESIZE characterisations are assumed to be PMFs and must not be PDFs. Maybe you need to fix your models here.";
871                        logger.error(msg);
872                        throw new TypeInferenceFailedException(expr, msg);
873                } else {
874                        String msg = "Unknown ProbabilityFunction subclass "+function.getClass().getName()+" that cannot be handled by "+this.getClass().getName();
875                        logger.error(msg);
876                        throw new TypeInferenceFailedException(expr, msg);
877                }
878        }
879 
880        /**
881         * @param expr
882         * @return
883         */
884        private IProbabilityDensityFunction extractIPDFFromLiteral(Expression expr) {
885                ProbabilityFunctionLiteral pfl = (ProbabilityFunctionLiteral)expr;
886                ProbabilityDensityFunction pdf = (ProbabilityDensityFunction)pfl.getFunction_ProbabilityFunctionLiteral();
887                IProbabilityDensityFunction ipdf = null;
888                try {
889                        ipdf = iProbFuncFactory.transformToPDF(pdf);
890                } catch (UnknownPDFTypeException e) {
891                        e.printStackTrace();
892                } catch (ProbabilitySumNotOneException e) {
893                        e.printStackTrace();
894                } catch (DoubleSampleException e) {
895                        e.printStackTrace();
896                }
897                return ipdf;
898        }
899 
900}
901 
902class UnsupportedComputationException extends UnsupportedOperationException {
903 
904 
905        public UnsupportedComputationException(Expression right, Expression left,
906                        TermProductOperation op, TypeEnum exprType) {
907                super("Cannot compute operation "+op+" with expression type "+exprType+" on expressions "+right.getClass()+" and "+left.getClass());
908        }
909        
910        public UnsupportedComputationException(Expression exp,
911                        String op) {
912                super("Cannot compute operation "+op+" on expression "+exp.getClass());
913        }
914        
915 
916        
917 
918        /**
919         * 
920         */
921        private static final long serialVersionUID = 653425379466321794L;
922        
923        
924}
925 
926 

[all classes][de.uka.ipd.sdq.stoex.analyser.visitors]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov