jump to navigation

How cute can modeling be ? November 18, 2013

Posted by Sandro Andrade in planetkde-sandroandrade, planetqt-sandroandrade.
trackback

Heya planet,

It’s been a long time since my last post (as usual :) – hopefully that’s going to change in next months). A lot of things have happened in QtModeling land tough. In case you haven’t read my previous ‘call for arms‘ and ‘XMI serialization and metamodel plugins‘ posts, QtModeling is intended to provide a complete and flexible infrastructure for software (meta)modeling, (automated) architecture design and analysis, model recovery, and whatever comes in mind when you think about software models. Although we are still far from have those features fully available, some interesting capabilities are quite functional.

MOF/UML Metamodel Implementation

The new refactored templates for automatic metamodel implementation make programmatic model manipulation easier by taking ownership of properties with ‘composite’ aggregation and automatically removing elements from all involved property lists when it’s deleted. While Qt properties features described in QTBUG-17301 are still being considered, QtModeling extends Qt property system by defining roles for aggregation, opposite association ends, redefined and subsetted properties, and derived and derived union constructors. Some UML functionalities defined as derived properties/operations still miss implementation but basic features involving class and components diagrams are already in place. XMI serialization, profiles and stereotypes definitions/applications, and imported elements/packages are also currently available.

When building QtModeling, the following Qt Add-ons modules will be available:

  • QtModeling: defines base classes for model elements (QModelingElement and QModelingObject) and QXmiWriter/QXmiReader classes for XMI serialization.
  • QtModelingWidgets: provides two new model classes (QModelingObjectModel and QModelingObjectPropertyModel) and two new view classes (QModelingObjectView and QModelingObjectPropertyEditor) for manipulating models and model element’s properties.
  • QtUml: implements the full UML 2.4.1 metamodel. It comprises 239 classes which are 91.83% automatically implemented by templates. The remaining code represents derived properties and are being implemented on demand.
  • QtMof: implements the full MOF (Meta Object Facility) 2.4.1 metamodel. It comprises 51 classes also almost entirely implemented automatically.
  • QtDuSE: implements the DuSE language/metamodel (part of my PhD research) for automated software architecture design and analysis.
  • QtSADuSEProfile: defines an UML Profile for automated software architecture design of self-adaptive systems. This is required by SADuSE – a specific DuSE design space instance devoted to self-adaptive systems design.
  • Qt metamodel plugins: bind the previous model modules as Qt plugins used during XMI serialization.

DuSE-MT

DuSE-MT is a software modeling framework built on top of QtModeling which provide underlying mechanisms for defining new modeling languages (metamodels), creating models described in available languages (currently UML, MOF, and DuSE), manipulate models via JavaScript, and basic constructs for UML diagrams.

DuSE-MT

DuSE-MT defines a plugin-based architecture (shamelessly :) inspired by Qt Creator’s one), which supports not only Qt metamodel plugins but also extensions implementing new DuSE-MT functionalities such as concrete syntax handling, architecture recovery, automated architecture design, and so on. One of the good things of being a professor is to have students eager to graduate :) and willing to do their final projects in some Qt/KDE related project. Let’s see what happens …

DuSE-MT Plugins

Model Scripting

DuSE-MT’s JavaScript Console allows for defining scripts which might, for example, verify well-formedness rules and/or extend/change the currently opened model. For instance, if you know in advance you are going to use Java to implement the currently modeled system, you might use the following script to verify if any multiple inheritance was found in your model:

DuSE-MT JavaScript Console

While a full OCL parser isn’t already available, such kind of scripts can be really useful (actually it’s even more expressive than OCL since it’s not limited to read-only operations).

QML for UML Concrete Syntax

It’s really amazing how QML seems to be born to make certain things real without much pain :) Even in such highly dynamic cases with many requirements for integrating with C++ objects, QML property binding and some new defined QML items can rapidly gives you some nifty diagrams:

