Metalevels & Meta-metalevels

It seems like a tongue twister, and sometimes it is. Modeling and metamodeling is always a topic subject to high probability of misinterpretation. At the end, the concepts involved has subtle differences, but talking about then in different levels depending on the properties we want to stress.

My friend Peter Bell posted some time ago, a nice introductory article to models, metamodels and meta-metamodels.

If you have some basic background on databases, the examples Peter provides, will be useful to understand it all.

On the contrary, I usually preffer to explain it starting from the top and then going downto the hill. But I have to recognize than the reverse (as explained by Peter) is probably easy to follow for newcomers.

Now my version:

Take the following concepts: entity, attribute and relation. These are more than enough to create your basic meta-meta-model. With this primitive concepts you can built everything from scratch in every model!

  • OMG / MOF call this level M3.
  • When instantiating these M3 concepts, you can build M2 models and create meta-models for UML class diagrams, or state-machines. For example, UML class can be described as an entity with an attribute called Name, etc.
  • Instantiating M2, it allows you to create M1 models: tipically your business problem to deal with invoices (class Invoice) and customers (class Customer) and its corresponding association relationships.
  • Finally, when instantiating M1 models, you are finally creating living objects in an M0 world (let’s call it: The Reality). For example, customer=ACME and invoice=INV0003 are living objects at your aplication run-time.

Funny and weird, isn’t it. It’s like building aztec pyramids but with a top-down approach.

This layered approach to modeling based in abstraction and instanciation are crucial to undestand MOF, or any meta-modeling tool you ever use.

  • M3 (meta-meta-models) used to be hard-wired in metamodeling tools like MetaEdit, EMT, or MS DSL Tools/Corona.
  • M2 defines the rules for modeling (meta-modeling). A typical metamodel is the UML metamodel hard-wired in each UML tool you use. If your are changing an M1 model, you are creating a new language, in a literal sense. Sample the UML class concept.
  • M1 are each of the instances or models you create with tools like UML. Sample: a class named Customer.
  • An M0 sample would be the object ACME persisted as a row in a table and representing a customer in runtime in one particular software, for example.

Frequently people ask: why we stop at M3? It’s is not possible to have M4? An upper model to M3?

Well, the easy answer to this is No.

However the long response is: Can you find a more simple primitive concepts of entity, attribute & relation in a more abstract way and still be capable to derive/express the same concepts? If this is possible and convenient for your domain, then you just have invented your M4 model.

At the end, you start defining some primitive concepts like axioms: they can not be simplified or divided in simpler parts and ones axioms can not deriver others.

Note that you can use as many levels as needed, but you need a root level containing the axioms to start from and a M0 to set an arbitrary reference for the reality. To my preferences, I would have started to name it in the reverse order, M0 for the axioms, and M3 for reality.

The core metamodeling concepts in MOF, EMF, Meta-Edit and MS models are basically the same if you take a look: entities or core-classes, attributes or properties and relations.

From these primitives, it is easy and convenient to build any syntactic construction needed for the lower levels.

On the contrary, how to incorporate the emerging semantics in each new level is still a topic for strong discussion. But this is another interesting open topic for another post…

Long life to meta-meta-modeling!

