513 | | // if-equation |
514 | | // if the condition is constant this case will select the correct branch and remove the if-equation |
515 | | case (cache,env,ih,mod,pre,csets,ci_state,SCode.EQ_IF(condition = conditions,thenBranch = tb,elseBranch = fb,info=info),SCode.NON_INITIAL(),impl,graph) |
516 | | equation |
517 | | (cache, expl1,props,_) = Static.elabExpList(cache,env, conditions, impl,NONE(),true,pre,info); |
518 | | DAE.PROP(DAE.T_BOOL(varLst = _),cnst) = Types.propsAnd(props); |
519 | | true = Types.isParameterOrConstant(cnst); |
520 | | (cache,valList,_) = Ceval.cevalList(cache, env, expl1, impl, NONE(), Ceval.NO_MSG()); |
521 | | // check if valList contains Values.EMPTY() |
522 | | containsEmpty = ValuesUtil.containsEmpty(valList); |
523 | | generateNoConstantBindingError(containsEmpty, info); |
524 | | blist = List.map(valList,ValuesUtil.valueBool); |
525 | | b = Util.selectList(blist, tb, fb); |
526 | | (cache,env_1,ih,dae,csets_1,ci_state_1,graph) = Inst.instList(cache, env, ih, mod, pre, csets, ci_state, instEEquation, b, impl, Inst.alwaysUnroll, graph); |
527 | | then |
528 | | (cache,env_1,ih,dae,csets_1,ci_state_1,graph); |
529 | | |
530 | | // if-equation |
531 | | // If we are doing checkModel we might get an if-equation whose condition is |
532 | | // a parameter without a binding, and which DAEUtil.ifEqToExpr can't handle. |
533 | | // If the model would have been instantiated one of the branches would have |
534 | | // been chosen, so this case therefore chooses one of the branches. |
535 | | case (cache,env,ih,mod,pre,csets,ci_state,SCode.EQ_IF(condition = conditions,thenBranch = tb,elseBranch = fb,info=info),SCode.NON_INITIAL(),impl,graph) |
| 514 | // if equation |
| 515 | case (cache,env,ih,mod,pre,csets,ci_state,SCode.EQ_IF(condition = conditions,thenBranch = tb,elseBranch = fb,info = info),SCode.NON_INITIAL(),impl,graph) |
537 | | true = Flags.getConfigBool(Flags.CHECK_MODEL); |
538 | | (cache, _,props,_) = Static.elabExpList(cache,env, conditions, impl,NONE(),true,pre,info); |
539 | | DAE.PROP(DAE.T_BOOL(varLst = _),DAE.C_PARAM()) = Types.propsAnd(props); |
540 | | b = Util.selectList({true}, tb, fb); |
541 | | (cache,env_1,ih,dae,csets_1,ci_state_1,graph) = Inst.instList(cache, env, ih, mod, pre, csets, ci_state, instEEquation, b, impl, Inst.alwaysUnroll, graph); |
542 | | then |
543 | | (cache,env_1,ih,dae,csets_1,ci_state_1,graph); |
544 | | |
545 | | // initial if-equation |
546 | | // if the condition is constant this case will select the correct branch and remove the initial if-equation |
547 | | case (cache,env,ih,mod,pre,csets,ci_state,SCode.EQ_IF(condition = conditions,thenBranch = tb,elseBranch = fb,info=info),SCode.INITIAL(),impl,graph) |
548 | | equation |
551 | | (cache,valList,_) = Ceval.cevalList(cache, env, expl1, impl, NONE(), Ceval.NO_MSG()); |
552 | | blist = List.map(valList,ValuesUtil.valueBool); |
553 | | b = Util.selectList(blist, tb, fb); |
554 | | (cache,env_1,ih,dae,csets_1,ci_state_1,graph) = Inst.instList(cache,env,ih, mod, pre, csets, ci_state, instEInitialEquation, b, impl, Inst.alwaysUnroll, graph); |
555 | | then |
556 | | (cache,env_1,ih,dae,csets_1,ci_state_1,graph); |
557 | | |
558 | | // if equation when condition is not constant |
559 | | case (cache,env,ih,mod,pre,csets,ci_state,SCode.EQ_IF(condition = conditions,thenBranch = tb,elseBranch = fb,info = info),SCode.NON_INITIAL(),impl,graph) |
560 | | equation |
561 | | (cache, expl1,props,_) = Static.elabExpList(cache,env, conditions, impl,NONE(),true,pre,info); |
562 | | DAE.PROP(DAE.T_BOOL(varLst = _),DAE.C_VAR()) = Types.propsAnd(props); |
563 | | (cache,expl1) = PrefixUtil.prefixExpList(cache, env, ih, expl1, pre); |
| 519 | (cache,expl1) = Ceval.cevalListIfConstantOrParam(cache, env, expl1, List.map(props,Types.propAllConst), impl, Ceval.MSG(info), {}); |
| 520 | (cache,expl1) = PrefixUtil.prefixExpList(cache, inEnv, ih, expl1, pre); |
568 | | (cache,env_1,ih,daeLLst,_,ci_state_1,graph) = instIfTrueBranches(cache, env,ih, mod, pre, csets, ci_state, tb, false, impl, graph); |
569 | | (cache,env_2,ih,DAE.DAE(daeElts2),_,ci_state_2,graph) = Inst.instList(cache,env_1,ih, mod, pre, csets, ci_state, instEEquation, fb, impl, Inst.alwaysUnroll, graph) "There are no connections inside if-clauses." ; |
570 | | dae = DAE.DAE({DAE.IF_EQUATION(expl1,daeLLst,daeElts2,source)}); |
| 525 | (cache,env_1,ih,daeLLst,unreachable,csets,ci_state_1,graph) = instIfTrueBranches(cache, env,ih, mod, pre, csets, ci_state, expl1, false, tb, false, impl, graph); |
| 526 | (fb,_) = SCode.traverseEEquationsList(fb, (replaceConnectWithLegalEquation,unreachable)); |
| 527 | (cache,env_2,ih,DAE.DAE(daeElts2),csets,ci_state_2,graph) = Inst.instList(cache,env_1,ih, mod, pre, csets, ci_state, instEEquation, fb, impl, Inst.alwaysUnroll, graph) "There are no connections inside if-clauses." ; |
| 528 | (cache,dae) = makeIfEquation(cache,env,impl,ih,pre,false,expl1,daeLLst,daeElts2,{},{},source); |
584 | | (cache,env_1,ih,daeLLst,_,ci_state_1,graph) = instIfTrueBranches(cache,env,ih, mod, pre, csets, ci_state, tb, true, impl, graph); |
585 | | (cache,env_2,ih,DAE.DAE(daeElts2),_,ci_state_2,graph) = Inst.instList(cache,env_1,ih, mod, pre, csets, ci_state, instEInitialEquation, fb, impl, Inst.alwaysUnroll, graph) "There are no connections inside if-clauses." ; |
586 | | dae = DAE.DAE({DAE.INITIAL_IF_EQUATION(expl1,daeLLst,daeElts2,source)}); |
| 543 | (cache,env_1,ih,daeLLst,unreachable,csets,ci_state_1,graph) = instIfTrueBranches(cache,env,ih, mod, pre, csets, ci_state, expl1, false, tb, true, impl, graph); |
| 544 | (fb,_) = SCode.traverseEEquationsList(fb, (replaceConnectWithLegalEquation,unreachable)); |
| 545 | (cache,env_2,ih,DAE.DAE(daeElts2),csets,ci_state_2,graph) = Inst.instList(cache,env_1,ih, mod, pre, csets, ci_state, instEInitialEquation, fb, impl, Inst.alwaysUnroll, graph) "There are no connections inside if-clauses." ; |
| 546 | (cache,dae) = makeIfEquation(cache,env,impl,ih,pre,true,expl1,daeLLst,daeElts2,{},{},source); |
| 550 | // if-equation |
| 551 | // If we are doing checkModel we might get an if-equation whose condition is |
| 552 | // a parameter without a binding, and which DAEUtil.ifEqToExpr can't handle. |
| 553 | // If the model would have been instantiated one of the branches would have |
| 554 | // been chosen, so this case therefore chooses one of the branches. |
| 555 | case (cache,env,ih,mod,pre,csets,ci_state,SCode.EQ_IF(condition = conditions,thenBranch = tb,elseBranch = fb,info=info),SCode.NON_INITIAL(),impl,graph) |
| 556 | equation |
| 557 | true = Flags.getConfigBool(Flags.CHECK_MODEL); |
| 558 | (cache, _,props,_) = Static.elabExpList(cache,env, conditions, impl,NONE(),true,pre,info); |
| 559 | DAE.PROP(DAE.T_BOOL(varLst = _),DAE.C_PARAM()) = Types.propsAnd(props); |
| 560 | b = Util.selectList({true}, tb, fb); |
| 561 | (cache,env_1,ih,dae,csets_1,ci_state_1,graph) = Inst.instList(cache, env, ih, mod, pre, csets, ci_state, instEEquation, b, impl, Inst.alwaysUnroll, graph); |
| 562 | then |
| 563 | (cache,env_1,ih,dae,csets_1,ci_state_1,graph); |
| 564 | |
2922 | | Inst.instList(cache, env, ih, mod, pre, csets, ci_state, instEEquation, e, impl, Inst.alwaysUnroll, graph); |
2923 | | (cache,env_2,ih,llb,csets_2,ci_state_2,graph) = |
2924 | | instIfTrueBranches(cache, env_1, ih, mod, pre, csets_1, ci_state_1, es, false, impl, graph); |
| 2905 | Inst.instList(cache, env, ih, mod, pre, csets, ci_state, Util.if_(IE,instEInitialEquation,instEEquation), e, impl, Inst.alwaysUnroll, graph); |
| 2906 | // Discard this connection graph since it is invalid; should not be needed since all connections were removed, but let's be safe |
| 2907 | (cache,env_2,ih,llb,unreachable,csets_2,ci_state_2,graph) = |
| 2908 | instIfTrueBranches(cache, env_1, ih, mod, pre, csets_1, ci_state_1, restExp, unreachable, es, IE, impl, graph); |
2931 | | Inst.instList(cache, env, ih, mod, pre, csets, ci_state, instEInitialEquation, e, impl, Inst.alwaysUnroll, graph); |
2932 | | (cache,env_2,ih,llb,csets_2,ci_state_2,graph) = |
2933 | | instIfTrueBranches(cache, env_1, ih, mod, pre, csets_1, ci_state_1, es, true, impl, graph); |
| 2915 | Inst.instList(cache, env, ih, mod, pre, csets, ci_state, Util.if_(IE,instEInitialEquation,instEEquation), e, impl, Inst.alwaysUnroll, graph); |
| 2916 | (cache,env_2,ih,llb,unreachable,csets_2,ci_state_2,graph) = |
| 2917 | instIfTrueBranches(cache, env_1, ih, mod, pre, csets_1, ci_state_1, restExp, true, es, IE, impl, graph); |
| 2923 | // Remove connections since they are evil |
| 2924 | (e,(_,i)) = SCode.traverseEEquationsList(e,(findConnectInNonParamIfError,0)); |
| 2925 | (cache,env_1,ih,DAE.DAE(elts),csets_1,ci_state_1,graph) = |
| 2926 | Inst.instList(cache, env, ih, mod, pre, csets, ci_state, Util.if_(IE,instEInitialEquation,instEEquation), e, impl, Inst.alwaysUnroll, graph); |
| 2927 | (cache,env_2,ih,llb,unreachable,csets_2,ci_state_2,graph) = |
| 2928 | instIfTrueBranches(cache, env_1, ih, mod, pre, csets_1, ci_state_1, restExp, unreachable, es, IE, impl, graph); |
| 2929 | then |
| 2930 | (cache,env_2,ih,elts::llb,unreachable,csets_2,ci_state_2,graph); |
| 2931 | |
| 2932 | case (cache,env,ih,mod,pre,csets,ci_state,_,_,(e :: es),_,impl,graph) |
| 2933 | equation |
| 2942 | protected function replaceConnectWithLegalEquation |
| 2943 | "Replaces connections with a legal terminate equation" |
| 2944 | input tuple<SCode.EEquation, Boolean> inTuple; |
| 2945 | output tuple<SCode.EEquation, Boolean> outTuple; |
| 2946 | algorithm |
| 2947 | outTuple := match inTuple |
| 2948 | local |
| 2949 | Absyn.Info info; |
| 2950 | case ((SCode.EQ_CONNECT(info=info),true)) |
| 2951 | then ((SCode.EQ_TERMINATE(Absyn.STRING("Connection removed from type checking since branch was false"),NONE(),info),true)); |
| 2952 | else inTuple; |
| 2953 | end match; |
| 2954 | end replaceConnectWithLegalEquation; |
| 2955 | |
| 2956 | protected function findConnectInNonParamIfError |
| 2957 | "Replaces connections with a legal terminate equation" |
| 2958 | input tuple<SCode.EEquation, Integer> inTuple; |
| 2959 | output tuple<SCode.EEquation, Integer> outTuple; |
| 2960 | algorithm |
| 2961 | outTuple := match inTuple |
| 2962 | local |
| 2963 | Absyn.Info info; |
| 2964 | case ((SCode.EQ_CONNECT(info=info),_)) |
| 2965 | equation |
| 2966 | Error.addSourceMessage(Error.INTERNAL_ERROR,{"Connections are not allowed in if-branches that cannot be evaluated at runtime"},info); |
| 2967 | then fail(); |
| 2968 | else inTuple; |
| 2969 | end match; |
| 2970 | end findConnectInNonParamIfError; |
| 2971 | |
| 2972 | protected function makeIfEquation "Selects branches and creates the elements associated with the if-equation" |
| 2973 | input Env.Cache inCache; |
| 2974 | input Env.Env inEnv; |
| 2975 | input Boolean impl; |
| 2976 | input InstanceHierarchy ih; |
| 2977 | input Prefix.Prefix pre; |
| 2978 | input Boolean isInitial; |
| 2979 | input list<DAE.Exp> exps; |
| 2980 | input list<list<DAE.Element>> tbs; |
| 2981 | input list<DAE.Element> fb; |
| 2982 | input list<DAE.Exp> accExp; |
| 2983 | input list<list<DAE.Element>> accTb; |
| 2984 | input DAE.ElementSource source; |
| 2985 | output Env.Cache outCache; |
| 2986 | output DAE.DAElist dae; |
| 2987 | algorithm |
| 2988 | (outCache,dae) := matchcontinue (inCache,inEnv,impl,ih,pre,isInitial,exps,tbs,fb,accExp,accTb,source) |
| 2989 | local |
| 2990 | DAE.Exp exp; |
| 2991 | list<DAE.Element> tb,elts; |
| 2992 | list<list<DAE.Element>> restTb; |
| 2993 | list<DAE.Exp> restExp,exps; |
| 2994 | list<DAE.Properties> restProp; |
| 2995 | DAE.Properties prop; |
| 2996 | Env.Cache cache; |
| 2997 | Boolean b; |
| 2998 | Option<Values.Value> containsEmpty; |
| 2999 | DAE.Const cnst; |
| 3000 | list<Values.Value> valList; |
| 3001 | list<Boolean> blist; |
| 3002 | case (cache,inEnv,impl,ih,pre,isInitial,DAE.BCONST(false)::restExp,_::restTb,fb,accExp,accTb,source) |
| 3003 | equation |
| 3004 | (cache,dae) = makeIfEquation(cache,inEnv,impl,ih,pre,isInitial,restExp,restTb,fb,accExp,accTb,source); |
| 3005 | then (cache,dae); |
| 3006 | case (cache,inEnv,impl,ih,pre,isInitial,DAE.BCONST(true)::restExp,tb::_,_,accExp,accTb,source) |
| 3007 | equation |
| 3008 | elts = makeIfEquation2(isInitial,listReverse(accExp),listReverse(accTb),tb,source); |
| 3009 | then (cache,DAE.DAE(elts)); |
| 3010 | case (cache,inEnv,impl,ih,pre,isInitial,exp::restExp,tb::restTb,fb,accExp,accTb,source) |
| 3011 | equation |
| 3012 | (cache,dae) = makeIfEquation(cache,inEnv,impl,ih,pre,isInitial,restExp,restTb,fb,exp::accExp,tb::accTb,source); |
| 3013 | then (cache,dae); |
| 3014 | case (cache,inEnv,impl,ih,pre,isInitial,{},{},fb,accExp,accTb,source) |
| 3015 | equation |
| 3016 | elts = makeIfEquation2(isInitial,listReverse(accExp),listReverse(accTb),fb,source); |
| 3017 | then (cache,DAE.DAE(elts)); |
| 3018 | end matchcontinue; |
| 3019 | end makeIfEquation; |
| 3020 | |
| 3021 | protected function makeIfEquation2 |
| 3022 | input Boolean isInitial; |
| 3023 | input list<DAE.Exp> exps; |
| 3024 | input list<list<DAE.Element>> tbs; |
| 3025 | input list<DAE.Element> fb; |
| 3026 | input DAE.ElementSource source; |
| 3027 | output list<DAE.Element> outElements; |
| 3028 | algorithm |
| 3029 | outElements := matchcontinue (isInitial,exps,tbs,fb,source) |
| 3030 | case (_,{},_,fb,source) |
| 3031 | then fb; |
| 3032 | case (false,exps,tbs,fb,source) |
| 3033 | then DAE.IF_EQUATION(exps,tbs,fb,source)::{}; |
| 3034 | case (true,exps,tbs,fb,source) |
| 3035 | then DAE.INITIAL_IF_EQUATION(exps,tbs,fb,source)::{}; |
| 3036 | end matchcontinue; |
| 3037 | end makeIfEquation2; |
| 3038 | |