Skip to content

Commit

Permalink
Update grammar.md
Browse files Browse the repository at this point in the history
  • Loading branch information
olivleno committed Dec 10, 2019
1 parent d8b2c8e commit 2e2a722
Showing 1 changed file with 30 additions and 29 deletions.
59 changes: 30 additions & 29 deletions RationaleMCP/0031/grammar.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,30 +83,31 @@ end _F;
> _class-definition_**encapsulated**? _class-prefixes_ _class-specifier_
> _class-prefixes_\
>   **partial**?\
>   ( **class**\
>   | **model**\
>   ~~**partial**?~~\
>   ( ~~**class**~~\
>   | ~~**model**~~\
>   | **flat_model**\

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 11, 2019

Collaborator

If we were to go with a language version header, I don't see that there would be an absolute need to replace model by flat_model. On the other hand, in case someone ignores the language version header, using a non-Modelica keyword might also serve to make sure that the file isn't interpreted as Modelica by mistake.

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 12, 2019

Collaborator

I can live with model .

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 17, 2019

Author Collaborator

But isn't a flat model something different than a model? - Encoding a type information in a version definition doesn't seem right to me?

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 18, 2019

Collaborator

Conceptually, the Flat Modelica model is very similar to a model class in Modelica. Anyway, I don't think that this should be discussed as a matter of which keyword to use, but rather as a matter of choosing the top level structure of Flat Modelica. I think that separating function and type definitions from the model variables and equations would be preferable over mixing everything inside one big container. In such a design, we wouldn't need the top level element at all, and if we would have one it should probably be package or flat_modelica_package. Figuring this out is not about getting rid of the obviously irrelevant parts of the grammar, so I'll add it as a roadmap item.

>   | **operator**? **record**\
>   | **block**\
>   | **expandable**? **connector**\
>   | ~~**block**~~\
>   | ~~**expandable**? **connector**~~\
>   | **type**\
>   | **package**\
>   | ~~**package**~~\
>   | ( **pure** | **impure** )? **operator**? **function**\
>   | **operator**\
>   )
> _class-specifier__long-class-specifier_ | _short-class-specifier_ | _der-class-specifier_
> _class-specifier__long-class-specifier_ ~~| _short-class-specifier_~~ | _der-class-specifier_
> _long-class-specifier_\
>  _IDENT_ _string-comment_ _composition_ **end** _IDENT_\
>   | **extends** _IDENT_ _class-modification_? _string-comment_ _composition_ **end** _IDENT_
>   ~~| **extends** _IDENT_ _class-modification_? _string-comment_ _composition_ **end** _IDENT_~~
> _short-class-specifier_\
~~> _short-class-specifier_\

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 11, 2019

Collaborator

I think we need these for the planned support of type aliases.

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 12, 2019

Collaborator

Agree.

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 13, 2019

Author Collaborator

I have a hard time to see what exactly you're referring to by

we need these

Is there a way to figure which line a comment is linked to? Or mybe you could be more explicit and quote the content you refer to please.

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 17, 2019

Collaborator

Yes, the comment appears right below the commented line(s). In this case, this refers to the removal of short-class-specifier.

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 19, 2019

Author Collaborator

Web Meeting: revert.

>   _IDENT_ **=**\
>   ( _base-prefix_? _type-specifier_ _array-subscripts_? _class-modification_?\
>   | **enumeration** `[(]` ( _enum-list_? | **:** ) `[)]`\
>   )\
>   _comment_
>   _comment_~~
> _der-class-specifier__IDENT_ **=** **der** `[(]` _type-specifier_ **,** _IDENT_ ( **,** _IDENT_ )* `[)]` _comment_
Expand All @@ -132,32 +133,32 @@ end _F;
> _external-function-call_ → ( _component-reference_ **=** )? _IDENT_ `[(]` _expression-list_? `[)]`
> _generic-element__import-clause_ | _extends-clause_ | _normal-element_
> _generic-element_~~_import-clause_ | _extends-clause_ |~~ _normal-element_
> _normal-element_\
>   ~~**redeclare**?~~\
>   **final**?\

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 12, 2019

Collaborator

final is only needed to handle parameters with literal values as constants. Parameters with other expressions are dependent parameters anyway and are not changeable later. Alternatively, 'final parameter' can be replaced by 'constant' in this case.

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 13, 2019

Collaborator

First, I think this kind of reasoning makes a dangerous assumption about being able to distinguish between literals and constants in general:

constant Real p = 1;
parameter Real q = p; /* Is this a 'dependent parameter? */

Second, I believe it is a popular assumption made by tools that the user intention of a parameter bound to a non-literal is that it should be treated as final. It is still possible to mark such as parameter as final, and interpret

parameter Real p = 1;
parameter Real q = p;

as q defaulting to p, but allowing this to be changed. I find this much more elegant from a language design point of view, as it gives final a meaning that is independent of the literal-status of the expression, and at the same time making it possible to express non-final defaults that aren't just literals.

I guess it's clear by now that final doesn't belong to the obviously irrelevant parts, and that we should keep it for now, and come back to it when we work on the road map item Investigate need for final.

This comment has been minimized.

Copy link
@casella

casella Dec 13, 2019

Collaborator

I disagree with @gkurzbach's statements. AFAIK, nowhere the specification says that parameters bound to non-literals should be considered as non-modifiable, and there libraries that rely on this assumption. For example, a common user pattern is

parameter Real p = system.p "Default parameter value provided by system object";

If I really mean this shouldn't be changed, I would definitely write

final parameter Real p = system.p "Default parameter value provided by system object";

or at least

parameter Real p = system.p "Default parameter value provided by system object" annotation(Evaluate = true);

if I want to be able to modify it when instantiating, but I want it to be evaluated at compile time.

As far as I understand, OpenModelica doesn't make this assumption at all.

Hence, I agree with @henrikt-ma that final is not obviously irrelevant and should be discussed at the proper time

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 13, 2019

Collaborator

@casella 'final' means "not changeable by modification". But in this stage in FlatModelica possible changes by modification are already performed. What I mean with "changeable" is changeable after compilation. So if a parameter refers to another parameter or even constant, it is at the first place a declaration equation in FlatModelica and there will be some code generated, assigning the value for the referenced parameter to this (as usual with dependent parameters). How should be decided at run time, whether a parameter is changed from outside and needs no further assignment, or not?

This comment has been minimized.

Copy link
@HansOlsson

HansOlsson Dec 13, 2019

Collaborator

I generally agree with @gkurzbach here, but there are some minor issues.

Originally Dymola differentiated between parameter Real p=2; and parameter Real q=foo(...); based on the idea that there was code for q and changing q to a number would remove that code so that it was not practical.
But then we have e.g. parameter Real q=sqrt(4.0); and parameter Complex c=Complex(2,3);.

Thus I think that if we want to capture how the model can be used then it makes sense that flat-Modelica doesn't capture the original model, but we add final to parameters that can longer be changed - due to the tool-specific rules.

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 13, 2019

Collaborator

Thus I think that if we want to capture how the model can be used then it makes sense that flat-Modelica doesn't capture the original model, but we add final to parameters that can longer be changed- due to the tool-specific rules.

This, in bold, I don't understand.

This comment has been minimized.

Copy link
@HansOlsson

HansOlsson Dec 13, 2019

Collaborator

Oops. It should have read "we add final to parameters that can no longer be changed"

This comment has been minimized.

Copy link
@casella

casella Dec 13, 2019

Collaborator

@casella 'final' means "not changeable by modification". But in this stage in FlatModelica possible changes by modification are already performed. What I mean with "changeable" is changeable after compilation.

@gkurzbach, Sect. 7.2.6 of the Modelica Specification states:

An element defined as final by the final prefix in an element modification or declaration cannot be modified by
a modification or by a redeclaration. All elements of a final element are also final. [Setting the value of a
parameter in an experiment environment is conceptually treated as a modification. This implies that a final
modification equation of a parameter cannot be changed in a simulation environment]
.

Although the interpretation of final as not changeable after compilation is non normative, it is nevertheless recommended by the specification. Shouldn't we follow that?

So if a parameter refers to another parameter or even constant, it is at the first place a declaration equation in FlatModelica and there will be some code generated, assigning the value for the referenced parameter to this (as usual with dependent parameters). How should be decided at run time, whether a parameter is changed from outside and needs no further assignment, or not?

As I see it, final parameters cannot be changed at runtime, non-finals can, unless a) they are structural parameters (i.e. they influence the mathematical structure of the problem, e.g. the size of arrys) or b) the user instructed the compiler to evaluate all (or some) parameters when generating the runtime code.

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 14, 2019