DuSE-MT UML Concrete Syntax

Wondering how much QML code was required to do that ? Here it is:

import QtQuick 2.0

UmlElement {
    UmlSlot {
        id: nameSlot
        anchors.top: parent.top
        Text {
            id: label
            text: element.name
            anchors.centerIn: parent
        }
    }
    UmlSlot {
        id: attributeSlot
        anchors { top: nameSlot.bottom; topMargin: -1 }
        height: (parent.height - nameSlot.height)/2
        ListView {
            model: element.ownedAttributes
            anchors { fill: parent; margins: 4 }
            delegate: Text {
                text: visibility(modelData.visibility) + modelData.name + ": " + (modelData.type ? modelData.type.name:"<no type>")
            }
        }
    }
    UmlSlot {
        anchors { top: attributeSlot.bottom; topMargin: -1; bottom: parent.bottom }
        ListView {
            model: element.ownedOperations
            anchors { fill: parent; margins: 4 }
            delegate: Text {
                text: visibility(modelData.visibility) + modelData.name
            }
        }
    }
    function visibility(visibilityEnum)
    {
        switch (visibilityEnum) {
        case 0: return " "
        case 1: return "+"
        case 2: return "-"
        case 3: return "#"
        case 4: return "~"
        }
    }
}

… and for UML associations:

import QtQuick 2.0
import QtModeling.Uml 1.0
import "util.js" as Util

Relationship {
    name: element.name
    relationshipType: "association"
    source: Util.findQuickItem(parent, element.memberEnds[0].class_.name)
    target: Util.findQuickItem(parent, element.memberEnds[0].type.name)
    sourceAggregation: aggregation(element.memberEnds[0].aggregation);
    targetAggregation: aggregation(element.memberEnds[1].aggregation);
    sourceMultiplicity: element.memberEnds[0].lowerValue.value + ".." + element.memberEnds[0].upperValue.value
    targetMultiplicity: element.memberEnds[1].lowerValue.value + ".." + element.memberEnds[1].upperValue.value
    function aggregation(aggregationEnum)
    {
        switch (aggregationEnum) {
        case 0: return "none"
        case 1: return "shared"
        case 2: return "composite"
        }
    }
}

… where Relationship is a new QML item we implemented based on QPainter API (I still need to learn how to use the new SG API). With such things done, UML concrete syntax implementation becomes the simple creation of QML files with names matching the corresponding UML metamodel element (UmlNode, UmlState, and so on).

QtOptimization

Supporting automated architecture design involves, among other things, the use of some search-based approach to find out several candidate architectures and then choose one that satisfies some specific quality attribute criteria. Elitist population-based algorithms have been successfully applied in such scenario because of their improved performance and fast convergence. If you’ve already played before with JMetal or some other framework for multi-objective optimization, that’s exactly what QtOptimization is intended to be. Currently, only NSGA-II (Nondominated Sorting Genetic Algorithm) is implemented (QNsga2 class), in conjunction with classes for bitwise mutation (QBitwiseMutationOperator), crossover (QCrossoverOperator), polynomial mutation (QPolynomialMutationOperator), simulated binary crossover (QSbxCrossoverOperator), and tournament selection (QTournamentSelectionOperator) operators.

Here is a brief description on how to use QtOptimization for a single-variable/two-objective optimization problem:

// Define objective function 1
class MyObjectiveFunction1 : public QObjectiveFunction
{
public:
    explicit MyObjectiveFunction1(QtOptimization::OptimizationGoal optimizationGoal = QtOptimization::OptimizationMinimizes) :
        QObjectiveFunction(optimizationGoal) {}
    virtual qreal evaluateOnIndividual(const QIndividual *individual) const
    {
        qreal x = individual->realVariableValue(0);
        return x*x;
    }
};