8 comments.

  1. Interestingly “Services” in SOA do no have an M0 equivalent.

    I would also argue that:

    >> Take the following concepts: entity, attribute and
    >> relation. These are more than enough to create your basic
    >> meta-meta-model.

    is leading to anemic metamodels (see my article here: http://www.infoq.com/articles/mop) and anemic metamodels are not as useful as the cogent kind.

  2. Hi Jean-Jacques:
    I just fixed the URL to point to your article about MOP.

    To my understanding, as M0 represents the reality level, also SOA has an M0 layer. We could make this layer emerge if needed. In SOA, services are modeled in an M1 layer, that’s true. The M0 level for SOA is the running system containing the traces of real execution of services. Such traces could contain the service already executed (or in execution), the values of the parameters/messages already passed, timestamps, IP of the machine executing the service, etc.

    Business Activity Monitoring products (BAM), for example, work with these assets tracking these executions and triggering new actions to fire Business Alerts.

    On the other hand, instead of referring to pure structural models, as anemic (that sounds to me a bit pejorative), I prefer to call it just declarative models or declarative DSLs.
    Declarative DSLs like SQL, OCL, HTML, or Prolog have one nice virtue: they focus on describing “the what” and avoid any details about “the how”.

    This virtue, to be purely declarative, is exactly what allows a runtime engine to apply optimizations to an SQL query, for example, or to optimize a rendering in HTML.

    Of course, your definition of Cogent DSL can help to transform a model into another level of refinement. But to me, this rings a bell in my mind and looks to me quite near to an imperative language approach (an abstract one, but an imperative language at the end, like Java, Pascal or Javascript able to execute algorithms with a well defined execution rules).

    When generating declarative conceptual models, I prefer to isolate the transformations, from the input and output model/DSLs. And maintain the models pure (or anemic, if you prefer).
    Again, when describing the transformation, it can be expressed using a declarative formalism or a imperative one (anemic or cogent in your terminology, if I understood it well).

    On the other hand, I agree with you, that if you are going to capture an algorithm, a workflow, a process, etc. where the execution order and steps are the specification itself (as Service requires), then you will need a predefined imperative executions semantics when modeling, that also has to be preserved till reaching the runtime layer.

    Thanks JJ for sharing your impressions and generating debate. 🙂

  3. Pedro:

    >> The M0 level for SOA is the running system containing the traces
    With all due respect, that does not fit your definition of M1/M0. At best, I would say that in SOA M1 could be the contract level and M0 the service implementation, but that’s not fitting very well the M levels of MDA.

    Personally, my conclusion is that MDA was designed with OO in mind without looking any further. Hence MDA is flawed. I can see how M3/M2/M1 fit well. As soon as you are stepping into the runtime, you have to be careful on how you articulate the relationship between the model and the execution.

    Our industry is so conservative that we never question anything even as new evidence show that ideas that were thought to be “universal” simply cannot account for modern architecture concepts.

    >> anemic
    this is a reference to DDD, I use it in the same sense.

    >>the what” and avoid any details about “the how”
    again, this is not the distinction, it is rather a question of anemic vs behavior or static vs dynamic. The dynamicity of the model cannot be escaped. It amounts to saying that Turing was wrong all along. Building systems abstracted from Turing is, IMHO, a huge, historical mistake for the MDE movement.

    >>able to execute algorithms with a well defined execution rules
    This is actually not what I describe in MOP. You seem to not see the difference between the lifecycle of the model elements (implied and constant in an OO system) and algorithms. Lots of people actually burry the lifecycle behind patterns and treat it as code. Again this is a huge and historical mistake for MDA, which is directly coming from the anchorage in OO. As soon as MDA/MDE will understand that OO is not the foundation of its architecture but OO should be built on top of an MDA/MDE, then we will see MDA and MDE bloom like we have seen nothing before.

    >> imperative executions semantics
    again, this has nothing to do with imperative vs declarative. It has to do with dymanic vs static. The lifecycle of the model elements cannot be ignored or buried in the code generator or code interpretor. It has to surface at the same level as the model itself.

    JJ

  4. Probably, I have not fully understood your statement about MOP and miss some parts. Particularly, the “execution element” is still diffuse to me. And hence, I interpreted it initially as a declarative versus imperative issue.

    Your claim about implicit life-cycles in OO and the necessity to make them explicit seems sensible to me in some scenarios.

    On the other hand, you are also asserting that OO is not the correct foundation for doing MDE because something else is missing.
    So, in your opinion, what are the missing parts we need to fix it?

  5. Hi Pedro.

    I am glad ABSE conforms to your specification!

    ABSE’s meta-metamodel, the Atom, does not rely on a DSL. Instead, it uses a general-purpose language and a library/framework. I think we can compare this to core classes you mention. Then, each Atom can have properties and relations. What is missing on your analysis from ABSE is behavior: An Atom can act, run, and behave differently according to its parameters, relations, or global model settings. For instance, this makes it easy to create software product families.

    Also, I can consider the four meta-levels as matching:

    M3 : Atom, ABSE’s meta-metamodel
    M2 : Atom Templates, created following the rules of Atom
    M1 : Atom Instances, created by instantiating Atom Templates
    M0 : Generated Artifacts, created by executing Atom Instances

    In conclusion, you made a very good overall analysis of the current MDSD methodologies!

  6. Thanks for your comments Rui:
    Do you have a link where to review a detailed description of the formalism you are using in ABSE? I am interested in taking a look on it.

  7. “Do you have a link where to review a detailed description of the formalism you are using in ABSE?”

    Not yet. However I will release a white paper with ABSE’s specification/formalisms. I am determined to have a working proof-of-concept (AtomWeaver, the ABSE IDE) at the same time this whitepaper is released.

    Time is a (very) limited resource!

  8. Pedro:

    “execution element” may not be the best name. The basic idea behind MOP is that OO methods are an example of “execution element” in the OO metamodel. Take a metamodel, you can “add” execution elements anywhere you want (where it makes sense of course). The next question what do you write in these execution elements? Well, you have the usual control structures of course, the basic data types and then, this is where the lifecycle of metamodel elements come to play. In OO, an object instance has a lifecycle, created, deleted, garbage collected,… Basically you can come up with any lifecycle that makes sense to you.

    MOP provides a blueprint to create cogent polyadic programming languages. DSLs and general purpose languages are very particular cases of these programming languages and frankly far less useful. MOP bridges GPLs and DSLs.

    See, the problem with OO is that people need the polyadism. 15 years ago it was not clear. Add SOA, the Web, BI, BAM, … and you start seeing annotations everywhere, in essence OO is becoming polyadic. Actually, OO is polyadic .Net, Java -all- have added polyadism, unfortunately without truly understanding the implications of polyadism. The last problem to solve is “how do you express behavior in a polyadic world?”. You guessed it, with OO you are limited to the Object lifecycle, -declarative- annotations have no way to express behavior correctly. You can say “start” or “stop” this service.

    So turn the OO model around like a sleeve and look at its structure (metamodel) and create a cogent polyadic meta-metamodel (that’s what I call MAF -MetaArchitecture Framework). Voila. OO is just a cogent monadic language, it’s good, it’s great, we all have done incredible things with it but add polyadism… and let’s talk again.

    JJ-

Post a comment.