Skip to content

Commit

Permalink
[NF] Improve unit checking.
Browse files Browse the repository at this point in the history
- Make constant variability configurable in EvalConstants, and use it to
  not evaluate structural parameters in general when checking a model.

Belonging to [master]:
  - #170
  - OpenModelica/OMCompiler#3082
  • Loading branch information
perost authored and OpenModelica-Hudson committed May 8, 2019
1 parent 6cebda4 commit d2540cc
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 48 deletions.
120 changes: 72 additions & 48 deletions Compiler/NFFrontEnd/NFEvalConstants.mo
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -106,14 +114,15 @@ end evaluateBinding;

function evaluateTypeAttribute
input output tuple<String, Binding> attribute;
input Variability constVariability;
protected
String name;
Binding binding, sbinding;
Boolean structural;
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);
Expand All @@ -122,29 +131,33 @@ 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;
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;
Expand All @@ -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;
Expand All @@ -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);

Expand All @@ -185,11 +199,13 @@ end evaluateDimension;

function evaluateEquations
input list<Equation> eql;
output list<Equation> outEql = list(evaluateEquation(e) for e in eql);
input Variability constVariability;
output list<Equation> 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
Expand All @@ -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;

Expand All @@ -262,6 +279,7 @@ end evaluateEquation;

function evaluateEqBranch
input Branch branch;
input Variability constVariability;
output Branch outBranch;
algorithm
outBranch := match branch
Expand All @@ -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);

Expand All @@ -282,22 +300,26 @@ end evaluateEqBranch;

function evaluateAlgorithms
input list<Algorithm> algs;
output list<Algorithm> outAlgs = list(evaluateAlgorithm(a) for a in algs);
input Variability constVariability;
output list<Algorithm> 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<Statement> stmts;
output list<Statement> outStmts = list(evaluateStatement(s) for s in stmts);
input Variability constVariability;
output list<Statement> 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
Expand All @@ -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;

Expand All @@ -364,14 +387,15 @@ end evaluateStatement;

function evaluateStmtBranch
input tuple<Expression, list<Statement>> branch;
input Variability constVariability;
output tuple<Expression, list<Statement>> outBranch;
protected
Expression cond;
list<Statement> 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;

Expand Down
5 changes: 5 additions & 0 deletions Compiler/NFFrontEnd/NFVariable.mo
Expand Up @@ -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);
Expand Down

0 comments on commit d2540cc

Please sign in to comment.