Skip to content

Commit

Permalink
[NF] Fix some variability issues.
Browse files Browse the repository at this point in the history
- Changed pre and change to be discrete and ndims to be parameter,
  as per the specification.
- Derive the variability of components with no explicit variability
  by using their types.
- Hacked the variability of relations to be at most discrete to
  avoid breaking implicitly discrete variables, needs to be fixed
  properly for e.g. noEvent.

Belonging to [master]:
  - OpenModelica/OMCompiler#2060
  - OpenModelica/OpenModelica-testsuite#798
  • Loading branch information
perost authored and OpenModelica-Hudson committed Nov 29, 2017
1 parent 12d1ede commit 83ffab2
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 4 deletions.
4 changes: 3 additions & 1 deletion Compiler/NFFrontEnd/NFCall.mo
Expand Up @@ -948,6 +948,7 @@ protected
argtycall := typeNormalCall(call, info);
(call , ty, variability) := matchTypedNormalCall(argtycall, info);
call := unboxArgs(call);
variability := Variability.PARAMETER;
end typeNdimsCall;

function typeSampleCall
Expand Down Expand Up @@ -991,7 +992,7 @@ protected
end if;

call := unboxArgs(call);

variability := Variability.DISCRETE;
end typePreCall;

function typeChangeCall
Expand Down Expand Up @@ -1020,6 +1021,7 @@ protected
fail();
end if;

variability := Variability.DISCRETE;
end typeChangeCall;

function typeReinitCall
Expand Down
18 changes: 18 additions & 0 deletions Compiler/NFFrontEnd/NFComponent.mo
Expand Up @@ -403,17 +403,35 @@ uniontype Component
end isOutput;

function variability
"Returns a component's variability, using the component's type to infer the
variability if no variability has been given explicitly."
input Component component;
output Variability variability;
algorithm
variability := match component
case TYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
case TYPED_COMPONENT() guard Type.isDiscrete(component.ty) then Variability.DISCRETE;
case UNTYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
case ITERATOR() then Variability.CONSTANT;
case ENUM_LITERAL() then Variability.CONSTANT;
else Variability.CONTINUOUS;
end match;
end variability;

function variabilityExplicit
"Returns a component's explicitly given variability, or CONTINUOUS."
input Component component;
output Variability variability;
algorithm
variability := match component
case TYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
case UNTYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
case ITERATOR() then Variability.CONSTANT;
case ENUM_LITERAL() then Variability.CONSTANT;
else Variability.CONTINUOUS;
end match;
end variabilityExplicit;

function isConst
input Component component;
output Boolean isConst = variability(component) == Variability.CONSTANT;
Expand Down
4 changes: 3 additions & 1 deletion Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -74,6 +74,7 @@ import Face = NFConnector.Face;
import System;
import ComplexType = NFComplexType;
import NFInstNode.CachedData;
import NFPrefixes.Variability;

public
type FunctionTree = FunctionTreeImpl.Tree;
Expand Down Expand Up @@ -228,7 +229,8 @@ algorithm
new_pre := ComponentRef.prefixCref(comp_node, ty, {}, prefix);
binding := flattenBinding(c.binding, prefix, comp_node);

if Type.isArray(ty) and Binding.isBound(binding) and Component.isVar(c) then
if Type.isArray(ty) and Binding.isBound(binding) and
Component.variability(c) >= Variability.DISCRETE then
comps := (new_pre, Binding.UNBOUND()) :: comps;
sections := Sections.prependEquation(
Equation.ARRAY_EQUALITY(Expression.CREF(ty, new_pre), Binding.getTypedExp(binding), ty, c.info),
Expand Down
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -410,7 +410,7 @@ uniontype Function

// Add the type if the parameter has been typed.
if printTypes and Component.isTyped(c) then
var_s := if Component.variability(c) < Variability.CONTINUOUS then Prefixes.variabilityString(Component.variability(c)) + " " else "";
var_s := Prefixes.unparseVariability(Component.variabilityExplicit(c));
input_str := var_s + Type.toString(Component.getType(c)) + " " + input_str;
end if;

Expand Down
12 changes: 12 additions & 0 deletions Compiler/NFFrontEnd/NFPrefixes.mo
Expand Up @@ -205,6 +205,18 @@ algorithm
end match;
end variabilityString;

function unparseVariability
input Variability var;
output String str;
algorithm
str := match var
case Variability.CONSTANT then "constant ";
case Variability.PARAMETER then "parameter ";
case Variability.DISCRETE then "discrete ";
else "";
end match;
end unparseVariability;

function variabilityMax
input Variability var1;
input Variability var2;
Expand Down
15 changes: 15 additions & 0 deletions Compiler/NFFrontEnd/NFType.mo
Expand Up @@ -519,5 +519,20 @@ public
end match;
end isEqual;

function isDiscrete
input Type ty;
output Boolean isDiscrete;
algorithm
isDiscrete := match ty
case INTEGER() then true;
case STRING() then true;
case BOOLEAN() then true;
case ENUMERATION() then true;
case ARRAY() then isDiscrete(ty.elementType);
case FUNCTION() then isDiscrete(ty.resultType);
else false;
end match;
end isDiscrete;

annotation(__OpenModelica_Interface="frontend");
end NFType;
4 changes: 3 additions & 1 deletion Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -1008,8 +1008,10 @@ algorithm
(e1, ty1, var1) := typeExp(exp.exp1, info, next_origin);
(e2, ty2, var2) := typeExp(exp.exp2, info, next_origin);
(exp, ty) := TypeCheck.checkRelationOperation(e1, ty1, exp.operator, e2, ty2);
// TODO: Implement this properly according to 3.8.3 in the spec.
variability := Prefixes.variabilityMin(Prefixes.variabilityMax(var1, var2), Variability.DISCRETE);
then
(exp, ty, Prefixes.variabilityMax(var1, var2));
(exp, ty, variability);

case Expression.IF()
algorithm
Expand Down

0 comments on commit 83ffab2

Please sign in to comment.