Collaborator

An element defined as final by the final prefix in an element modification or declaration cannot be modified by
a modification or by a redeclaration. All elements of a final element are also final. [Setting the value of a
parameter in an experiment environment is conceptually treated as a modification. This implies that a final
modification equation of a parameter cannot be changed in a simulation environment]
.

Although the interpretation of final as not changeable after compilation is non normative, it is nevertheless recommended by the specification. Shouldn't we follow that?

@casella Thank you for pointing this out. I overlooked it. So we may keep 'final' in the language.

But I still not see how it works. Given, there are three parameters 'p', not marked with 'final', 'q', marked with 'final', and 'r' not marked with 'final': 'p' refers to 'q', 'q' refers to 'r' and 'r' has a literal.

Usually after compilation there are two functions: 'Initialize', where the changeable parameters and all other constants get their values initially and 'UpdateDependendParameters', where dependend parameters are calculated and assigned. Inbetween the calls of these two, the changeable parameters may get a new value from outside.

So changeable parameters (as 'p' and 'r') must not be assigned in 'UpdateDependendParameters', because then the value from outside will be overwitten with a calculated one. So they are assigned in 'Initialize'. Non-changeable 'final' parameters (as 'q') referring to another parameter have to be assigned in 'UpdateDependendParameters' to get the updated value from changeable parameters.

