diff --git a/Compiler/NFFrontEnd/NFEvalConstants.mo b/Compiler/NFFrontEnd/NFEvalConstants.mo index 7abd775b089..fa498b42f48 100644 --- a/Compiler/NFFrontEnd/NFEvalConstants.mo +++ b/Compiler/NFFrontEnd/NFEvalConstants.mo @@ -59,33 +59,41 @@ import Package = NFPackage; public function evaluate input output FlatModel flatModel; +protected + Variability const_var; algorithm - flatModel.variables := list(evaluateVariable(v) for v in flatModel.variables); - flatModel.equations := evaluateEquations(flatModel.equations); - flatModel.initialEquations := evaluateEquations(flatModel.initialEquations); - flatModel.algorithms := evaluateAlgorithms(flatModel.algorithms); - flatModel.initialAlgorithms := evaluateAlgorithms(flatModel.initialAlgorithms); + const_var := if Flags.getConfigBool(Flags.CHECK_MODEL) then + Variability.CONSTANT else Variability.STRUCTURAL_PARAMETER; + + flatModel.variables := list(evaluateVariable(v, const_var) for v in flatModel.variables); + flatModel.equations := evaluateEquations(flatModel.equations, const_var); + flatModel.initialEquations := evaluateEquations(flatModel.initialEquations, const_var); + flatModel.algorithms := evaluateAlgorithms(flatModel.algorithms, const_var); + flatModel.initialAlgorithms := evaluateAlgorithms(flatModel.initialAlgorithms, const_var); execStat(getInstanceName()); end evaluate; function evaluateVariable input output Variable var; + input Variability constVariability; protected Binding binding; algorithm - binding := evaluateBinding(var.binding, Variable.isStructural(var)); + binding := evaluateBinding(var.binding, + Variable.variability(var) <= constVariability, constVariability); if not referenceEq(binding, var.binding) then var.binding := binding; end if; - var.typeAttributes := list(evaluateTypeAttribute(a) for a in var.typeAttributes); + var.typeAttributes := list(evaluateTypeAttribute(a, constVariability) for a in var.typeAttributes); end evaluateVariable; function evaluateBinding input output Binding binding; input Boolean structural; + input Variability constVariability; protected Expression exp, eexp; algorithm @@ -95,7 +103,7 @@ algorithm if structural then eexp := Ceval.evalExp(exp, Ceval.EvalTarget.ATTRIBUTE(binding)); else - eexp := evaluateExp(exp); + eexp := evaluateExp(exp, constVariability); end if; if not referenceEq(exp, eexp) then @@ -106,6 +114,7 @@ end evaluateBinding; function evaluateTypeAttribute input output tuple attribute; + input Variability constVariability; protected String name; Binding binding, sbinding; @@ -113,7 +122,7 @@ protected algorithm (name, binding) := attribute; structural := name == "fixed" or name == "stateSelect"; - sbinding := evaluateBinding(binding, structural); + sbinding := evaluateBinding(binding, structural, constVariability); if not referenceEq(binding, sbinding) then attribute := (name, sbinding); @@ -122,13 +131,15 @@ end evaluateTypeAttribute; function evaluateExp input Expression exp; + input Variability constVariability; output Expression outExp; algorithm - outExp := evaluateExpTraverser(exp, false); + outExp := evaluateExpTraverser(exp, constVariability, false); end evaluateExp; function evaluateExpTraverser input Expression exp; + input Variability constVariability; input Boolean changed; output Expression outExp; output Boolean outChanged; @@ -136,15 +147,17 @@ protected Expression e; ComponentRef cref; Type ty; + Variability var; algorithm outExp := match exp case Expression.CREF() algorithm (outExp as Expression.CREF(cref = cref, ty = ty), outChanged) := - Expression.mapFoldShallow(exp, evaluateExpTraverser, false); + Expression.mapFoldShallow(exp, + function evaluateExpTraverser(constVariability = constVariability), false); // Evaluate constants and structural parameters. - if ComponentRef.nodeVariability(cref) <= Variability.STRUCTURAL_PARAMETER then + if ComponentRef.nodeVariability(cref) <= constVariability then // Evaluate all constants and structural parameters. outExp := Ceval.evalCref(cref, outExp, Ceval.EvalTarget.IGNORE_ERRORS(), evalSubscripts = false); outChanged := true; @@ -157,7 +170,8 @@ algorithm else algorithm - (outExp, outChanged) := Expression.mapFoldShallow(exp, evaluateExpTraverser, false); + (outExp, outChanged) := Expression.mapFoldShallow(exp, + function evaluateExpTraverser(constVariability = constVariability), false); then if outChanged then Expression.retype(outExp) else outExp; end match; @@ -175,7 +189,7 @@ algorithm case Dimension.EXP() algorithm - e := evaluateExp(dim.exp); + e := evaluateExp(dim.exp, constVariability = Variability.STRUCTURAL_PARAMETER); then if referenceEq(e, dim.exp) then dim else Dimension.fromExp(e, dim.var); @@ -185,11 +199,13 @@ end evaluateDimension; function evaluateEquations input list eql; - output list outEql = list(evaluateEquation(e) for e in eql); + input Variability constVariability; + output list outEql = list(evaluateEquation(e, constVariability) for e in eql); end evaluateEquations; function evaluateEquation input output Equation eq; + input Variability constVariability; algorithm eq := match eq local @@ -199,60 +215,61 @@ algorithm case Equation.EQUALITY() algorithm ty := Type.mapDims(eq.ty, evaluateDimension); - e1 := evaluateExp(eq.lhs); - e2 := evaluateExp(eq.rhs); + e1 := evaluateExp(eq.lhs, constVariability); + e2 := evaluateExp(eq.rhs, constVariability); then Equation.EQUALITY(e1, e2, ty, eq.source); case Equation.ARRAY_EQUALITY() algorithm ty := Type.mapDims(eq.ty, evaluateDimension); - e2 := evaluateExp(eq.rhs); + e2 := evaluateExp(eq.rhs, constVariability); then Equation.ARRAY_EQUALITY(eq.lhs, e2, ty, eq.source); case Equation.FOR() algorithm - eq.range := Util.applyOption(eq.range, evaluateExp); - eq.body := evaluateEquations(eq.body); + eq.range := Util.applyOption(eq.range, + function evaluateExp(constVariability = constVariability)); + eq.body := evaluateEquations(eq.body, constVariability); then eq; case Equation.IF() algorithm - eq.branches := list(evaluateEqBranch(b) for b in eq.branches); + eq.branches := list(evaluateEqBranch(b, constVariability) for b in eq.branches); then eq; case Equation.WHEN() algorithm - eq.branches := list(evaluateEqBranch(b) for b in eq.branches); + eq.branches := list(evaluateEqBranch(b, constVariability) for b in eq.branches); then eq; case Equation.ASSERT() algorithm - e1 := evaluateExp(eq.condition); - e2 := evaluateExp(eq.message); - e3 := evaluateExp(eq.level); + e1 := evaluateExp(eq.condition, constVariability); + e2 := evaluateExp(eq.message, constVariability); + e3 := evaluateExp(eq.level, constVariability); then Equation.ASSERT(e1, e2, e3, eq.source); case Equation.TERMINATE() algorithm - eq.message := evaluateExp(eq.message); + eq.message := evaluateExp(eq.message, constVariability); then eq; case Equation.REINIT() algorithm - eq.reinitExp := evaluateExp(eq.reinitExp); + eq.reinitExp := evaluateExp(eq.reinitExp, constVariability); then eq; case Equation.NORETCALL() algorithm - eq.exp := evaluateExp(eq.exp); + eq.exp := evaluateExp(eq.exp, constVariability); then eq; @@ -262,6 +279,7 @@ end evaluateEquation; function evaluateEqBranch input Branch branch; + input Variability constVariability; output Branch outBranch; algorithm outBranch := match branch @@ -271,8 +289,8 @@ algorithm case Branch.BRANCH(condition = condition, body = body) algorithm - condition := evaluateExp(condition); - body := evaluateEquations(body); + condition := evaluateExp(condition, constVariability = Variability.STRUCTURAL_PARAMETER); + body := evaluateEquations(body, constVariability); then Branch.BRANCH(condition, branch.conditionVar, body); @@ -282,22 +300,26 @@ end evaluateEqBranch; function evaluateAlgorithms input list algs; - output list outAlgs = list(evaluateAlgorithm(a) for a in algs); + input Variability constVariability; + output list outAlgs = list(evaluateAlgorithm(a, constVariability) for a in algs); end evaluateAlgorithms; function evaluateAlgorithm input output Algorithm alg; + input Variability constVariability; algorithm - alg.statements := evaluateStatements(alg.statements); + alg.statements := evaluateStatements(alg.statements, constVariability); end evaluateAlgorithm; function evaluateStatements input list stmts; - output list outStmts = list(evaluateStatement(s) for s in stmts); + input Variability constVariability; + output list outStmts = list(evaluateStatement(s, constVariability) for s in stmts); end evaluateStatements; function evaluateStatement input output Statement stmt; + input Variability constVariability; algorithm stmt := match stmt local @@ -307,54 +329,55 @@ algorithm case Statement.ASSIGNMENT() algorithm ty := Type.mapDims(stmt.ty, evaluateDimension); - e1 := evaluateExp(stmt.lhs); - e2 := evaluateExp(stmt.rhs); + e1 := evaluateExp(stmt.lhs, constVariability); + e2 := evaluateExp(stmt.rhs, constVariability); then Statement.ASSIGNMENT(e1, e2, ty, stmt.source); case Statement.FOR() algorithm - stmt.range := Util.applyOption(stmt.range, evaluateExp); - stmt.body := evaluateStatements(stmt.body); + stmt.range := Util.applyOption(stmt.range, + function evaluateExp(constVariability = constVariability)); + stmt.body := evaluateStatements(stmt.body, constVariability); then stmt; case Statement.IF() algorithm - stmt.branches := list(evaluateStmtBranch(b) for b in stmt.branches); + stmt.branches := list(evaluateStmtBranch(b, constVariability) for b in stmt.branches); then stmt; case Statement.WHEN() algorithm - stmt.branches := list(evaluateStmtBranch(b) for b in stmt.branches); + stmt.branches := list(evaluateStmtBranch(b, constVariability) for b in stmt.branches); then stmt; case Statement.ASSERT() algorithm - e1 := evaluateExp(stmt.condition); - e2 := evaluateExp(stmt.message); - e3 := evaluateExp(stmt.level); + e1 := evaluateExp(stmt.condition, constVariability); + e2 := evaluateExp(stmt.message, constVariability); + e3 := evaluateExp(stmt.level, constVariability); then Statement.ASSERT(e1, e2, e3, stmt.source); case Statement.TERMINATE() algorithm - stmt.message := evaluateExp(stmt.message); + stmt.message := evaluateExp(stmt.message, constVariability); then stmt; case Statement.NORETCALL() algorithm - stmt.exp := evaluateExp(stmt.exp); + stmt.exp := evaluateExp(stmt.exp, constVariability); then stmt; case Statement.WHILE() algorithm - stmt.condition := evaluateExp(stmt.condition); - stmt.body := evaluateStatements(stmt.body); + stmt.condition := evaluateExp(stmt.condition, constVariability); + stmt.body := evaluateStatements(stmt.body, constVariability); then stmt; @@ -364,14 +387,15 @@ end evaluateStatement; function evaluateStmtBranch input tuple> branch; + input Variability constVariability; output tuple> outBranch; protected Expression cond; list body; algorithm (cond, body) := branch; - cond := evaluateExp(cond); - body := evaluateStatements(body); + cond := evaluateExp(cond, constVariability = Variability.STRUCTURAL_PARAMETER); + body := evaluateStatements(body, constVariability); outBranch := (cond, body); end evaluateStmtBranch; diff --git a/Compiler/NFFrontEnd/NFVariable.mo b/Compiler/NFFrontEnd/NFVariable.mo index cb02079f9da..b17cc5f212d 100644 --- a/Compiler/NFFrontEnd/NFVariable.mo +++ b/Compiler/NFFrontEnd/NFVariable.mo @@ -86,6 +86,11 @@ public variable.attributes.variability <= Variability.STRUCTURAL_PARAMETER; end isStructural; + function variability + input Variable variable; + output Variability variability = variable.attributes.variability; + end variability; + function isEmptyArray input Variable variable; output Boolean isEmpty = Type.isEmptyArray(variable.ty);