// Define objective function 2
class MyObjectiveFunction2 : public QObjectiveFunction
{
public:
    explicit MyObjectiveFunction2(QtOptimization::OptimizationGoal optimizationGoal = QtOptimization::OptimizationMinimizes) :
        QObjectiveFunction(optimizationGoal) {}
    virtual qreal evaluateOnIndividual(const QIndividual *individual) const
    {
        qreal x = individual->realVariableValue(0);
        return (x-2)*(x-2);
    }
};

QNsga2 nsga2;
MyObjectiveFunction1 *f1 = new MyObjectiveFunction1;
f1->setOptimizationGoal(QtOptimization::OptimizationMinimizes);
MyObjectiveFunction2 *f2 = new MyObjectiveFunction2;
f2->setOptimizationGoal(QtOptimization::OptimizationMinimizes);
nsga2.setObjectiveFunctions(QList<QObjectiveFunction *>() << f1 << f2);

nsga2.setSelectionOperator(new QTournamentSelectionOperator);
nsga2.setCrossoverOperator(new QSbxCrossoverOperator(0.9, 5.0));
nsga2.setMutationOperator(new QPolynomialMutationOperator(0.5, 10.0));
nsga2.createRandomPopulation(48);

// Improve population by 250 generations
for (int i = 0; i < 250; ++i) {
    nsga2.appendNewPopulation();
    nsga2.reducePopulation(48);
}

We’re currently implementing some quality indicators for Pareto-fronts and finish integration of such features in DuSE-MT in order to support better automated architecture design and analysis.

So, interesting stuff coming … I’d really love to see those things effectively integrated in QtCreator, KDevelop, and Umbrello. If you are willing to join the effort, fell free to try it from gitorious and don’t hesitate to contact me if you face any trouble.

See you,

 

About these ads

Comments»

1. jstaniek - November 18, 2013

My favourite topic “advanced use of QML” dept. Congratulations. Planning something related for Predicate (http://community.kde.org/Predicate) to replace SQL/DML/whatever with something on top of QML.

Sandro Andrade - November 20, 2013

Thanks jstaniek. I’m curious where in Predicate SDL is being used … How does such graphics stuff relate with database features ?

jstaniek - November 20, 2013

Possible use is in object-relational mapping. Having that, object modeling can be used instead of just ERD modeling.

Sandro Andrade - November 20, 2013

I see. I still need to implement some code generation features in QtModeling. It seems Grantlee doesn’t work with Qt5 yet :( Would be great to have some automatic schema generation from QtModeling. Maybe in the future :)

2. Manuel - November 18, 2013

Does your NSGA-II implementation use an external Pareto archive where you store all nondominated points found? It is well-known that the NSGA-II population can deteriorate in terms of Pareto optimality. If you want a bounded size (external) archive, you need to use a Pareto-compliant archiver: http://iridia.ulb.ac.be/IridiaTrSeries/IridiaTr2011-001.pdf

Sandro Andrade - November 20, 2013

Hi Manuel, thanks for the nice reference. No external Pareto archive in our implementation, actually I wasn’t even aware of such issue :) I’ll take a look at you paper, thanks …

3. Michel - November 28, 2013

Hi. I just compiled your AMZING module. Now I’m trying to read a MagicDraw file which contains only the state machine that can be seen in the Qt state machine framework documentation.
XmiReader parses the file but at some point I have a segfault in QXmiReader::createInstance because metamodelPlugin = d->metaModelPlugins[namespaceUri].first is equal to 0 so metamodelPlugin->createModelingElement(…) is illegal.
I can give the simple mdxml file for investigation. My goal here is to be able to generate a CPP file for the state machine.

Sandro Andrade - November 28, 2013

Hi, XMI serialization still need some polishment. I’d be grateful if you send the xmi file to sandroandrade at kde dot org. Note that code generation is currently done by using the Perl Template Toolkit and only for classes and profiles. Code generation directly from DuSE-MT is expected in the future, probably when Grantlee gets working with Qt5.

Thanks,


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: