@@ -701,7 +701,7 @@ public
701701 tupl_recd_str := if Type . isTuple(eq. ty) then "[TUPL] " else "[RECD] " ;
702702 then str + tupl_recd_str + s + " " + Expression . toString(eq. lhs) + " = " + Expression . toString(eq. rhs) + EquationAttributes . toString(eq. attr, " " );
703703 case ALGORITHM () then str + "[ALGO] " + s + EquationAttributes . toString(eq. attr, " " ) + " \n " + Algorithm . toString(eq. alg, str + "[----] " );
704- case IF_EQUATION () then str + IfEquationBody . toString(eq. body, str + "[----] " , "[-IF-] " + s + EquationAttributes . toString(eq. attr, " " ));
704+ case IF_EQUATION () then str + IfEquationBody . toString(eq. body, str + "[----] " , "[-IF-] " + s + EquationAttributes . toString(eq. attr, " " ) + " \n " );
705705 case FOR_EQUATION () then str + forEquationToString(eq. iter, eq. body, "" , str + "[----] " , "[FOR-] " + s + EquationAttributes . toString(eq. attr, " " ));
706706 case WHEN_EQUATION () then str + WhenEquationBody . toString(eq. body, str + "[----] " , "[WHEN] " + s + EquationAttributes . toString(eq. attr, " " ) + " \n " );
707707 case AUX_EQUATION () then str + "[AUX-] " + s + "Auxiliary equation for " + Variable . toString(Pointer . access(eq. auxiliary));
@@ -1338,6 +1338,7 @@ public
13381338 algorithm
13391339 e := func (e);
13401340 end apply;
1341+ Equation old_eq;
13411342 algorithm
13421343 if Flags . isSet(Flags . DUMP_SIMPLIFY ) and not stringEqual(indent, "" ) then
13431344 print(" \n " );
@@ -1347,10 +1348,10 @@ public
13471348 eq := map(eq, simplifyExp, mapFunc = apply);
13481349
13491350 // simplify equation structure
1351+ old_eq := eq;
13501352 eq := match eq
13511353 local
13521354 Equation new_eq;
1353- WhenEquationBody body;
13541355
13551356 case SCALAR_EQUATION () algorithm
13561357 if Expression . isEqual(eq. lhs, eq. rhs) then
@@ -1376,8 +1377,22 @@ public
13761377 case ALGORITHM () algorithm
13771378 eq. alg := SimplifyModel . simplifyAlgorithm(eq. alg);
13781379 then eq;
1380+
13791381 case WHEN_EQUATION () algorithm
13801382 new_eq := match WhenEquationBody . simplify(SOME (eq. body))
1383+ local
1384+ WhenEquationBody body;
1385+ case SOME (body) algorithm
1386+ eq. body := body;
1387+ then eq;
1388+ else Equation . DUMMY_EQUATION ();
1389+ end match;
1390+ then new_eq;
1391+
1392+ case IF_EQUATION () algorithm
1393+ new_eq := match IfEquationBody . simplify(SOME (eq. body))
1394+ local
1395+ IfEquationBody body;
13811396 case SOME (body) algorithm
13821397 eq. body := body;
13831398 then eq;
@@ -1387,13 +1402,18 @@ public
13871402
13881403 // ToDo: implement the following correctly:
13891404
1390- case IF_EQUATION () then eq;
13911405 case FOR_EQUATION () then eq;
13921406 case AUX_EQUATION () then eq;
13931407 else algorithm
13941408 Error . addMessage(Error . INTERNAL_ERROR , {getInstanceName() + " failed for: " + toString(eq)});
13951409 then fail();
13961410 end match;
1411+
1412+ if Flags . isSet(Flags . DUMP_SIMPLIFY ) and not isEqual(old_eq, eq) then
1413+ print(indent + "### dumpSimplify | " + name + " ### \n " );
1414+ print(indent + "[BEFORE] \n " + toString(old_eq, indent + " " ) + " \n " );
1415+ print(indent + "[AFTER ] \n " + toString(eq, indent + " " ) + " \n\n " );
1416+ end if ;
13971417 end simplify;
13981418
13991419 function createName
@@ -2297,20 +2317,21 @@ public
22972317 input String elseStr = "" ;
22982318 input Boolean selfCall = false ;
22992319 output String str;
2300- protected
2301- IfEquationBody elseIf;
23022320 algorithm
2321+ str := elseStr;
2322+ if not selfCall then
2323+ str := str + indent;
2324+ end if ;
23032325 if not Expression . isEnd(body. condition) then
2304- str := elseStr + "if " + Expression . toString(body. condition) + " then \n " ;
2326+ str := str + "if " + Expression . toString(body. condition) + " then \n " ;
23052327 else
2306- str := elseStr + " \n " ;
2328+ str := str + " \n " ;
23072329 end if ;
23082330 for eqn in body. then_eqns loop
23092331 str := str + Equation . toString(Pointer . access(eqn), indent + " " ) + " \n " ;
23102332 end for ;
23112333 if isSome(body. else_if) then
2312- SOME (elseIf) := body. else_if;
2313- str := str + toString(elseIf, indent, indent + "else" , true );
2334+ str := str + toString(Util . getOption(body. else_if), indent, indent + "else" , true );
23142335 end if ;
23152336 if not selfCall then
23162337 str := str + indent + "end if;" ;
@@ -2507,6 +2528,60 @@ public
25072528 end for ;
25082529 end split;
25092530
2531+ function simplify
2532+ input output Option < IfEquationBody > body;
2533+ input Integer depth = 1 ;
2534+ input Boolean done = false ;
2535+ algorithm
2536+ body := match body
2537+ local
2538+ IfEquationBody b;
2539+ Expression condition;
2540+ list< Expression > conditions;
2541+
2542+ case SOME (b) algorithm
2543+ if done then
2544+ b. condition := Expression . END ();
2545+ b. else_if := NONE ();
2546+ end if ;
2547+ // if the condition is True -> cut later unreachable branches
2548+ if Expression . isTrue(b. condition) then
2549+ // FIXME can't yet handle removing the IF altogether so at least two branches have to remain.
2550+ if depth >= 2 then
2551+ b. condition := Expression . END ();
2552+ b. else_if := NONE ();
2553+ else
2554+ b. else_if := simplify(b. else_if, depth + 1 , true );
2555+ end if ;
2556+ else
2557+ b. else_if := simplify(b. else_if, depth + 1 );
2558+ end if ;
2559+ // if the condition is False -> skip this unreachable branch
2560+ // FIXME can't yet handle removing the IF altogether so at least two branches have to remain.
2561+ if Expression . isFalse(b. condition) and depth - 1 + numberOfBranches(b. else_if) >= 2 then
2562+ body := b. else_if;
2563+ else
2564+ body := SOME (b);
2565+ end if ;
2566+ then body;
2567+
2568+ // NONE() stays NONE()
2569+ else body;
2570+ end match;
2571+ end simplify;
2572+
2573+ function numberOfBranches
2574+ input Option < IfEquationBody > body;
2575+ output Integer numBranches;
2576+ algorithm
2577+ numBranches := match body
2578+ local
2579+ IfEquationBody b;
2580+ case SOME (b) then 1 + numberOfBranches(b. else_if);
2581+ else 0 ;
2582+ end match;
2583+ end numberOfBranches;
2584+
25102585 function isRecordOrTupleEquation
25112586 "only checks first layer body if it returns multiple variables"
25122587 input IfEquationBody body;
@@ -2585,20 +2660,17 @@ public
25852660 input String elseStr = "" ;
25862661 input Boolean selfCall = false ;
25872662 output String str;
2588- protected
2589- WhenEquationBody elseWhen;
25902663 algorithm
25912664 str := elseStr;
25922665 if not selfCall then
25932666 str := str + indent;
25942667 end if ;
2595- str := str + "when " + Expression . toString(body. condition) + " then \n " ;
2668+ str := str + "when " + Expression . toString(body. condition) + " then \n " ;
25962669 for stmt in body. when_stmts loop
25972670 str := str + WhenStatement . toString(stmt, indent + " " ) + " \n " ;
25982671 end for ;
25992672 if isSome(body. else_when) then
2600- SOME (elseWhen) := body. else_when;
2601- str := str + toString(elseWhen, indent, indent + "else " , true );
2673+ str := str + toString(Util . getOption(body. else_when), indent, indent + "else" , true );
26022674 end if ;
26032675 if not selfCall then
26042676 str := str + indent + "end when;" ;
@@ -2631,7 +2703,7 @@ public
26312703 input WhenEquationBody body2;
26322704 output Boolean b;
26332705 algorithm
2634- b := List . all(List . zip(body1. when_stmts, body2. when_stmts), WhenStatement . isEqualTpl) and Util . optionEqual(body1. else_when, body2. else_when, isEqual);
2706+ b := Expression . isEqual(body1 . condition, body2 . condition) and List . all(List . zip(body1. when_stmts, body2. when_stmts), WhenStatement . isEqualTpl) and Util . optionEqual(body1. else_when, body2. else_when, isEqual);
26352707 end isEqual;
26362708
26372709 function getBodyAttributes
0 commit comments