If, in this scenario, 'r' is set from outside, 'q' is updated in 'UpdateDependendParameters' but 'p' does not get the updated value. If 'p' would be assigned in 'UpdateDependendParameters' then changes of 'p' from outside are overwritten by the assignment and therefore lost.

How to solve this?

This comment has been minimized.

Copy link
@casella

casella Dec 16, 2019

Collaborator

I understand this is the intended behaviour. If you wanted 'p' to be updated automatically, you should mark it as final.

Do I miss something?

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 17, 2019

Collaborator

I dont' see this as intended, because there is an equation 'p=q' and this doesn't hold if 'r' is changed.
So something is wrong. May be, referring from a non-final parameter to a final parameter has to be forbidden in Modelica. But this would be strange, because models could become invalid, just by adding a final modification.

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 17, 2019

Collaborator

Please don't have this conversation here. There will be a much better place for this when we look more closely at what to do with final. This PR is only for removing the obviously irrelevant parts of the grammar. Perhaps someone would like to initiate a PR where the discussion can be continued? It is definitely a very important and interesting topic.

This comment has been minimized.

Copy link
@casella

casella Dec 18, 2019

Collaborator

I agree. BTW, when we have it in the proper place, please add the explicit source code of the example we are discussion, otherwise I find it a bit hard to follow.

Thanks!

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 19, 2019

Author Collaborator

Web Meeting: Separate issue.

