Changeset f6051a17 in OpenModelica
- Timestamp:
- 2016-04-07T13:46:47+02:00 (8 years ago)
- Branches:
- Added-citation-metadata, maintenance/v1.14, maintenance/v1.15, maintenance/v1.16, maintenance/v1.17, maintenance/v1.18, maintenance/v1.19, maintenance/v1.20, maintenance/v1.21, maintenance/v1.22, maintenance/v1.23, master, omlib-staging
- Children:
- c3cf1e92
- Parents:
- 058fd5a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Compiler/BackEnd/EvaluateFunctions.mo
r9027e889 rf6051a17 80 80 end FuncInfo; 81 81 82 public uniontype Variability 83 record CONST end CONST; 84 record VARIABLE end VARIABLE; 85 end Variability; 86 87 public uniontype CallSignature 88 record SIGNATURE 89 Absyn.Path path; 90 list<Variability> inputsVari;//not scalar, take records, arrays, calls as a single input variability 91 Boolean canBeEvaluated; 92 end SIGNATURE; 93 end CallSignature; 94 95 // ============================================================================= 96 // caching of already evaluated functions 97 // 98 // ============================================================================= 99 100 protected function checkCallSignatureForExp 101 input DAE.Exp expIn; 102 input list<CallSignature> signLst; 103 output Boolean continueEval; 104 protected 105 CallSignature signature; 106 algorithm 107 continueEval := true; 108 signature := getCallSignatureForCall(expIn); 109 if List.isMemberOnTrue(signature,signLst,callSignatureIsEqual) then 110 SIGNATURE(canBeEvaluated = continueEval) := List.getMemberOnTrue(signature,signLst,callSignatureIsEqual); 111 end if; 112 end checkCallSignatureForExp; 113 114 protected function callSignatureStr "outputs a string representation for the CallSignature" 115 input CallSignature signat; 116 output String str; 117 protected 118 Absyn.Path path; 119 list<Variability> varis; 120 Boolean b; 121 algorithm 122 SIGNATURE(path=path,inputsVari=varis, canBeEvaluated=b) := signat; 123 str := Absyn.pathString(path)+"[ "+stringDelimitList(List.map(varis,VariabilityString)," | ")+" ] "+boolString(b); 124 end callSignatureStr; 125 126 protected function VariabilityString "outputs a string representation for the Variability" 127 input Variability var; 128 output String str; 129 algorithm 130 str := match(var) 131 case(CONST()) 132 then "CONST"; 133 else then "VARIABLE"; 134 end match; 135 end VariabilityString; 136 137 protected function callSignatureIsEqual"outputs true if 2 CallSignatures are equal" 138 input CallSignature signat1; 139 input CallSignature signat2; 140 output Boolean isEqual; 141 protected 142 Absyn.Path path1,path2; 143 list<Variability> vari1,vari2; 144 algorithm 145 SIGNATURE(path=path1, inputsVari=vari1) := signat1; 146 SIGNATURE(path=path2, inputsVari=vari2) := signat2; 147 isEqual := false; 148 if Absyn.pathEqual(path1,path2) then 149 if List.isEqualOnTrue(vari1,vari2,VariabilityIsEqual) then 150 isEqual := true; 151 end if; 152 end if; 153 end callSignatureIsEqual; 154 155 protected function VariabilityIsEqual"outputs true if 2 Variabilites are equal" 156 input Variability vari1; 157 input Variability vari2; 158 output Boolean isEqual; 159 algorithm 160 isEqual := match(vari1,vari2) 161 case(CONST(),CONST()) 162 then true; 163 case(VARIABLE(),VARIABLE()) 164 then true; 165 else 166 then false; 167 end match; 168 end VariabilityIsEqual; 169 170 protected function getCallSignatureForCall"determines the callSignature for a function call expression" 171 input DAE.Exp callExpIn; 172 output CallSignature signatureOut; 173 protected 174 Absyn.Path path; 175 list<DAE.Exp> expLst; 176 list<Variability> vari; 177 algorithm 178 try 179 DAE.CALL(path=path, expLst=expLst) := callExpIn; 180 vari := List.map(expLst,getVariabilityForExp); 181 signatureOut := SIGNATURE(path,vari,true); 182 else 183 print("evalFunc.getCallSignatureForCall failed for :\n"+ExpressionDump.printExpStr(callExpIn)+"\n"); 184 fail(); 185 end try; 186 end getCallSignatureForCall; 187 188 protected function getVariabilityForExp"determines if the exp is either constant or variable" 189 input DAE.Exp expIn; 190 output Variability variOut; 191 algorithm 192 variOut := match(expIn) 193 local 194 Variability vari; 195 case(DAE.ICONST()) 196 then CONST(); 197 case(DAE.RCONST()) 198 then CONST(); 199 case(DAE.SCONST()) 200 then CONST(); 201 case(DAE.BCONST()) 202 then CONST(); 203 case(DAE.CLKCONST()) 204 then CONST(); 205 case(DAE.ENUM_LITERAL()) 206 then CONST(); 207 case(DAE.CREF()) 208 then VARIABLE(); 209 case(DAE.BINARY()) 210 equation 211 if Expression.isConst(expIn) then 212 vari = CONST(); 213 else 214 vari=VARIABLE(); end if; 215 then vari; 216 case(DAE.UNARY()) 217 equation 218 if Expression.isConst(expIn) then vari = CONST(); 219 else vari=VARIABLE(); end if; 220 then vari; 221 case(DAE.LBINARY()) 222 equation 223 if Expression.isConst(expIn) then vari = CONST(); 224 else vari=VARIABLE(); end if; 225 then vari; 226 case(DAE.LUNARY()) 227 equation 228 if Expression.isConst(expIn) then vari = CONST(); 229 else vari=VARIABLE(); end if; 230 then vari; 231 case(DAE.RELATION()) 232 then VARIABLE(); 233 case(DAE.IFEXP()) 234 then VARIABLE(); 235 case(DAE.CALL()) 236 then VARIABLE(); 237 case(DAE.RECORD()) 238 equation 239 if Expression.isConst(expIn) then vari = CONST(); 240 else vari=VARIABLE(); end if; 241 then vari; 242 case(DAE.PARTEVALFUNCTION()) 243 then VARIABLE(); 244 case(DAE.ARRAY()) 245 equation 246 if Expression.isConst(expIn) then vari = CONST(); 247 else vari=VARIABLE(); end if; 248 then vari; 249 case(DAE.MATRIX()) 250 equation 251 if Expression.isConst(expIn) then vari = CONST(); 252 else vari=VARIABLE(); end if; 253 then vari; 254 case(DAE.RANGE()) 255 equation 256 if Expression.isConst(expIn) then vari = CONST(); 257 else vari=VARIABLE(); end if; 258 then vari; 259 case(DAE.TUPLE()) 260 equation 261 if Expression.isConst(expIn) then vari = CONST(); 262 else vari=VARIABLE(); end if; 263 then vari; 264 case(DAE.CAST()) 265 equation 266 if Expression.isConst(expIn) then vari = CONST(); 267 else vari=VARIABLE(); end if; 268 then vari; 269 case(DAE.ASUB()) 270 equation 271 if Expression.isConst(expIn) then vari = CONST(); 272 else vari=VARIABLE(); end if; 273 then vari; 274 case(DAE.TSUB()) 275 equation 276 if Expression.isConst(expIn) then vari = CONST(); 277 else vari=VARIABLE(); end if; 278 then vari; 279 case(DAE.RSUB()) 280 equation 281 if Expression.isConst(expIn) then vari = CONST(); 282 else vari=VARIABLE(); end if; 283 then vari; 284 case(DAE.SIZE()) 285 then VARIABLE(); 286 case(DAE.CODE()) 287 then VARIABLE(); 288 case(DAE.EMPTY()) 289 then VARIABLE(); 290 case(DAE.REDUCTION()) 291 then VARIABLE(); 292 else 293 VARIABLE(); 294 end match; 295 end getVariabilityForExp; 296 82 297 // ============================================================================= 83 298 // evaluate functions … … 97 312 try 98 313 BackendDAE.DAE(eqs=eqSysts, shared=shared) := inDAE; 99 (eqSysts, (shared, _, changed )) := List.mapFold(eqSysts, evalFunctions_main, (shared, 1, false));314 (eqSysts, (shared, _, changed, _)) := List.mapFold(eqSysts, evalFunctions_main, (shared, 1, false, {})); 100 315 //shared = evaluateShared(shared); 101 316 … … 141 356 true = Expression.isCall(bindExp); 142 357 ExpressionDump.dumpExp(bindExp); 143 ((bindExp,_,_,_,_,_ )) = evaluateConstantFunction(bindExp,bindExp,funcTree,1);358 ((bindExp,_,_,_,_,_,_)) = evaluateConstantFunction(bindExp,bindExp,funcTree,1,{}); 144 359 ExpressionDump.dumpExp(bindExp); 145 360 then … … 151 366 protected function evalFunctions_main "traverses the eqSystems for function calls and tries to evaluate them" 152 367 input BackendDAE.EqSystem eqSysIn; 153 input tuple<BackendDAE.Shared,Integer,Boolean > tplIn;368 input tuple<BackendDAE.Shared,Integer,Boolean, list<CallSignature>> tplIn; 154 369 output BackendDAE.EqSystem eqSysOut; 155 output tuple<BackendDAE.Shared,Integer,Boolean > tplOut;370 output tuple<BackendDAE.Shared,Integer,Boolean, list<CallSignature>> tplOut; 156 371 protected 157 372 Boolean changed; … … 160 375 BackendDAE.EquationArray eqs; 161 376 list<BackendDAE.Equation> eqLst, addEqs; 162 algorithm 163 (sharedIn,sysIdx,changed) := tplIn; 377 list<CallSignature> callSign; 378 algorithm 379 (sharedIn,sysIdx,changed,callSign) := tplIn; 164 380 BackendDAE.EQSYSTEM(orderedEqs=eqs) := eqSysIn; 165 381 eqLst := BackendEquation.equationList(eqs); 166 382 167 383 //traverse the eqSystem for function calls 168 (eqLst, (shared, addEqs, _, changed )) := List.mapFold(eqLst, evalFunctions_findFuncs, (sharedIn, {}, 1, changed));384 (eqLst, (shared, addEqs, _, changed, callSign)) := List.mapFold(eqLst, evalFunctions_findFuncs, (sharedIn, {}, 1, changed, callSign)); 169 385 eqLst := listAppend(eqLst, addEqs); 170 386 eqs := BackendEquation.listEquation(eqLst); 171 387 eqSysOut := BackendDAEUtil.setEqSystEqs(eqSysIn, eqs); 172 388 173 tplOut := (shared, sysIdx+1, changed );389 tplOut := (shared, sysIdx+1, changed, callSign); 174 390 end evalFunctions_main; 175 391 176 392 protected function evalFunctions_findFuncs "traverses the lhs and rhs exps of an equation and tries to evaluate function calls " 177 393 input BackendDAE.Equation eqIn; 178 input tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean > tplIn;394 input tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean, list<CallSignature>> tplIn; 179 395 output BackendDAE.Equation eqOut; 180 output tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean > tplOut;396 output tuple<BackendDAE.Shared,list<BackendDAE.Equation>,Integer,Boolean, list<CallSignature>> tplOut; 181 397 algorithm 182 398 (eqOut,tplOut) := matchcontinue(eqIn,tplIn) … … 192 408 list<BackendDAE.Equation> addEqs, addEqs1, addEqs2; 193 409 list<DAE.Exp> lhs; 410 list<CallSignature> callSign; 194 411 case(BackendDAE.EQUATION(exp=exp1, scalar=exp2,source=source,attr=attr),_) 195 412 equation … … 197 414 b2 = Expression.containFunctioncall(exp2); 198 415 true = b1 or b2; 199 (shared,addEqs,idx,changed ) = tplIn;416 (shared,addEqs,idx,changed,callSign) = tplIn; 200 417 funcs = BackendDAEUtil.getFunctions(shared); 201 ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1 )) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx) else (exp2,exp1,{},funcs,idx,changed);418 ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1,callSign)) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx,callSign) else (exp2,exp1,{},funcs,idx,changed,callSign); 202 419 changed = changed1 or changed; 203 ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1 )) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx) else (rhsExp,lhsExp,{},funcs,idx,changed);420 ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1,callSign)) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx,callSign) else (rhsExp,lhsExp,{},funcs,idx,changed,callSign); 204 421 changed = changed1 or changed; 205 422 addEqs = listAppend(addEqs1,addEqs); … … 208 425 //if changed then print("FROM EQ "+BackendDump.equationString(eqIn)+"\n");print("GOT EQ "+BackendDump.equationString(eq)+"\n"); end if; 209 426 then 210 (eq,(shared,addEqs,idx+1,changed ));427 (eq,(shared,addEqs,idx+1,changed,callSign)); 211 428 case(BackendDAE.ARRAY_EQUATION(),_) 212 429 equation … … 221 438 b2 = Expression.containFunctioncall(exp2); 222 439 true = b1 or b2; 223 (shared,addEqs,idx,changed ) = tplIn;440 (shared,addEqs,idx,changed,callSign) = tplIn; 224 441 funcs = BackendDAEUtil.getFunctions(shared); 225 ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1 )) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx) else (exp2,exp1,{},funcs,idx,changed);442 ((rhsExp,lhsExp,addEqs1,funcs,idx,changed1,callSign)) = if b1 then evaluateConstantFunction(exp1,exp2,funcs,idx,callSign) else (exp2,exp1,{},funcs,idx,changed,callSign); 226 443 changed = changed or changed1; 227 ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1 )) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx) else (rhsExp,lhsExp,{},funcs,idx,changed);444 ((rhsExp,lhsExp,addEqs2,funcs,idx,changed1,callSign)) = if b2 then evaluateConstantFunction(exp2,exp1,funcs,idx,callSign) else (rhsExp,lhsExp,{},funcs,idx,changed,callSign); 228 445 changed = changed or changed1; 229 446 addEqs = listAppend(addEqs1,addEqs); … … 235 452 //if changed then print("FROM EQ "+BackendDump.equationString(eqIn)+"\n");print("GOT EQ "+BackendDump.equationString(eq)+"\n"); end if; 236 453 then 237 (eq,(shared,addEqs,idx+1,changed ));454 (eq,(shared,addEqs,idx+1,changed,callSign)); 238 455 else 239 456 (eqIn,tplIn); … … 393 610 input DAE.FunctionTree funcsIn; 394 611 input Integer eqIdx; 395 output tuple<DAE.Exp, DAE.Exp, list<BackendDAE.Equation>, DAE.FunctionTree,Integer,Boolean> outTpl; //rhs,lhs,addEqs,funcTre,idx,haschanged 396 algorithm 397 outTpl := matchcontinue(rhsExpIn,lhsExpIn,funcsIn,eqIdx) 612 input list<CallSignature> callSignLstIn; 613 output tuple<DAE.Exp, DAE.Exp, list<BackendDAE.Equation>, DAE.FunctionTree,Integer,Boolean, list<CallSignature>> outTpl; //rhs,lhs,addEqs,funcTre,idx,haschanged 614 algorithm 615 outTpl := matchcontinue(rhsExpIn,lhsExpIn,funcsIn,eqIdx,callSignLstIn) 398 616 local 399 617 Boolean funcIsConst, funcIsPartConst, isConstRec, hasAssert, hasReturn, hasTerminate, hasReinit, abort, changed; … … 419 637 list<String> outputVarNames; 420 638 list<list<DAE.ComponentRef>> scalarInputs, scalarOutputs; 421 case(DAE.CALL(path=path, expLst=expsIn, attr=attr1),_,_,_) 639 CallSignature signature; 640 list<CallSignature> callSignLst; 641 Boolean continueEval; 642 case(DAE.CALL(path=path, expLst=expsIn, attr=attr1),_,_,_,callSignLst) 422 643 equation 423 644 … … 425 646 print("\nStart function evaluation of:\n"+ExpressionDump.printExpStr(lhsExpIn)+" := "+ExpressionDump.printExpStr(rhsExpIn)+"\n\n"); 426 647 end if; 648 649 //------------------------------------------------ 650 //Check if this particular call signature has been analysed before 651 //------------------------------------------------ 652 //print(stringDelimitList(List.map(callSignLst,callSignatureStr),"\n")); 653 continueEval = checkCallSignatureForExp(rhsExpIn,callSignLst); 654 if not continueEval and Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("THIS FUNCTION CALL WITH THIS SPECIFIC SIGNATURE CANNOT BE EVALUTED\n"); end if; 655 if not continueEval then fail(); end if; 427 656 428 657 //------------------------------------------------ … … 543 772 funcIsPartConst = if hasAssert and funcIsConst then true else funcIsPartConst; 544 773 funcIsPartConst = if abort then false else funcIsPartConst; // quit if there is a return or terminate 774 545 775 true = funcIsPartConst or funcIsConst; 776 777 signature = getCallSignatureForCall(rhsExpIn); 778 signature.canBeEvaluated = true; 779 callSignLst = signature::callSignLst; 546 780 changed = funcIsPartConst or funcIsConst; 547 781 … … 566 800 funcs = if funcIsPartConst then DAEUtil.addDaeFunction({func},funcs) else funcs; 567 801 idx = if funcIsPartConst or funcIsConst then (idx+1) else idx; 802 568 803 569 804 //decide which lhs to take (tuple or 1d) … … 606 841 end if; 607 842 then 608 ((exp,outputExp,constEqs,funcs,idx,changed)); 609 610 case(DAE.ASUB(DAE.CALL(path=path, expLst=exps, attr=attr1),sub),_,_,_) 611 equation 843 ((exp,outputExp,constEqs,funcs,idx,changed,callSignLst)); 844 845 case(DAE.ASUB(DAE.CALL(path=path, expLst=exps, attr=attr1),sub),_,_,_,callSignLst) 846 equation 847 exp = DAE.CALL(path=path, expLst=exps, attr=attr1); 848 849 //Check if this particular call signature has been analysed before 850 continueEval = checkCallSignatureForExp(exp,callSignLst); 851 if not continueEval and Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("THIS FUNCTION CALL WITH THIS SPECIFIC SIGNATURE CANNOT BE EVALUTED\n"); end if; 852 if not continueEval then fail(); end if; 853 612 854 //this ASUB stuff occurs in the flattened DAE, check this special case because of removeSimpleEquations 613 exp = evaluateConstantFunctionCallExp( DAE.CALL(path=path, expLst=exps, attr=attr1),funcsIn);855 exp = evaluateConstantFunctionCallExp(exp,funcsIn); 614 856 (exp,_) = ExpressionSimplify.simplify(DAE.ASUB(exp,sub)); 615 857 … … 619 861 changed=false; 620 862 end if; 621 then ((exp,lhsExpIn,{},funcsIn,eqIdx,changed ));863 then ((exp,lhsExpIn,{},funcsIn,eqIdx,changed,callSignLst)); 622 864 623 865 else 624 ((rhsExpIn,lhsExpIn,{},funcsIn,eqIdx,false)); 866 equation 867 callSignLst = callSignLstIn; 868 if Expression.isCall(rhsExpIn) then 869 //Add a call signature for the call that could not been evaluated 870 signature = getCallSignatureForCall(rhsExpIn); 871 signature.canBeEvaluated = false; 872 if not List.isMemberOnTrue(signature,callSignLstIn,callSignatureIsEqual) then 873 callSignLst = signature::callSignLst; 874 end if; 875 end if; 876 then ((rhsExpIn,lhsExpIn,{},funcsIn,eqIdx,false,callSignLst)); 625 877 end matchcontinue; 626 878 end evaluateConstantFunction; … … 1861 2113 1862 2114 exp2 = DAE.TUPLE(expLst); 1863 ((exp1,exp2,addEqs,funcTree2,idx,_ )) = evaluateConstantFunction(exp1,exp2,funcTree,idx);2115 ((exp1,exp2,addEqs,funcTree2,idx,_,_)) = evaluateConstantFunction(exp1,exp2,funcTree,idx,{}); 1864 2116 //print("\nthe LHS after\n"); 1865 2117 //print(ExpressionDump.printExpStr(exp2)); … … 2468 2720 DAE.Exp rhs, lhs; 2469 2721 DAE.FunctionTree funcs; 2470 DAE.Type ty;2471 2722 list<BackendDAE.Equation> addEqs; 2472 2723 list<DAE.Statement> stmts,stmtsIn; 2473 2724 case (DAE.CALL(),(lhs,funcs,idx,stmtsIn)) 2474 2725 equation 2475 ((rhs,lhs,addEqs,funcs,idx,_ )) = evaluateConstantFunction(inExp,lhs,funcs,idx);2726 ((rhs,lhs,addEqs,funcs,idx,_,_)) = evaluateConstantFunction(inExp,lhs,funcs,idx,{}); 2476 2727 stmts = List.map(addEqs,equationToStmt); 2477 2728 stmts = listAppend(stmts,stmtsIn); 2478 2729 then (rhs,true,(lhs,funcs,idx,stmts)); 2479 2730 2480 case (DAE.UNBOX(exp=rhs , ty=ty),(lhs,funcs,idx,stmts))2731 case (DAE.UNBOX(exp=rhs),_) 2481 2732 equation 2482 2733 (rhs,_,(lhs,funcs,idx,stmts)) = evaluateConstantFunctionWrapper(rhs,inTpl);
Note: See TracChangeset
for help on using the changeset viewer.