modelica / ModelicaSpecification

Specification of the Modelica Language
https://specification.modelica.org
Creative Commons Attribution Share Alike 4.0 International
104 stars 40 forks source link

Forcing function call sequence / use of short class definition for functions #1795

Closed modelica-trac-importer closed 6 years ago

modelica-trac-importer commented 6 years ago

Reported by otter on 6 Oct 2015 11:35 UTC In https://trac.openmodelica.org/OpenModelica/ticket/3383 an issue with OpenModelica is reported to fail simulation of the Modelica_Noise library. There are different opinions what is correct Modelica 3.2. I would like to ask the Modelica language specialists whether the following model is correct Modelica (and if not, how to correct it). Here is simplified version of the code (some irrelevant optional parts are removed; the code simulates correctly in Dymola):

model GlobalSeed
  final parameter Integer id = 
        initializeImpureRandrom( automaticSeed() );

  function randomInteger=impureRandomInteger(final id=id);  
end GlobalSeed;

model TestRandom
  inner GlobalSeed globalSeed;
  ModelWithRandom modelWithRandom;
end TestRandom;

model ModelWithRandom
  output Real r "Random number in the range 0..1"
protected
  outer GlobalSeed globalSeed;
  discrete Integer state[4];
  discrete Integer localSeed;
equation
  when initial() then
     localSeed = globalSeed.randomInteger(); 
  end when;
initial equation
  pre(state) = pureRandomInitialize(localSeed)
equation
  when sample(0,0.1) then
     (r, pre(state)) = pureRandom(state)
  end when;
end ModelWithRandom;

Short explanation: Whenever the model is simulated, "automaticSeed()" returns a new random number and therefore the impure random number generator impureRandomInteger() starts always at another internal state (so basically this means that every simulation results in different random numbers). In order to guarantee that the impure random number is initialized before used (initializeImpureRandrom() is called before the first call of impureRandomInteger()), the construction with the "id" is used.

In the model "ModelWithRandom" a "pure" random number generator (it is pure because the state is explicit in the interface) is used. This random number is initialized with "globalSeed.randomInteger()" and therefore gives always a new random sequence for every simulation run.

The essential question is whether the code of GlobalSeed is correct Modelica.

According to my understanding this is an application of section 4.5.1 Short Class Definition (Modelica 3.2 specification) that defines:

class IDENT1 = IDENT2 class_modification;

There is no restriction in the specification that states that "class" cannot be a function.


Migrated-From: https://trac.modelica.org/Modelica/ticket/1795

modelica-trac-importer commented 6 years ago

Comment by otter on 6 Oct 2015 11:37 UTC Sorry, the first sentence in "Short explanation" should read: Whenever the model is simulated, "automaticSeed()" returns a new number that is computed from the actual time and the process id and therefore ....

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 6 Oct 2015 12:01 UTC This idea with a short function (with modifiers depending on parameters) in an inner model is just a simpler version of the gravityAcceleration used in the world-object in Modelica.Mechanics.MultiBody.

In particular I agree that 4.5.1 Short class Definition also cover functions, and there are many functions defined with short class definitions.

The problem here seems to be a claim that functions with parameter-modifiers are allowed, unless the parameters are bound to an external function. I cannot see that restriction in the specification.

modelica-trac-importer commented 6 years ago

Comment by beutlich on 7 Oct 2015 12:52 UTC To gain a deterministic function call sequence the developers of Modelica_DeviceDrivers created dummy (Modelica) functions that take a dummy input argument, call the external function and return this dummy argument again as output. This dummy parameter is then passed to all functions (and also over the connections) and determines the execution order of the external functions. See Modelica_DeviceDrivers.Blocks.Packaging.SerialPackager.Internal.DummyFunctions

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 7 Oct 2015 13:26 UTC Replying to [comment:3 beutlich]:

To gain a deterministic function call sequence the developers of Modelica_DeviceDrivers created dummy (Modelica) functions that take a dummy input argument, call the external function and return this dummy argument again as output. This dummy parameter is then passed to all functions (and also over the connections) and determines the execution order of the external functions. See Modelica_DeviceDrivers.Blocks.Packaging.SerialPackager.Internal.DummyFunctions

I agree that it is necessary if you want to enforce a specific order between the calls and this order is something that the user cares about for the device drivers (if the protocol says 'integer' and then 'float' they better be in that order).

I would assume this is normally a local order, since you build the package to be sent to the device in one place.

However, for Modelica_Noise it was only a matter of calling one function before any other globally (thus using inner/outer), and requiring the connection between all noise-blocks would decrease usability of the library. [There are other ways of ensuring repeatability.]

Similarly Modelica_DeviceDrivers.Blocks.Examples.TestSerialPackager_SocketCAN does not define order between the different CAN-packages.

Note that neither variant will work well if you get algebraic loops, but I don't see any situations where you get loops for these two cases.

modelica-trac-importer commented 6 years ago

Modified by beutlich on 21 Oct 2015 10:23 UTC

modelica-trac-importer commented 6 years ago

Comment by otter on 11 Dec 2015 13:00 UTC Closed this ticket, since the Modelica_Noise library was changed, so that no short class definitions are used in an inner/outer model (so this ticket is no longer relevant)

modelica-trac-importer commented 6 years ago

Modified by beutlich on 11 Dec 2015 13:02 UTC