>   **inner**? **outer**?\
>   ( _class-definition_\
>   ~~**inner**? **outer**?~~\
>   ( ~~_class-definition_~~\

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 11, 2019

Collaborator

Are we sure that this isn't where we want the function definitions to go?

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 12, 2019

Collaborator

Yes, we need class-definitions for type aliases and functions here. But it doesn't have to be recursive. So, we can divide between the (global) model-definition and (local) class-definition. The model-definition needs a class-definition, the class-definition itself not.

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 13, 2019

Collaborator

Sounds good.

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 19, 2019

Author Collaborator

Web Meeting: Related to top level structure, to be discussed there.

>   | _component-clause_\
>   | ~~**replaceable**~~ ( _class-definition_ | _component-clause_ ) ( _constraining-clause_ _comment_ )?\
>   ~~| **replaceable** ( _class-definition_ | _component-clause_ ) ( _constraining-clause_ _comment_ ~~)?\
>   )
> _import-clause_\
> ~~_import-clause_\
>   **import**\
>   ( _IDENT_ **=** _name_\
>   | _name_ ( `[.]` ( `[*]` | **{** _import-list_ **}** ) | `[.][*]` )?\
>   )\
>   _comment_
> _import-list__IDENT_ ( **,** _IDENT_ )*
> ~~_import-list__IDENT_ ( **,** _IDENT_ )*

## B23 Extends

> _extends-clause_**extends** _type-specifier_ _class-modification_? _annotation-comment_?
> ~~_extends-clause_**extends** _type-specifier_ _class-modification_? _annotation-comment_?
> _constraining-clause_**constrainedby** _type-specifier_ _class-modification_?
> ~~_constraining-clause_**constrainedby** _type-specifier_ _class-modification_?

## B24 Component**clause**
Expand All @@ -179,27 +180,27 @@ end _F;

## B25 Modification

> _modification_\
> ~~_modification_\

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 11, 2019

Collaborator

modification is still present in declaration.

This comment has been minimized.

Copy link
@gkurzbach

gkurzbach Dec 12, 2019

Collaborator

I would prefer to reduce the modification to the declaration equation and to remove the class-modification.
The only case where it would be used is the to specify equations to attributes of parameter a variables. This could also be handled by having attributes a normal parameters or constants: e.g.

Real 'v';
parameter Real 'v.start'=1;

The relation is then given by the name. Instead of parameter, a new prefix attribute could be invented.

Atleast, I would restrict class-modification to a non recursive rule.

Also remove the ":=" case, because this is obsolete in Modelica already.

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 13, 2019

Collaborator

Let's begin with the easy parts, and come back later to the attributes.

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 19, 2019

Author Collaborator

Web Meeting:
Removal would require to invent something new e.g. for records and structures.
To be discussed further in an new issue: "Simplify modifications".

>  _class-modification_ ( **=** _expression_ )?\
>   | **=** _expression_\
>   | **:=** _expression_
> _class-modification_`[(]` _argument-list_? `[)]`
> ~~_class-modification_`[(]` _argument-list_? `[)]`
> _argument-list__argument_ ( **,** _argument_ )*
> ~~_argument-list__argument_ ( **,** _argument_ )*
> _argument_\
> ~~_argument_\
>  _element-modification-or-replaceable_\
>   ~~| _element-redeclaration_~~
>   | _element-redeclaration_~~
> _element-modification-or-replaceable_\
> ~~_element-modification-or-replaceable_\
>   **each**?\
>   **final**?\
>   ( _element-modification_\
>   ~~| _element-replaceable_~~\
>   | _element-replaceable_~~\
>   )
> _element-modification__name_ _modification_? _string-comment_
> ~~_element-modification__name_ _modification_? _string-comment_
> ~~_element-redeclaration_~~\
> ~~  **redeclare** **each**? **final**?~~\
Expand All @@ -219,15 +220,15 @@ end _F;
> ~~_component-declaration1__declaration_ _comment_~~
> _short-class-definition__class-prefixes_ _short-class-specifier_
> ~~_short-class-definition__class-prefixes_ _short-class-specifier_
## B26 Equations

> _equation_\
>   ( _simple-expression_ ( **=** _expression_ )?\
>   | _if-equation_\
>   | _for-equation_\
>   | _connect-clause_\
> ~~  | _connect-clause_~~\

This comment has been minimized.

Copy link
@henrikt-ma

henrikt-ma Dec 11, 2019

Collaborator

Right, let's see if someone objects to this.

This comment has been minimized.

Copy link
@casella

casella Dec 13, 2019

Collaborator

Maybe I'm missing something, but in my view connect statements shouldn't be part of flat Modelica at all. I understand the whole point of flat Modelica is to get rid of all the object-oriented superstructure, and remain with the naked equations for further mathematical treatment. Handling connect statements is definitely object-oriented stuff, and definitely non-trivial (think of stream connectors with inside and outside connections).

Maybe we could keep connect statements optional, because it may be useful to retain them in some contexts, but not in others. However, if I were writing a numerical back-end that is going to rely on flat Modelica input (as we actually are) , I wouldn't want to bother about processing connect statements at all.

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 17, 2019

Author Collaborator

Yes, connect should be removed.

This comment has been minimized.

Copy link
@olivleno

olivleno Dec 19, 2019

Author Collaborator

Web Meeting:
Remove but consider an annotation to enable advanced heuristics relying on the OO-structure.
New issue: "Allow to identify connector variables"

>   | _when-equation_\
>   )\
>   _comment_
Expand Down Expand Up @@ -301,7 +302,7 @@ end _F;
>   )* \
>   **end** **when**
> _connect-clause_**connect** `[(]` _component-reference_ **,** _component-reference_ `[)]`
> ~~_connect-clause_**connect** `[(]` _component-reference_ **,** _component-reference_ `[)]`

## Expressions
Expand Down

0 comments on commit 2e2a722

Please sign in to comment.