clifo: a textual editor for ontoumlprime with clif constraints · pdf fileclifo: a textual...

89
Universidade Federal do Espírito Santo Ramon Sobrinho Goularte CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, Brasil Março de 2016

Upload: hoangcong

Post on 30-Jan-2018

232 views

Category:

Documents


8 download

TRANSCRIPT

Page 1: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Universidade Federal do Espírito Santo

Ramon Sobrinho Goularte

CLIFO: A Textual Editor forOntoUMLPrime

with CLIF constraints

Vitória - ES, Brasil

Março de 2016

Page 2: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 3: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Resumo

Nesta monografia, apresentamos um editor textual para criar modelos conceituais em CLIFO, uma linguagem desenvolvida para este fim. CLIFO usa o meta-modelo de OntoUMLPrime, que é feito no Eclipse Modeling Framework e é compatível com UFO-A (Unified Foundational Ontology). OntoUMLPrime é baseado em OntoUML, uma linguagem cognitivamente bem-fundamentada. CLIFO tem duas sub-linguagens: uma para modelar em OntoUMLPrime, que foca em legibilidade do texto; a outra é um dialeto de CLIF (Common Logic Interchange Format), usado para enriquecer os modelos com restrições lógicas arbitrárias. A importância dessas restrições em modelagem conceitual é discutida aqui. Também revisamos o meta-modelo de OntoUMLPrime e o apresentamos aqui, antes de apresentarmos CLIFO, a nossa linguagem textual. Por fim, apresentamos o editor, que foi implementado como um plug-in do Eclipse, junto com sua arquitetura e os recursos que usamos para melhorar sua usabilidade. Nosso objetivo é prover um editor textual que é apropriado como uma alternativa à modelagem diagramática, e que foca principalmente na precisão dos modelos.

Page 4: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Abstract

In this work, we build a textual editor for creating conceptual models in CLIFO, a language designed for this purpose. CLIFO uses the OntoUMLPrime meta-model, which is built in the Eclipse Modeling Framework and conforms to UFO-A (Unified Foundational Ontology). OntoUMLPrime is based in a cognitively well-founded modeling language, named OntoUML. CLIFO has two sublanguages: the first is for modeling in OntoUMLPrime and aims to have an emphasized readability; the second is a dialect of CLIF (Common Logic Interchange Format), used to enrich the models with arbitrary logical constraints. The importance of arbitrary constraints in conceptual modeling is discussed in this work. We also revise the OntoUMLPrime metamodel and present it here, then we present CLIFO, our textual language. Finally, we present the editor, that was implemented as an Eclipse Plug-in, along with its architecture and the resources we used to improve its usability. Our goal is to provide a textual editor that is suitable as an alternative to diagrammatic modeling, and that focus in the accuracy of the models first.

Page 5: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

1. Introduction

Information is everywhere. Since the beginning of human history until the present days, we always had to create, modify, read, transmit and deal with information in many ways. When the information is too complex for us to deal with it, we create tools that assist us in this task.

There are tools that help us create information, tools that generate it for us, tools that destroy it, tools that keep it safe, tools that change it, tools that try to transmit it unchanged. Some tools are intended to help us understanding the information. The process of observing complex information and creating a simplified version that represents it in a more understandable way is, sometimes, what we call "modeling".

A model represents an abstraction of the reality we want to describe. This abstraction is intended to identify, in the complex reality, what we consider important. This important information is then simplified and written in this concrete artifact, that's the model.

There are many tools that assist us in the task of modeling. In this work, we intend to create one of such tools: a textual editor for conceptual modeling.

1.1 Background

According to Guizzardi (2005, p. XI), "A model is an abstraction of reality according to a certain conceptualization. Once represented as a concrete artifact, a model can support communication, learning and analysis about relevant aspects of the underlying domain. […] As a concrete artifact, a represented model must be expressed in some suitable language".

One question that naturally comes is: what could be a "suitable language"? Or, perhaps: what should the language be "suitable" for? Or: what do we intend to achieve when we design a language in a particular way?

Traditionally, modelers use graphic languages (such as a class diagram) to create conceptual models. A significant advantage of this approach is that a visual model is easier for non-modelers to understand. Textual languages, on the other hand, are widely used to describe computer programs and algorithms. Most of the programming languages are textual because, for experts, text-based tools are usually more practical.

Textual editors require that users deal mostly with the keyboard and that they focus mostly in one area of the editor: the text field that contains the program. On the other hand, many graphic editors, specially diagrammatic ones, require that the users deal with the mouse and the keyboard, and that they focus in many distinct elements of the editor at the same time.

For example, to insert and edit elements in a model, a user might be required to drag an element of an area to another, then select a text field and type something, then select an option in a drop-down, then click a button in a dialog, etc. Since the users have to focus in many different elements in the screen, they tend to take more time to think, and perform the task slower than a similar task in the continuous flow of typing in a textual editor.

When we are thinking of modeling, the ability of a diagram to facilitate the communication seems essential. But many users may also want the flexibility and convenience of typing in a

Page 6: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

textual editor. This leads to the question: should we create models with graphic tools, textual editors or try to use some sort of combination of both?

1.2 Motivation and goals

A lot of information (mostly intended, but sometimes, also unintended) is transmitted implicitly with the visual aspect of the diagrams. For example, a small distance between two classes in a diagram may implicitly transmit the idea that these classes are closely related. This can be seen as a huge advantage, because it simplifies the task of explaining the model.

However, it might be the case that, when a modeler begins creating a model, he may not yet be sure of what is the essence of the model – the elements in the model, not the part that is implicit or represented by visual aspects of the diagram. Without a "macro" understanding of the model, the modeler, sometimes, tends to insert this implicit visual information little by little, in an improper way. For example, a modeler may choose to put a class in the corner of the diagram and start creating other classes that are connected to it. Sometimes, this class would be better at the center of the diagram, and the modeler only realizes this when the model already has a lot of classes and long connections all over the place.

Ideally, the main elements of the model should be defined first. Then the modeler would start worrying about how he will use the visual aspects of the diagram to communicate with others. Sometimes, when the modeler works in the visual aspects of the diagram (such as positioning the classes properly) before the main idea of the model is clear, it's possible that most of this work will have to be redone as the model changes. In the cases where the model changes a lot in this process, the task of positioning stuff may become unnecessarily repetitive. Unfortunately, in many of the graphical tools, the modeler has no way to know beforehand how to avoid the creation of the models to end up being done this way.

We believe that a textual editor can solve this problem. If the modelers create models without having to worry about diagrams all the time, they can focus in the validity of their models. A correct model is more important than a model that is easy to understand.

Of course, understanding the models is very important too, and a textual editor is limited with regard to this. For this reason, we believe that a good approach to create good models is:

create the model textually, worrying about the accuracy of its main elements first

enrich the model with the necessary constraints (further improving its accuracy)

ensure that everything is correct - tools like the Alloy Analyzer (JACKSON, 2012) may help

use a tool to transform the model into a visual diagram

with a good "macro" understanding of the model, start worrying specifically about the visual aspects that will facilitate communication, for example, the color, size and position of the classes and the paths of connections between classes

In the current work, we are going to build a textual editor using the OntoUMLPrime meta-model (ALMEIDA, 2013), that is derived from a diagrammatic modeling language called OntoUML (GUIZZARDI, 2005). We are not going to create a tool to transform the textual models into diagrammatic ones, but we leave it as a suggestion for future works.

Another goal we intend to achieve is to offer, in this editor, the possibility to enrich these models

Page 7: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

with constraints. We discuss more about this subject in chapter 3.

Finally, we also would like to have in the models a textual syntax that is somewhat self-explaining. We believe this can help non-experts to understand the model when there is no diagram for this. Even so, creating a visual diagram from it is still recommended, of course.

1.3 Approach and structure

To build the editor, we use the Eclipse Modeling Framework (EMF) . The editor compiles as an Eclipse plugin, so it opens the files in an Eclipse Application. Since Eclipse runs on top of the Java Runtime Environment , the editor is platform-independent. Also, it's easier to integrate with other applications from NEMO that run as Java too, such as OLED .

The meta-model for the editor is built with Ecore, which is part of EMF. We use a combination of Xtend and OCL (ISO/IEC 19507:2012) to specify how the validation of the models is done. This validation allows the editor to show errors when the model is invalid for some reason.

The grammar of the editor is built with Xtext . In the approach we are using, the validation is implemented as a live-validation, which means the errors are displayed immediately as the user types something invalid.

In the Chapter 2, we make a brief review of the OntoUML key concepts, which are the basis for the OntoUMLPrime meta-model that we use in the editor. In the Chapter 3, we discuss about the importance of the ability to specify arbitrary constraints in an OntoUML model. Chapter 4 presents the revised version of the OntoUMLPrime meta-model, whose elements correspond to the concepts in Chapter 2. Chapter 5 presents the informative specification of the language we use in the editor, including the sublanguages for the model and for the constraints, respectively. Chapter 6 presents the conclusions and suggests possible future works.

Page 8: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

2. A brief review of the OntoUML key concepts

Guizzardi's thesis (2005) presents an ontological foundation for the most relevant concepts in conceptual modeling. This ontology is called UFO-A, and is the part of UFO (Unified Foundational Ontology) that deals with "endurant universals". This ontology is concretized in a modeling language called OntoUML. In this chapter we will briefly review some key concepts of UFO-A.

First, in order to explain what are the "endurant universals" that are defined by this ontology, we have to distinguish the concept of "universals" from the concept of "individuals". As Guizzardi (2005, p. 95) says: "universals and individuals […] are represented in conceptual modeling by the constructs of Types (classes, classifiers) and their instances, respectively".

So, "Human" and "Man" are examples of universals, and "Abraham" is an example of an individual that's instance of both universals. A universal is said to "specialize" or "be a child of" another universal when all instances of the first are always instances of the second, too. In the previous example, "Man" specializes "Human", meaning that all individuals that are a "Man" are also a "Human".

The term "endurant" refer to entities that "are in time", in the sense that, in different points in time (or circumstances), they can change their properties while remaining the same entity (they preserve their identity). We can refer to the same endurant in different circumstances because we know it's the same individual.

For example, when we say that "Abram" became "Abraham", we know that we are talking about one single individual that has a property (the name) with two different values in different times. So, we say that the individual changed because its property changed, but we know he is the same individual, because his identity does not change.

The concept of "endurant" differs from the concept of "perdurant". OntoUML does not deal with perdurants, so we are not going to worry about them in this work.

The "endurant universals" are classified in two types: "substantial universals" and "moment universals". Guizzardi (2005, p. 214) defines a moment as "an endurant that inheres in, and, therefore, is existentially dependent of, another endurant", and a substantial as "[an endurant] that cannot inhere in other individuals".

In the next section, we are going to review the types of substantial universals.

2.1 Substantial Universals

UFO-A classifies substantial universals in two distinct categories: "sortal universals" and "mixin universals". It also classifies them with regard to "rigidity".

Sortal universals "supply both a principle of application and a principle of identity" to their instances, while non-sortals don't supply a principle of identity (GUIZZARDI, 2005, p. 98).

With a principle of application, one can judge if an individual is instance of the given type. With a principle of identity, one can judge if two individuals of the given type are the same individual.

Page 9: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

The "mixin universals" are generic abstract types representing properties that are common to many different sorts. As found in Guizzardi's thesis (2005, p. 105), "they cover many concepts with different principles of identity". Mixin universals are always abstract because, since they "do not denote sortals, […] [they] cannot have direct instances".

Regarding "rigidity", Guizzardi (2005, p. 101) defines that "[a] rigid universal is one that applies to its instances necessarily, i.e., in every possible world". When a universal is non-rigid it's considered anti-rigid if "it does not apply necessarily to all its instances".

This means that if an individual is an instance of an anti-rigid type, one can always imagine another circumstance in which the same individual wouldn't be instance of this type. For example, "Adult" is an anti-rigid type. If "Abraham" is an adult in a given circumstance, we can imagine a different circumstance in which he is a child, not an adult.

If an individual is an instance of a rigid type, there is no way this same individual can exist and not be an instance of this type. For example, let's consider "Human" as a rigid type and "Abraham" as a "Human". Then, in any circumstance, any individual that is not human is surely not "Abraham", but a different entity.

In UFO-A, "sortal universals" are partitioned into two types: "rigid sortal universals" and "anti-rigid sortal universals". The "mixin universals" are divided into types "rigid mixin universal" and "non-rigid mixin universal"; the latter is further divided into types "semi-rigid mixin universal" and "anti-rigid mixin universal". We'll talk about them in the subsections that follow.

2.1.1 Rigid Sortals

A "substance sortal universal" is the ultimate sortal that provides an identity principle to its instances. As a consequence, all types that specialize a substance sortal inherit this principle. Also, in a given conceptualization of a domain, "[any] individual represented in a conceptual model of the domain must instantiate exactly one [universal] representing an ultimate Substance Sortal" (GUIZZARDI, 2005, p. 100). Substance sortal universals are rigid.

UFO-A defines three types of substance sortal: kind, quantity and collective.

A quantity is a type used to describe an amount of matter. As such, a quantity can always be partitioned in smaller portions of the same type. Quantities "lack both individuation and counting principles" (GUIZZARDI, 2005, p. 174). Therefore, a quantity cannot be counted unless it is "contained" in an individual that's instance of a countable type.

A collective is a type used to describe a group of individuals. As Guizzardi (2005) says, collectives "have parts that are not of the same [type] (e.g., a tree is not forest) and they are not infinitely divisible" (p. 180). He also states that "differently from quantities, collectives do not necessarily obey an extensional principle of identity", so a collective may or may not be extensional, depending on the conceptualization. When a collective is extensional, "the addition or subtraction of a member renders a different collective" (p. 183).

A kind is a type that provides a counting principle to its instances. Every individual that's instance of a kind is counted as "one" of that type.

A subkind is a rigid sortal type that inherits the identity principle from another rigid sortal type. Subkinds are often grouped in orthogonal partitions of the parent type. Each of these partitions is a disjoint and covering generalization set. However, as Guizzardi (2005, p. 110) says, "subkinds

Page 10: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

do not have to be necessarily defined in a partition".

2.1.2 Anti-rigid Sortals

The anti-rigid sortal types "possibly apply to an individual only during a certain [period] of its existence" (GUIZZARDI, 2005, p. 102). UFO-A distinguishes two types: phases and roles.

A phase is a type that represents "possible stages in the history of a [sortal]". Phases can only be in a disjoint and covering generalization set with other phases, since types "representing phases constitute a partition of the [sortal] they specialize" (GUIZZARDI, 2005, p. 103). This generalization set is usually associated with some property of the specialized type, as said: "[the specialization condition of] a phase […] depends solely on intrinsic properties" (p. 104).

A role is a type that is externally-dependent on a relation, as said: "[the specialization condition of] a role [...] depends on extrinsic (relational) properties". It's also said that "an entity plays a role in a certain context, demarcated by its relation with other entities" (GUIZZARDI, 2005, p. 104). Therefore, we note that a rigid type is only specialized into a role when a relation is created.

2.1.3 Mixin Universals

UFO-A defines rolemixin types, which "are anti-rigid and represent […] [an abstraction] of common contingent properties of multiple disjoint roles" (GUIZZARDI, 2005, p. 112). They can only be distinguished into anti-rigid sorts (we'll talk about distinctions in chapter 5). The figure bellow from Guizzardi's thesis (2005, p. 111) exemplifies a case where a rolemixin should be used.

Figure 1 – Rolemixin pattern.

The semi-rigid mixin types are types that "represent properties that are essential to some of its instances and accidental to others" (GUIZZARDI, 2005, p. 113). They can be distinguished into both rigid and anti-rigid sorts.

A category is defined as "a rigid mixin that subsumes different [sorts]". A distinction of sorts from a category can only have rigid sorts. The figure below (GUIZZARDI, 2005, p. 113) exemplifies a distinction of a category into kinds.

Page 11: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Figure 2 – Distinction of sorts.

We use the word "sorts" in this work to denote types that form a specific type of partition (namely, a "distinction by sort") of a mixin universal. Two sorts of a certain distinction never have a common substance sortal identity provider.

2.2 Moment Universals and Relations

When talking about moment universals, Guizzardi (2005) explains that "[the] bearer of a moment x is the unique individual y such that x inheres in y". UFO-A defines three types of "moment universals": qualities, modes and relators.

Qualities and modes are called "intrinsic moment universals", because they always characterize one single universal. A characterization is a type of relation involving an endurant and its intrinsic property. The individual having a quality or mode is called the bearer of that property.

Guizzardi (2005, p. 222) states that "for several perceivable or conceivable moment universals there is an associated quality dimension in human cognition". He defines a quality universal as "an intrinsic moment universal that is associated with a quality structure" (p. 224).

A mode universal is defined as "an intrinsic moment [universal] which is not a quality". Modes "can bear other moments" and "are not directly related to quality structures" (GUIZZARDI, 2005, p. 237-238). However, since they are intrinsic moments, they have a bearer, just the like qualities.

A relator universal is a type that instantiates "individuals with the power of connecting entities". The relators mediate relata (or participants) of a material relation (GUIZZARDI, 2005, p. 236). These mediations (relations between relators and relata) specify the cardinalities in both ends. The types and the cardinalities of a material relation are completely derived from a relator. This is called a derivation relation (p. 331).

When a relation between universals is not a part-whole relation or a generalization, and is not derived from a relator, it is called a formal relation. According to UFO-A, they "hold between two or more entities directly without any further intervening individual" (GUIZZARDI, 2005, p. 236).

In this chapter, we have reviewed some of the basic concepts of UFO-A. Since this is just a brief review, we'll not discuss some concepts, such as part-whole relations, here. We'll talk about part-whole relations in chapter 4, though.

Page 12: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

3. Constraints in a OntoUML model

In this chapter, we'll discuss about the addition of arbitrary logical constraints in conceptual models, and also how we intend to implement it in this work.

In the section 3.1, we talk about the importance of allowing these constraints in a model. In the section 3.2, we present our approach for implementing this in our editor.

3.1 The need for constraints in modeling languages

Conceptual modeling is "the activity of formally describing some aspects of the physical and social world around us for purposes of understanding and communication" (MYLOPOULOS, 1992). Therefore, the purpose of a conceptual modeling language is to allow the modeler to accurately express what is intended to be modeled. The model as expressed has to be as close to the modeler's intention as possible. When there is a divergence between the expressed model and the intended meaning, communication problems happen.

For this very reason it is important to allow the modeler to accurately express what are valid and invalid instances of the model. These are called the constraints of the model – the elements in the model that are capable of constraining. Constraints distinguish, among all instances of the model, just the ones that are considered valid from the others, which are invalid.

Typically, most constraints of the models are already embedded in the semantics of the modeling language that’s used. However, if the modeling language doesn’t incorporate logic elements, it will usually not be expressive enough to allow any constraint to be defined.

According to Guerson, Almeida and Guizzardi (2011), "in complex domains, there are typically a number of domain constraints which cannot be directly expressed by the […] language, but which are of great importance for capturing as accurately as possible the modeler’s intended domain conceptualization".

Since OntoUML alone doesn’t incorporate logic elements in the language, it needs another language to allow the modeler to specify arbitrary constraints. Guerson, Almeida and Guizzardi (2011) have used OCL for this purpose. To exemplify this need, we'll use the following figure of an OntoUML model taken from their article (colors were added to improve readability).

Page 13: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Figure 3 - OntoUML model of a domain that requires custom constraints. Each color represents a different sort.

This is a traffic accident domain. This model may initially look like it's suitable for this domain. However, some valid instances of this model would represent situations that wouldn't make sense. For example: without constraints, a rear-end collision involving one single car would be considered valid.

In this example, four constraints were specified to eliminate invalid instances from this model.

Every rear-end collision must involve exactly two crashed vehicles.

The attribute fatalvictims is derived from the number of deceased victims in an accident.

Every traveler of a vehicle participating in an accident is a victim in that accident.

Every vehicle, in which there is a victim of an accident, is involved in that accident.

These constraints are out of the scope of OntoUML, because they are domain constraints (they only make sense in this particular model). The figure below (GERSON; ALMEIDA; GUIZZARDI, 2005) shows these constraints implemented in OCL.

In this work, we'll create a textual language that supports constraints in a conceptual model. We'll come back to the previous example later and model it in this language.

Page 14: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

3.2 Adopted approach for implementing a constraints language

Our goal is to create a textual editor that’s compatible with OntoUML and that allows the modeler to specify arbitrary constraints over the model. We chose to use a language that is conformant to OntoUMLPrime as the meta-model and to CLIF (ISO/IEC 24707:2007) as the constraints language. The advantage of CLIF over OCL is that the portion of CLIF we want to cover has a simpler grammar, and this avoids an additional complexity in creating the editor. Another advantage is that CLIF is still relevant beyond the UML community.

CLIF is a language for the CL (Common Logic) framework. The ISO/IEC standard (2007) for the framework states that CLIF "[is] logically comprehensive" and "[provides] for the expression of arbitrary first-order logical sentences". This capacity of specifying arbitrary logical constraints in a domain allows us to create a CLIF dialect to be used as a constraints language.

Since we are talking about a language that is bound to an external metamodel (OntoUMLPrime) and that conforms to an external specification (CLIF), we have to specify it as a CLIF dialect L with the following properties:

Dialect conformance: All constructs of L need to obey the syntax and semantics of CLIF.

Syntactical binding: L has to establish a syntactical binding between its own meta-classes and the meta-classes of OntoUMLPrime. Some constructs of L will need to allow direct references to the elements of the model in the constraints.

Conformance of semantics: L has to define syntactical validations for any constructs that may directly or indirectly reference the meta-classes of OntoUMLPrime. These validations will ensure these constructs conform to the semantics of OntoUMLPrime.

Definition of semantics: L has to define its own semantics, which need to be enough to identify instances of the model that violate the constraints. This definition is not in the editor, but in the specification of L. If someone implements a language that is bound to L or a tool that deals with instances of the models constrained by L's constraints, this tool or language will have to obey these semantics.

According to the CLIF specification in the ISO/IEC standard (2007, p. 23), CLIF contains "a syntax for classical first-order (FO) logic", uses "exclusively a prefix notational convention, and [LISP-like] S-expressions style syntax conventions", and uses "parentheses as lexical delimiters". Our dialect of CLIF will also follow this syntax, it's a part of the language we'll present in chapter 5.

Page 15: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

4. The OntoUMLPrime meta-model

OntoUML (GUIZZARDI, 2005) was designed to be conformant to UML – there is a recent meta-model for it that works as a UML profile (CARRARETTO, 2010). This is both an advantage and a disadvantage. When we are thinking of a textual language for OntoUML, it is a disadvantage, because the meta-model is too "polluted" with UML elements (ALMEIDA, 2013), and we are not interested in diagrammatic elements in a textual language.

We need a meta-model that is equivalent to OntoUML (conforms to UFO-A), but without UML. This is the goal of OntoUMLPrime (ALMEIDA, 2013). It redesigned the meta-model and the OCL constraints over it, to remove the UML elements and keep just the elements for the ontology.

OntoUMLPrime is built on top of Ecore (the meta-meta-model) and it now uses Xtend and OCL for the constraints on the meta-model (they are used to validate the models). This work has contributed with some changes in this meta-model and its constraints.

We are going to present a simplification of the revised meta-model for OntoUMLPrime and its constraints in this chapter. The complete code for this revised meta-model and the editor we built in this work can be currently found in the GitHub repository .

4.1 Packageable Elements and Containers

In OntoUMLPrime, a model can contain elements, called "Packageable Elements". A model can also contain packages, which can contain elements or other packages. Therefore, anything that can be placed in a model or package is classified as a packageable element.

Some elements have a name (and therefore, can be referenced in other elements by name), while others don’t.

4.2 Universals and Generalization Sets

One of the most important concepts is that of a universal. In OntoUMLPrime, it is correspondent to the notion of universals in OntoUML (GUIZZARDI, 2005). Universals are the classes in the model; they generate instances (called "individuals") in instances of the model.

In OntoUMLPrime, universals can be specialized by other universals. This happens when they participate in generalization sets. A specialization means that every instance of the specializing universal is also an instance of the specialized universal.

If the universal is abstract, it may not have instances directly. Instead, it can only have an instance if it is also instance of a subtype of this abstract universal.

The revised version of OntoUMLPrime now considers that a universal is abstract whenever it has any complete (or covering) generalization set specializing it (which means the universal cannot have instances directly, therefore, it is abstract). The exceptions are mixin universals, which are always abstract.

Page 16: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

For example, in the figure below (GUIZZARDI, 2005, p. 113), "Crate" is abstract because of the generalization set (which is covering, since it's a phase partition). The class "Seatable" is abstract because it's a mixin.

Figure 4 – Partition of abstract classes.

The generalization sets from OntoUMLPrime are always disjoint (no individual can be instance of two universals if they are in the same generalization set), but may or may not be complete (or covering). A complete generalization set means that any instance of the specialized universal is necessarily also an instance of one of the specializing universals.

4.3 Endurants and Characterizations

Since OntoUMLPrime only intends to cover the concepts in UFO-A, it only deals with endurant universals. OntoUMLPrime allows all endurants to be characterized by intrinsic moments (or aspects).

A characterization is a special type of binary directed relationship which involves a characterized endurant and a characterizing intrinsic moment (a quality or mode). The characterization also specifies the cardinality of the moment, i.e., the amount of values that can be held by that quality or mode. We'll show some examples when we talk about characterizations, in the next chapter.

The difference between qualities and modes is that a quality has an associated datatype for its values, while a mode doesn’t have a datatype. A mode can have other characterizations.

4.4 Datatypes

In OntoUMLPrime, datatypes (including primitive datatypes) are also specified in the models; they can be associated with many quality universals. Note that this is not the concept defined in UFO-A as a "quality structure", because "quality structures are always associated with a unique quality universal" (GUIZZARDI, 2005, p. 224), and vice-versa, as we can see in the UFO-A fragment in the figure (p. 236). However, this concept is related to the datatypes here. We can say that when a datatype is assigned in the model to a particular quality universal (which characterizes a specific endurant universal), a quality structure is implied from this association. The configuration of this quality structure reflects the configuration of the datatype.

Page 17: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Figure 5 - UFO-A fragment regarding qualities.

The revised version of OntoUMLPrime now allows three types of user-defined datatypes: enumerations, complex datatypes and abstract datatypes.

Complex datatypes contain many attributes, which are each associated to another datatype. For example, "ColorHSV" is a datatype that has 3 attributes (or dimensions) namely: hue, saturation and value. Each dimension is associated to a datatype (for example, "Real").

Note that UFO-A defines the concept of "quality domain". We can say that a complex datatype, when assigned to a particular quality universal, implies a "quality domain" (or a "quality dimension", if it has only one dimension) associated with both. For example, consider that an endurant universal "Apple" has the quality universal "Apple.Color", which instantiates colors of apples. If, in our conceptualization, we assign the complex datatype "ColorHSV" to it in the model, there will be an implied quality domain, say, "Apple.Color in ColorHSV", representing colors of apples measured in HSV.

Although we may want to specify the measurement we are using for a property, we may also want to adopt a more conceptual approach. For example, we may want to specify that "Apple.Color" is a "Color", without specifying if it is "ColorHSV" or "ColorRGB" or some other implementation of a color measurement structure. We may also want to be able to specify both measurements (saying that they implement the same abstract concept of "Color") and how they are convertible to each other. As Guizzardi (2005, p. 277) states, "[by] explicitly representing conceptual spaces and their constituent domains and dimensions, one can analyze the same object in different measurement structures. In particular, one can define transformations and projections between conceptual spaces that facilitate knowledge sharing and semantic interoperability".

For this reason, we are including, in OntoUMLPrime, a meta-class for abstract datatypes. They correspond to this notion of "conceptual spaces" in UFO-A. They allow to separate concepts from implementation, when regarding datatypes. For example, the complex datatypes "ColorRGB" and "ColorHSV" from the previous example would both specialize an abstract datatype "Color". Any user-defined datatype can specialize an abstract datatype if desired.

Page 18: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Again, note that, when we are talking about a "Color" datatype, it is different from the "Color" quality universal from the "Apple" endurant universal. The first is a generic abstract datatype that refers to colors in general. The second is a quality universal that instantiates colors of apples when the apples are created.

When we say that an apple "a" changes its color "a.color", the value of "a.color" (in a conceptual space) changes, causing a change in the measurement (in the quality structure of our conceptualization), which may change the representation of the value in the datatype we assigned in our conceptualization. However, if this datatype is abstract, the implied quality structure is not specified as a particular quality domain (or dimension), therefore, we don’t have a measurement with a representation of the value, although we know that it can be represented by a measurement (differently from modes).

All user-defined datatypes depend on the domain. A datatype can only specialize an abstract datatype if it also depends on the conceptualization of the modeler. There are, however, some datatypes that don’t ever depend on any domain or conceptualization. These are the unidimensional primitive datatypes. OntoUMLPrime recognizes four possible types for their value sets: one for logical values false and true, one for discrete numbers, one for continuous (real) numbers and one for symbolic, non-numeric data (a sequence of bits, or of a finite set of characters, with unlimited length).

OntoUMLPrime doesn’t impose a limit on the amount of primitive types specified in the model, so we could, in theory, define many types of primitive datatypes in a model. For example, one may want to have different discrete datatypes for cardinal, ordinal and distinctive (or nominal) natural numbers, and also integer numbers. Each datatype can be assumed to have its own set of values and operations that make sense (for example, multiplying ordinal or nominal numbers doesn’t make sense). We believe we could use this as an advantage and greatly improve the accuracy of the models, because this is closely related to the "associated quality dimension in human cognition" (GUIZZARDI, 2005, p. 222), when we are talking about a single dimension. For example, in the "ColorHSV" datatype, we could conceive "hue" and "saturation" as continuous dimensions (for real numbers), but that doesn’t say anything about the different "shape" we imagine for them. This isn't just our perception, they are indeed mathematically different – they are both continuous (implying ordered) and have a closed range of values (implying finite), but only "hue" is periodic, and that’s why we imagine an angular shape for this dimension and a delimited linear shape for the other.

We could discuss this subject in-depth, but this isn't the goal of this work. What is important to understand here is that the only restriction over primitive datatypes is that they are always unidimensional, purely mathematical and, therefore, independent of any domain or conceptualization.

The third type of user-defined datatype is enumeration. Enumerations are custom datatypes with a finite set of possible values. They always depend on the domain (since they are user-defined datatypes), but only sometimes they depend on the conceptualization. For example "DayOfWeek" doesn’t depend on the conceptualization, but a type "ColorGrayscale" can be enumerated in many different ways. Enumerations are also unidimensional, and we can classify them with different "shapes", but, again, discussing this subject isn't the goal of this work.

4.5 Sortals and Mixins

The notion of sortals and mixins (substantial universals) in OntoUMLPrime is very similar to the

Page 19: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

meta-model of the correspondent part in UFO-A. For example, the types kind, subkind, quantity, phase, category and mixin are just like the corresponding types in OntoUML.

The substantial universal class and its subclasses from the UFO-A fragment below (GUIZZARDI, 2005, p. 315) follow the same hierarchy as in this version of OntoUMLPrime.

Figure 6 – UFO-A fragment regarding substantial universals.

There are still some small differences. The collective universal, in OntoUMLPrime, has a property to specify whether or not it is extensional. The revised version also adds the supertypes "rigid universal" and "anti-rigid universal" to the corresponding substantial universal meta-classes. These supertypes are useful when we don't want to distinguish sortal types from mixin types.

4.6 Roles, Relators and Relations

UFO-A defines the concept of relators as being non-intrinsic moment universals. Relators represent material relations by mediating externally dependent universals (roles or rolemixins).

Each mediation specify the cardinality of the relator and the cardinality of the participant.

A material relation can be derived from the relator. OntoUMLPrime can now derive all cardinalities of the material relation from the associated relator and its mediations, with the equations defined in Guizzardi's thesis (2005, p. 331).

Page 20: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

The revised version of OntoUMLPrime now doesn’t require that the relator has direct mediations. Instead, it can inherit the mediations from a parent relator, like allowed in OntoUML. The constraint about the sum of the minimum cardinalities remains, as in OntoUML: "we require that a relator mediates at least two distinct individuals" (GUIZZARDI, 2005, p. 240).

The externally dependent universals (roles and rolemixins) must be connected to a mediation, but OntoUMLPrime now allows them to have indirect connections (inherited from a parent) too.

If a relation is not derived from a relator, it is a formal relation. Formal relations can freely specify all the cardinalities of the involved types.

4.7 Parts and Wholes

The revised version of OntoUMLPrime now considers meronymic (part-whole) relations in a more consistent way. Only the necessary elements of the relations are specified, everything else is derived. For example, some cardinalities have to be one, while others are specified as desired.

Another change proposed by this work is that we assume that a meronymic relation is "shareable" whenever the maximum cardinality in the whole is greater than one. We can make this assumption based on what Guizzardi (2005, p. 162) says: "An individual x of type A is said to be [non-shareable] part of another individual y of type B […] iff y is the only B that has x as part". We can say that this situation only happens when the maximum cardinality is one in the whole.

Another property that is now considered derived is "essential". The part is essential whenever it was specified as immutable (it has to be a specific part) and the whole is rigid. This is based on what Guizzardi (2005) says: "only rigid universals can participate as wholes in essential parthood relations" (p. 344) and "every essential part is also immutable" (p. 283).

There are four types of part-whole relations, described below.

The "component of" relation holds between functional complexes, and needs to have all cardinalities specified. If the part or the whole is immutable, this has to be specified too.

The membership relation also needs to have all cardinalities specified. The whole is necessarily a collective, while the part is either a collective or a functional complex. These relations also need to have specified if the parts or the wholes are immutable.

The sub-collection relation only needs the cardinality of the whole specified, since the part is always one single immutable part. This relation only holds between collections.

The sub-quantity relation doesn’t need any cardinalities specified, since they are all one. Additionally, the part is always essential. Since the whole is always one, this relation is never shareable. This relation only holds between quantities.

4.8 Main Differences with Respect to the Previous Version of the Meta-Model

The following table summarizes the main differences between the previous version of the OntoUMLPrime meta-model and the revised version of this work. The complete revised meta-model can be found in appendix A.

Page 21: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Previous Version Revised Version

PackageableElement doesn't reference its container (which may be Model or Package)

New Packageable Container superclass of Model and Package contains the PackageableElements

No support to importations New class Importation is a PackageableElement

Only MixinUniversal classes are abstract MixinUniversal classes are always abstract, but other classes are abstract whenever they have at least one partition (covering generalization set)

All constraints that validate models are invariants in an OCL file; many utility methods (e.g. allAncestors) are defined in OCL too

A validator class contains all the OCL invariants; most utility methods are now operations in the corresponding classes, and can be accessed from outside the OCL interpreter

A quality may be assigned many datatypes; all datatypes are implementation

A quality is assigned one datatype; new user-defined AbstractDataType corresponds to a conceptual space, and can be implemented by many other user-defined datatypes

Classes such as MeronymicRelation are too permissive

Redesign of these parts; classes only allow specification of what the modeler can specify, the rest is all derived; this also eliminates the need of some OCL constraints

Some classes don't follow the UFO-A hierarchy ExternallyDependentUniversal and MixinUniversal are now subtypes of SubstantialUniversal

Roles, rolemixins and relators are required to have a direct mediation; Qualities and modes are required to have a direct characterization

Mediation and characterization can be inherited; there is an accessor for the (possibly indirect) mediation and characterization on the classes

The OCL constraints have too many isKindOf checks

New RigidUniversal and AntiRigidUniversal superclasses that are common to sortals and mixins; new polymorphic operation to get the substance sortal identity provider

BinaryMaterialRelation would allow cardinalities to be specified

All cardinalities are completely derived, according to the equations in Guizzardi's thesis

Some OCL checks could raise a StackOverflowError depending on the model

Methods to check loops, for example, if a type is characterizing itself, or if a type is its own ancestor

In the next chapter, we'll present the language for the textual editor we built in this work. This editor is compatible with the meta-model of this chapter.

Page 22: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

5. The specification of the language

CLIFO (CLIF + UFO) stands for "Constraints in Logic are Important For Ontologies". In this chapter, we are going to present the language and discuss the semantics, mostly with examples. This chapter can serve as an informative reference for the language.

The meta-model of CLIFO is conformant to OntoUMLPrime, which we presented in the last chapter. OntoUMLPrime, in turn, is derived from OntoUML and conformant to UFO-A (we presented the main concepts in chapter 2).In section 3.2, we mentioned that we intend to make a language that is able to incorporate constraints in a model. Since the basis for the constraints language (CLIF) and the meta-model (OntoUMLPrime) are both external to this language, we presented some properties that are necessary in this language in order to properly connect it to the model and to properly specify the constraints. Considering that, we can say that CLIFO is designed with three goals in mind:

CLIFO has to be able to recognize an OntoUMLPrime model and specify constraints to it. The language considers the meta-model and its semantics to specify what can be done in the constraints, as discussed in section 3.2.

In CLIFO, we'll have a CLIF dialect for the constraints. Apart from that, we'll also have a way to specify the model itself, so we want one sublanguage for the model too. Every meta-class of CLIFO intended for the model is either a subclass of an OntoUMLPrime meta-class or the meta-class itself. Therefore, we can say that this part of CLIFO is an extension on OntoUMLPrime. For example, in CLIFO, we have specific types of generalization sets, as we'll discuss in this chapter.

We chose to design this model language aiming at an emphasized readability, so we wanted it to be somewhat self-explaining. We expect that people with little knowledge of UFO will be able to read a model and understand at least its main idea. We also expect that this readability will help modelers with the words to explain their models to another person. Of course, this task will be a lot easier when associated to a visual diagram, too.

5.1 About the notation used to explain the syntax

We will present all the syntax in the form of "templates". These are generic "shapes" that tell what text is accepted in the editor to represent a specific type of element in the meta-model of the grammar. The names between "<" and ">" are slots that can be replaced with something. These names tell what can be placed in the corresponding slot. The other parts are literal text; they appear exactly as they are in the template. Whitespaces/newlines are ignored. When the slot contains a "?", it's optional. When it contains a "*", it may have zero or more values, in a sequence. We will also use examples in addition to the templates. A "…" is used in the examples to denote some omitted text.

When the templates include "<ID>", it means that the slot is filled with a name. A name is a sequence of characters that follow these rules:

If the first character is "_", there are one or more safe characters after it.

Page 23: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Otherwise, the first character is an ASCII letter, and there are one or more safe characters after the first character.

A safe character is defined as one of these:

an ASCII letter (characters between "a" and "z" or between "A" and "Z");

an underscore "_";

an ASCII number;

When the templates include "<QID>", it means that the slot is filled with a qualified name. This is a sequence of names with a dot connecting all adjacent names. A single <QID> contains no whitespace or newlines.

When the templates include "<CLIF_STRING>", this is equivalent to the lexical token "quotedstring" from the CLIF specification.

When the templates include "<…>" after a pattern, the pattern may be repeated many times.

Page 24: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

5.2 CLIFO File

The purpose of a CLIFO file is to describe an ontology, through specification of the model and of the constraints that apply to its instances. Therefore, a CLIFO file uses two sublanguages. The sublanguage used for describing the model is compatible with the OntoUMLPrime meta-model. The sublanguage used for the constraints is a dialect of CLIF, supporting references of the model inside the constraints. We are going to present both sublanguages in this chapter.

A CLIFO file starts with a header that is intended to contain a minimum of meta-information. This header follows the template below:

//(C) 2016 - Example Inc. All rights reserved.

CLIFO: version 0;

compatible with: OntoUMLPrime and CLIF;

The first line is just a recommendation for a comment line (or comment lines). It is recommended to always include the copyright and license as a comment in the beginning of the files. The comment may include "public domain" if the file is not copyrighted. Multiline comments can be done enclosing the comment with the markers "/*" and "*/", as in CLIF and many other languages. Single-line comments begin with "//", as above.

The header includes the version number of the CLIFO language and two identifiers for the compatible meta-model and constraints language.

The next section presents the sublanguage for the model, which is compatible with the OntoUMLPrime meta-model.

Page 25: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

5.3 Model Language

A CLIFO file contains an OntoUMLPrime model right after the header. Any packageable element can be defined directly in the root of the model, but it is recommended to enclose the elements with a package. Packages follow the template below:

package <QID>:

<Using*>

<PrimitivePackage*>

<PackageableElements*>

end of package;

The package has a name (QID), and contains packageable elements. CLIFO imposes additional restrictions in how the packageable elements can be in a model. For example, import declarations (Using) and primitive packages have to be first in the package.

Import declarations allow the editor to find a reference to an element of a different scope, without having to specify the whole path to it. For example, if an element would be referenced as "foo.bar.Element", then one could write an import declaration for it as below:

package mypackage:

(using foo.bar.Element here)

// can now use the reference here as "Element"

end of package;

// the import is local, so it won't work here

// this is out of the scope where the import was made

// the reference has to be made as "foo.bar.Element" here

Wildcards are allowed, so it's possible to import everything inside a package, like below:

(using foo.bar.* here)

Primitive packages are just like regular packages, but they contain only primitive datatypes or other primitive packages. This is the template:

primitive package <QID>:

<PrimitiveElements*>

end of package;

OntoUMLPrime requires primitive datatypes to be defined in the model, and allows the name to be specified. In CLIFO, they can be defined as in the examples below:

logical type Logical; // false and true

discrete type Integer; // integer numbers

continuous type Real; // real numbers

symbolic type Textual; // strings

The editor allows to reference elements in other files of the same project, so it is recommended

Page 26: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

to have a separate CLIFO file just for the primitive datatypes.

CLIFO allows the following "packageable elements" to be inside the model or the packages: any user-defined datatype, an intrinsic package (a package for a specific type) followed by its corresponding type (a universal), a binary directed relationship, a generalization set, another package and a constraint. These elements can appear in any order. We are going to present each of them in the next sections.

5.3.1 User-defined Datatypes

OntoUMLPrime currently allows these types of user-defined (not primitive) datatypes: enumerations, abstract datatypes and complex datatypes. We are going to present the CLIFO syntax for them in this section.

OntoUMLPrime now includes abstract datatypes, which are called "conceptual spaces" in CLIFO. An abstract datatype can be "implemented" in many particular ways by other datatypes (the abstract is considered the generic type and the specializing datatype is the specific type). It can be defined with one of the templates below:

type <ID> is conceptual space;

type <ID> is conceptual subspace of <AbstractDataType>;

For example, one may write:

type Color is conceptual space;

type ColorGrayscale is conceptual subspace of Color; // also abstract

In CLIFO, a complex datatype is called an "structure". The attributes that compose it are called "dimensions". It is recommended that it always implements an abstract space, even if it's going to be used directly in qualities. The two possible templates are presented here (the second is the recommended one):

type <ID> is structure

(dimensions: <ID> is <DataType>; <...>);

type <ID> is structure

for <AbstractDataType>

(dimensions:

<ID> is <DataType>;

<...>

);

Three examples that implement the same space (the last one indirectly):

type ColorCMYK is structure for Color

(dimensions:

cyan is Real // [0 ~ 1]

magenta is Real // [0 ~ 1]

yellow is Real // [0 ~ 1]

black is Real // [0 ~ 1]

Page 27: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

);

type ColorHSV is structure for Color

(dimensions:

hue is Real // [0 ~ ]360.. angular

saturation is Real // [0 ~ 1] delimited

value is Real // [0 ~ 1] delimited

);

type ColorK is structure for ColorGrayscale

(dimensions: black is Real) // [0 ~ 1]

Enumerations can be defined with one of the templates below:

type <ID> is enumeration with {

<CLIF_STRING> , <CLIF_STRING> , <...>

};

type <ID> is enumeration for <AbstractDataType> with {

<CLIF_STRING> , <CLIF_STRING> , <...>

};

For example, one may write:

type ProcessState is enumeration with { 'Inactive', 'Active', 'Initializing' };

type ColorGrayscaleBasic is enumeration for ColorGrayscale with {

'black', 'lightgray', 'gray', 'darkgray', 'black'

}

Note that the enumeration type considers that each enumeration literal is equal to a string. For example, an instance can be compared to a literal in a CLIFO constraint, with:

(= processState 'Active')

5.3.2 Generalization Sets

As Guerson, Almeida and Guizzardi (2011) say, "OntoUML […] has a full support for dynamic and multiple classification". OntoUMLPrime always uses generalization sets to specify that a universal specializes another. CLIFO differentiates static classification from dynamic classification by allowing three types of generalization sets: distinction, status and recognition. We are going to present each type in this section.

The <QID> slots here represent a reference to a universal by QID (a qualified name, such as "mypackage.mysubpackage.MyUniversal"). The fist <QID> (after the keyword "each") is always the specialized universal; the other <QID> slots are specializing universals, unless specified otherwise. The <ID> slot is the name of the generalization set.

A static distinction is a generalization set used for static classification. It means that as soon as the specialized universal is instantiated, one of the specializing universals is chosen (or may be chosen) to be the type of that instance. This binding is kept until the instance ceases to exist.

A distinction implies that when the parent (specialized universal) is rigid, all the children (the specializing universals) are rigid too. In a static distinction, the classification is static, so the distinction can only be made when the individual is created and it never changes.

Page 28: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

For this reason, CLIFO uses the following templates for a static distinction:

any <QID> may be created as <QID>;

any <QID> may be created as either <QID> or <QID> or <...>;

any <QID> may be created with <ID> as either <QID> or <QID> or <...>;

each <QID> is created as either <QID> or <QID> or <...>;

each <QID> is created with <ID> as either <QID> or <QID> or <...>;

The ID after "with" is the name of the generalization set, and is recommended to be specified when the specialized universal is sortal. When a distinction is a partition (a covering generalization set), it is specified with "each". When it's not covering (the parent may or may not be instantiated as one of the children), it's specified with "any" and "may". A covering generalization set is required to have more than one specializing universal. We can use the static distinctions below as examples:

// partition of a kind into subkinds (distinction by subkind)

each Human is created with gender as either Man or Woman;

// distinction of sortal types from a category (distinction by sort)

each Person is created as either Human or Corporation;

// distinction of special relator from a parent relator (distinction by subkind)

any Accident may be created as Fatality;

A static distinction does not accept a non-rigid as the specialized universal. When non-rigid universals are specialized, the individual cannot be ensured to be at creation time anymore, because anti-rigid universals are instantiated and destroyed dynamically, because of changes. For this reason, there are other types of distinction. Consider the example below:

// distinction of sortal roles from a rolemixin (distinction by sort)

each Customer is automatically either HumanCustomer or CorporateCustomer;

This distinction is not static, because when a person becomes a customer, this individual is not at creation time anymore (Customer is anti-rigid). On the other hand, the distinction among human and corporation was already made at creation time. The distinction among human customer and corporate customer is automatic, because a previous static distinction was already made among the corresponding rigid universals.

For this reason, there is a second type of distinction: the automatic sort distinction. It happens when a non-rigid mixin is specialized with a distinction (therefore, it requires the specialized universal to be a non-rigid mixin universal). The templates are below:

each <QID> is automatically either <QID> or <QID> or <...>;

each <QID> has <ID> automatically as either <QID> or <QID> or <...>;

Automatic distinctions are always a partition of the abstract mixin type, so the generalization set is always covering. The second form allows to specify its name.

The other subtype is a sub-role distinction. It happens when a sortal role is yet specialized with a distinction. Again, it uses "each" when the generalization set is covering and it uses "any" and "may" otherwise. The templates are below:

any <QID> may be yet <QID>;

any <QID> may be yet either <QID> or <QID> or <...>;

any <QID> may have yet <ID> as either <QID> or <QID> or <...>;

each <QID> is yet either <QID> or <QID> or <...>;

each <QID> has yet <ID> as either <QID> or <QID> or <...>;

Page 29: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Here are some examples:

// partition of a role into more specific sub-roles

// this is a distinction of a previous recognition (no new relator)

// compare to the example below without the intermediate Worker role

each Worker is yet either Trainee or Employee;

// distinction of a special role

any Victim may be yet FatalVictim;

A second type of generalization set occurs when a universal is partitioned into phases. We call this a status. A status is always covering. The templates are below:

each <QID> is either <QID> or <QID> or <...>;

each <QID> changes in <ID> as either <QID> or <QID> or <...>;

The second form, which specifies the name of the generalization set, is preferred. It is recommended that the specialized universal have a quality associated with the phase partition. In this case, it's a good practice to use the same name in this quality and in the generalization set. When the specialized type is a substantial universal, the child types need to be phases. Let's see some examples:

each Human is either LivingPerson or DeadPerson;

each Human changes in age as either Baby or Child or Teenager or Adult;

The other type is called recognition. It happens when an individual participates in a relationship. We can say that the specialized universal is recognized as the specializing universal. A recognition is, therefore, associated with a relator. The classification happens when the relator is created.

CLIFO requires that a recognition specifies the relator from which it is derived explicitly (after the keyword "with"), as we see below:

any <QID> may become <QID> with <QID>;

any <QID> may become either <QID> or <QID> or <...> with <QID>;

any <QID> may get <ID> as either <QID> or <QID> or <...> with <QID>;

A recognition is never covering. The specializing universals are always roles or rolemixins, and they have to be associated with the relator (or a subtype of it) specified in the recognition.

Here are some examples:

// subkind getting a role

each Man may become Husband with Marriage;

// phase getting a role

// compare to the distinction example above with an intermediate Worker role

each Adult may get profession as either Trainee or Employee;

// role getting a second role (there is another relator)

// this is a recognition, not a sub-role distinction

each Player may get rank as either Winner or Loser with GameResult;

In this work, we are NOT stating that all generalization sets can be classified into one of these types. Nevertheless, CLIFO only supports these types, which shall cover most practical cases.

Page 30: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

5.3.3 Part-whole Relations

In this section we will present the CLIFO syntax for the four types of meronymic relations described earlier, in the other chapter. In the templates, <M> is the lower bound (a natural number) and <N> is the upper bound (a natural number or the keyword "many", representing that there is no upper bound).

A "component of" relation can be created as below:

there may be <M> to <N> specific <QID> as component of <M> to <N> specific <QID>;

The keyword "specific" is optional in both ends. When present, it means that the part or the whole is immutable. As said before, when the whole is rigid and the part is immutable, the part is called an essential part.

Here are some examples:

there may be 1 to 1 specific HumanBrain as component of 1 to 1 specific Human;

there may be 1 to 1 Heart as component of 0 to 1 Human;

The membership relation is analogous:

there may be <M> to <N> specific <QID> as member of <M> to <N> specific <QID>;

The keyword "specific" is also optional in both part and whole.

Here is an example:

there may be 2 to many Tree as member of 0 to 1 Forest;

The sub-collection relation is similar, but the part is essential to the whole:

there is the subcollective <QID> in <M> to <N> specific <QID>;

The keyword "specific" is optional in the whole. There is always one single specific part.

We can use this as an example:

there is the subcollective EnglishSegment in 1 to 1 specific GroupOfVisitors;

The sub-quantity relation is as below:

there is the subquantity <QID> in the specific <QID>;

The keyword "specific" is optional in the whole.There is always one single essential part and one single whole.

We can use the following example:

there is the subquantity Alcohol in the specific Wine;

5.3.4 Intrinsic Types

In this section, we will present the syntax for describing intrinsic moment universals and characterizations in CLIFO.

Page 31: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

A characterization uses the template below:

<M> to <N> <IntrinsicMomentUniversal>;

We use <M> and <N> as in the previous section, they are the lower and upper bounds of the characterization. The keyword "many" in <N> means there is no upper bound.

A quality is specified by the template below:

quality <ID> as <DataType>;

CLIFO only allows qualities to be specified inside intrinsic packages, to avoid name conflicts.For example, here we have an intrinsic package "Human" for the kind "Human":

type Human

(defines:

quality weight as WeightKG;

);

Human is kind

(characterized by:

1 to 1 weight;

);

Note that the quality "weight" is inside the intrinsic package. This makes it possible to access the quality with the QID "Human.weight". Inside the characterization, however, the quality is simply referenced as "weight", since it's already in the scope "Human".

Similarly, a mode also needs to be inside an intrinsic package. Here are the templates:

type <ID> is mode;

type <ID>

(defines:

<IntrinsicElement*>

);

<ID> is mode

(characterized by:

<M> to <N> <IntrinsicMomentUniversal>;

<...>

);

The first form has no characterizations. The other one is used when the mode is characterized by other intrinsic moment universals. It specifies the intrinsic package for the mode and the mode itself. They need to have the same name.

5.3.5 Substantial Types

In this section, we will present the CLIFO syntax for the substantial universals. Since the syntax is very similar, we are going to use the same templates for them:

type <ID> is <SubstantialUniversalMetaclass>;

type <ID>

(defines:

<IntrinsicElement*>

Page 32: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

);

<ID> is <SubstantialUniversalMetaclass>

(characterized by:

<M> to <N> <IntrinsicMomentUniversal>;

<...>

);

As before, the first template doesn’t specify an intrinsic package, while the second does. When the substantial universal has intrinsic elements (such as qualities), they are placed in its intrinsic package. This avoids name conflicts and is possible because the intrinsic elements have only one "container" type.

The slot <SubstantialUniversalMetaclass> can be replaced by these keywords:

kind

subkind

phase

role

rolemixin

mixin

category

quantity

collective

extensional collective

Each refers to the corresponding type in OntoUMLPrime; the last two refer to the CollectiveUniversal type, which may be specified as extensional, if desired.

5.3.6 Relations

In this section we will present the CLIFO syntax for the elements that represent relations. We will use <Participant> to represent a reference to an externally dependent universal (role/rolemixin).

A relator can be specified with one of the four templates below:

type <ID> is relator;

type <ID> is relator

(mediating:

<M> to <N> <ID> of type <Participant> with <M> to <N> <ID> of this type;

<...>

);

type <ID>

(defines:

<IntrinsicElement*>

);

Page 33: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

<ID> is relator

(characterized by:

<M> to <N> <IntrinsicMomentUniversal>;

<...>

);

type <ID>

(defines:

<IntrinsicElement*>

);

<ID> is relator

(mediating:

<M> to <N> <ID> of type <Participant> with <M> to <N> <ID> of this type;

<...>

)

(characterized by:

<M> to <N> <IntrinsicMomentUniversal>;

<...>

);

Note that a mediation defines lower and upper bounds of both the mediated role/rolemixin and the containing relator, in this order. It also specifies in <ID> the names of both association ends.

Here is an example:

type Marriage

(defines:

quality date as DateGregorian;

);

Marriage is relator

(mediating:

1 to 1 husband of type Husband with 1 to many marriages of this type;

1 to 1 wife of type Wife with 1 to many marriages of this type;

)

(characterized by:

1 to 1 date;

);

The revised version of OntoUMLPrime now considers that the direct mediations are optional, because a mediation can be inherited from a parent relator. The relator is still required to mediate always at least two individuals, but this mediation can be indirect now, as in OntoUML.

Characterizations are also optional in a relator, as in other types.

A binary material relation can be specified as one of the options below:

relation <ID> derived from the <Relator> between <Participant> and <Participant>;

relation <ID> derived from the <Relator> between

<ID> of type <Participant> and

<ID> of type <Participant>;

The names of the association ends are optional. For example, one can write:

relation isMarriedTo derived from the Marriage between Husband and Wife;

Page 34: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

No cardinality has to be specified, since they are all derived from the mediations.

A binary formal relation, however, requires that the modeler specifies the cardinalities:

relation <ID> between

<M> to <N> of type <Universal> and

<M> to <N> of type <Universal>;

relation <ID> between

<M> to <N> <ID> of type <Universal> and

<M> to <N> <ID> of type <Universal>;

The names of the association ends are still optional.

Here is an example of a formal relation with the end names:

relation isHeavierThan between

1 to 1 heavyPerson of type Person and 1 to many

thinPeople of type Person;

In the previous sections, we presented the syntax of model elements in CLIFO, in an informative way. In the next section, we will present a complete example of a CLIFO model.

Page 35: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

5.3.7 Example of a Model

In this section, we'll present an example of a CLIFO model without constraints. This model is equivalent to the one presented in section 3.1, which is in the domain of a road traffic accident.

This is the file "roadTrafficAccident.model.clifo":

//(C) 2016 public domain

CLIFO: version 0;

compatible with: OntoUMLPrime and CLIF;

// Road Traffic Accident - Model

package br.inf.ufes.nemo.ontouml.ontoumlprime.clifo.examples:

(using native.* here)

primitive package native:

discrete type Cardinal;

end of package;

type Person is kind;

type Man is subkind;

type Woman is subkind;

type Living is phase;

type Deceased is phase;

type Traveler is role;

type Victim is role;

each Person is created with gender as either Man or Woman;

each Person is either Living or Deceased;

any Person may become Traveler with Trip;

any Traveler may become Victim with Accident;

type Vehicle is kind;

type TravelingVehicle is role;

type CrashedVehicle is role;

any Vehicle may become TravelingVehicle with Trip;

any TravelingVehicle may become CrashedVehicle with Accident;

type Roadway is kind;

type AccidentRoadway is role;

any Roadway may become AccidentRoadway with Accident;

type Accident

(defines:

quality fatalVictims as Cardinal;

);

Accident is relator

(mediating:

1 to 1 place of type AccidentRoadway with 1 to many accidents of this type;

1 to many vehicles of type CrashedVehicle with 1 to 1 accident of this type;

1 to many victims of type Victim with 1 to 1 accident of this type;

)

Page 36: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

(characterized by:

1 to 1 fatalVictims;

);

type RearEndCollision is relator;

any Accident may be created as RearEndCollision;

type Trip is relator

(mediating:

1 to 1 vehicle of type TravelingVehicle with 1 to 1 trip of this type;

1 to many travelers of type Traveler with 1 to 1 trip of this type;

);

end of package;

In the next part, we'll show the syntax and semantics of the constraints, which have references to the model elements shown before.

Page 37: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

5.4 Constraints Language

Since constraints are packageable elements, they can be placed anywhere in the model or inside packages. As mentioned before, the sublanguage used to specify constraints is a dialect of CLIF. This means it is conformant to the CLIF specification from ISO/IEC 24707:2007, annex A. We are going to present the language in this section.

A CLIFO constraint has the following template:

(cl:text <NAME> <Sentence*>)

This means that a constraint with the specified name applies to the containing model. This constraint can have any amount of sentences; all these sentences are invariants that must always evaluate to true for any instances of the model.

Suppose there is a program that is capable of verifying these constraints for some instance of the model. If a sentence evaluates to false, an error should be displayed, with the name of the constraint included in the error message.

5.4.1 Sentences

In this section, we will present the syntax and semantics of the sentences in CLIFO.

The CL standard from ISO/IEC (2007) defines a sentence as: "unit of logical text which is true or false, i.e. which is assigned a truth-value in an interpretation" (p. 4).

In CLIFO, there are four types of sentences.

A comment sentence simply wraps a sentence in a comment string for it. The template is below:

(cl:comment <CLIF_STRING> <Sentence>)

The comment evaluates to the sentence.

The other type is a logic sentence, which can be any of the ones below:

(and <Sentence> <Sentence*>)

(or <Sentence> <Sentence*>)

(if <Sentence> <Sentence>)

(iff <Sentence> <Sentence>)

(not <Sentence>)

Each of them apply a logic operation to the results of the argument sentences. The and/or sentences that have a single argument will evaluate to that argument.

A quantified sentence represents a loop, and can be one the two options below:

(forall <InstanceIterator> <Sentence>)

(exists <InstanceIterator> <Sentence>)

Page 38: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Both types declare an instance iterator, which will have many values during evaluation, one value for each iteration in the loop.

The first one (forall) evaluates to true only when the inner sentence evaluates to true for every value of the iterator. The other type (exists) is true only when the inner sentence is true for at least one of the iterations.

The instance iterator declares an iterated individual, with the following template:

(<ID> <UniversalAttached>)

The left side is the name of the iterator, while the right side is a term which is attached to a universal. This can be either a type from the model in the "as" namespace, or an individual term, as we explain later. Here are examples of both, respectively:

(forall (person as:Person) …)

(forall (person peopleInTheRoom) …)

The last type of sentence is an atomic sentence. Atomic sentences evaluate terms, not other sentences (terms are discussed in the next section). The CL standard from ISO/IEC (2007) defines an atom as a "sentence form which has no subsentences as syntactic components" (p. 2).

Currently, the supported atomic sentences in CLIFO are the three types below (arbitrary atoms, as in CLIF, are not currently supported).

The equation sentence has the same meaning as in the CLIF specification – it evaluates to true only when the terms are considered equal (both evaluate to the same value). The template is:

(= <Term> <Term>)

Note that, if both terms have no value (empty), they are considered equal. If they both have multiple values, they are considered equal only when each value of one is included in the other.

The ordering sentence requires that both terms are comparable. If this is not the case, the evaluation must raise an error at runtime (or throw an exception), and the whole constraint must not be considered satisfied. The template is one of the types below:

(< <Term> <Term>)

(> <Term> <Term>)

The first one evaluates to true only when the first term is considered smaller than the second, and the other evaluates to true only when the first is greater than the second. Note that the operators for "greater or equal" and "smaller or equal" are not included, but can be achieved by using a combination of the previous sentences with "not".

The last type of atomic sentence is a declaration sentence. It is similar to the equation, but it allows the compiler to identify that a new variable is being declared, and what is the scope where the variable is "alive". The template is as below:

(var <QID> <IndividualTerm>)

It means that a new variable is declared with the specified name (QID) and defined as having the value of the specified individual term. This term represents an individual, instance of one of the types (universals) in the model. If the declaration is inside a quantified sentence (which is usually the case), the variable may receive a different value in each iteration of the loop.

This sentence always evaluate to "true", and it will be usually inside an "and" sentence, which is

Page 39: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

the scope of the variable (the variable is not "alive" out of that sentence).

5.4.2 Terms

In this section, we will present the syntax and semantics of the terms.

The CL standard from ISO/IEC (2007) defines terms as an "expression which denotes an individual, consisting of either a name or, recursively, a function term applied to a sequence of arguments, which are themselves terms" (p. 4).

In CLIFO, terms always represent sets of values. As a set, a term may be empty, a single value or contain many values. Also, a term has an associated type, which can be a datatype or an endurant universal from the model. The types of terms that are supported are explained in this section (CLIFO does not support arbitrary functions or terms, as in CLIF).

A comment term wraps a term with a comment string, as below:

(cl:comment <CLIF_STRING> <Term>)

The comment must evaluate to the term it contains; the string is ignored.

Numeral and textual terms are simply natural and string literals, according to the CLIF specification ("numeral" and "quotedstring"). The difference is that CLIFO considers non-negative real numbers as numeral terms too.

A non-negative real number may be any sequence of numeric characters that include one single dot in the middle (not in start or end). Examples:

3.14159 012345.67890 0.0 1.00

CLIFO considers that, when applicable, the numbers zero and one are equivalent to the logical values of "false" and "true", respectively. CLIFO does not consider strings as equivalent to numbers, even if they are a textual representation of that number.

A numeral function evaluates to a number, and follows the templates below:

(- <Term?> <Term>)

(/ <Term> <Term>)

(** <Term> <Term>)

(+ <Term> <Term*>)

(* <Term> <Term*>)

Each argument term have to contain exactly one value, and that value has to be a number.

If any argument doesn’t evaluate to a number, the evaluation of the function raises an error at runtime. Otherwise, they calculate the result of the corresponding operations, which are subtraction, division, exponentiation, addition and multiplication, respectively.

The left term of the subtraction is considered zero when not present. The multiplication or the addition with a single argument will evaluate to that argument.

There is also the amount function, with the template below:

Page 40: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

(# <Term>)

Since the terms are always sets of values, this function returns the amount of values in the term. If the term evaluates to empty (a set with no values), this function returns zero. If it evaluates to a single value, it returns one. If it evaluates to many values, it returns the amount of values.

For example, imagine a property "favoriteColor" which is optional (cardinality of zero or one). Let's consider the case where a person has no favorite color. We will take as an example the variable "person.favoriteColor", which would contain the favorite color of that person. This variable would be empty, so the function below would evaluate to zero in this case:

(# person.favoriteColor)

The other type is an individual term, which evaluates to a set of individuals that are instance of types from the model. It is either a direct reference to a variable or a function that returns the said set. In any case, it is associated to a type (universal) from the model, so it's considered an "UniversalAttached" term.

If it is an individual reference, it is just the name (QID) of the referenced variable. This variable can be either an individual iterator (declared in a quantified sentence) or an individual declared with "var". Variables from outer scopes can be referenced, but variables from inner scopes can't.

If it is an individual function, it may be one of the types that follow. These functions are used to access values or individuals from other individuals. They establish the binding between CLIF and the ontology (UFO-A).

A cast function has the template below:

(is <IndividualTerm> <EndurantUniversalConcept>)

The endurant universal concepts are types from the model; they are placed inside the "as" namespace, to be accessed by this function. For example, one may write:

(var man (is person as:Man))

The function will evaluate to the individual term (in this case, the individual in the variable "person"), but the compiler will now associate the result to the specified endurant universal. In this case, the variable "man" will have the endurant "Man" as its type (and therefore, the properties of "Man" can be accessed in this variable).

Since the type of "person" is known, CLIFO is capable of checking if individuals of that type could be cast to the desired type. A type can only be cast to a supertype or a subtype. Any other cast is invalid, and will make the compiler raise an error, which is shown in the editor.

A cast to a subtype will only return the values where the cast can be performed. For example, suppose the variable "people" is a set of men and women (subtypes of "Person"), in the example below:

(var men (is people as:Man))

When the function is evaluated, the variable "men" will contain all individuals from "people" that can be cast to the type "Man", so the others are excluded. This means that, if no individual can be cast (for example, if "people" contains only women), the result is empty (not an error).

A wholes function has the following template:

(with <IndividualTerm> <SubstantialUniversalConcept>)

The substantials universal concepts are types from the model; they are placed inside the "get"

Page 41: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

namespace, to be accessed in this function. For example, one may write:

(var teams (with person get:Team))

The function will evaluate to all the individuals of type "Team" that contain a value in "person" as a part. In this case, the variable "teams" will have the substantial universal "Team" as its type. CLIFO is able to check if there is a part-whole relation between "Team" as a whole and the type of "person" as a part; the compiler raises an error if there is none.

Again, note that the result is a set, and might be empty. Also, let's consider the example:

(var teams (with people get:Team))

The result will be: all teams that have a value in "people" as a part. This is a union of the teams of every person in the variable "people". The result is a set of teams (not a set of sets).

A parts function is completely analogous to the previous one, but it returns all parts that belong to a whole in the variable. It has the same template, but using "within" instead of "with".

Here we have an example that gets all trees that belong to any forest in the variable "forests":

(var trees (within forests get:Tree))

An intrinsic function is used to access an intrinsic moment of an individual. The template is:

(of <IndividualTerm> <IntrinsicMomentUniversalConcept>)

The intrinsic moment universal concepts are types from the model; they are placed inside the "get" namespace, to be accessed in this function. For example, one may write:

(var man.weight (of man get:Person.weight))

The function will evaluate to the values in the property "weight" of the individual "man". The variable "man.weight" will have the same type as the property. For example, if "weight" is a quality associated to the "WeightKG" datatype, the variable will have this type. Therefore one could write, for example:

(< man.weight 66)

This would compare the variable to the literal, assuming the type "WeightKG" has the "<" operation defined, of course. Note that, in the previous example, "man" is an individual of the type "Man", which is a subtype of "Person". This allows "man" to have (indirectly) the property "weight" desired (the characterization is inherited). If the required characterization was not compatible with the type of the individual, the compiler of CLIFO would have raised an error.

As said before, the result is a set. This means that the values can be iterated with a quantified sentence, regardless of the cardinality in the characterization. Let's now suppose we are getting the property from a variable "people" that contain many individuals, like this:

(var people.weight (of people get:weight))

The result stored in "people.weight" will have the property "weight" of each individual in "people". Note that we have used "get:weight" here, instead of "get:Person.weight", because we are assuming the constraint is placed inside the package for "Person" (therefore, it is already in the "Person" scope).

Let's now consider an example of a property with a cardinality of zero to many:

(var people.nicknames (of people get:nicknames))

Page 42: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Here we can have many people, and each person can have many nicknames. The result will be a set of nicknames, not a set of sets. For example, we could use a quantified sentence to iterate directly through the nicknames:

(not (exists (nickname people.nicknames) (= nickname '')))

A related function has two forms, as below:

(from <IndividualTerm>)

(from <IndividualTerm> <MediationConcept>)

The first one allows to access a relator from an associated role or rolemixin. Since OntoUMLPrime only allows one mediation connected to a role or rolemixin (even if it is inherited), the mediation is obtained implicitly.

The second one goes on the opposite direction, and requires that the mediation is specified (because a relator can have many mediations). If the desired mediation is not in the type of the individual (or in a supertype), the CLIFO compiler raises an error.

The mediation concepts are obtained specifying the containing relator (which is in the get namespace to be accessed in this function). For example, one may write:

(var marriage.husband (from marriage get:Marriage->husband))

The variable "marriage.husband" will contain the individuals that are associated to the individual "marriage" (a relator) through the mediation "husband" specified in the relator universal "Marriage". The result is of the type "Husband", implicitly obtained from the mediation.

As an example of a navigation in the opposite direction, one may write:

(var wife.marriages (from wife))

As said before, the mediation is obtained implicitly in this case. The variable "wife.marriages" will contain all the relator individuals associated to the individual "wife". Of course, if "wife" wasn’t a role or a rolemixin, the compiler would raise an error.

Note that in this case, the result has many values, because of the cardinality in the mediation. One could iterate on each value by writing:

(forall (marriage marriages) …)

or even:(forall (marriage (from wife)) …)

As an additional example of multiple values, one could write:

(var wives.marriages (from wives))

This would be a union of all marriages from all wives.

In the previous sections, we presented, in an informative way, the syntax and semantics of the sublanguage used for the constraints in the model. This sublanguage conforms to the ISO/IEC definition of a CLIF dialect. With this, one can verify whether instances of the model are obeying the constraints. In the next section, we'll present an example of constraints over a model.

Page 43: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

5.4.3 Example of Constraints

In this section, we'll present an example of a CLIFO file with the constraints of the model presented in section 5.2.7, which is in the domain of a road traffic accident. CLIFO allows the model and constraints both separate or in the same file; it doesn’t matter, as long as they are in the same project. We'll present just the constraints here, assuming separate files.

This is the file "roadTrafficAccident.constraints.clifo":// Public Domain.

CLIFO: version 0;

compatible with: OntoUMLPrime and CLIF;

// Road Traffic Accident: Constraints

package br.inf.ufes.nemo.ontouml.ontoumlprime.clifo.examples:

//> needs to import the package from the other file, it has the same name

(using br.inf.ufes.nemo.ontouml.ontoumlprime.clifo.examples.* here)

(cl:text "Every rear-end collision must involve exactly two crashed vehicles"

(forall (self as:RearEndCollision) (and

//> get the vehicles of the RearEndCollision (Accident)

(var self.vehicles (from self get:Accident->vehicles))

//> the amount of vehicles = 2

(= (# self.vehicles) 2)

))

)

(cl:text "The attribute fatalVictims is derived from the number of deceased

victims in an accident"

(forall (accident as:Accident) (and

//> instead of a derived property, we can only force the expected value

(var accident.fatalVictims (of accident get:Accident.fatalVictims))

//> get all victims from the accident

(var accident.victims (from accident get:Accident->victims))

//> cast each Victim to supertype Person

(var accident.victims.asPerson (is accident.victims as:Person))

//> cast each Person to subtype Deceased (will filter only deceased victims)

(var deceasedVictims (is accident.victims.asPerson as:Deceased))

//> check if the fatalVictims value is right: the amount of deceased victims

(= accident.fatalVictims (# deceasedVictims))

))

)

(cl:text "Last 2 constraints"

(forall (accident as:Accident) (and

//> get all vehicles from the accident

(var accident.vehicles (from accident get:Accident->vehicles))

//> get all victims from the accident

(var accident.victims (from accident get:Accident->victims))

//> constraint 3

Page 44: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

(cl:comment 'Every traveler of a vehicle participating in an accident is a

victim in that accident'

(forall (crashedVehicle accident.vehicles) (and

//> cast each CrashedVehicle to supertype TravelingVehicle

(var vehicle (is crashedVehicle as:TravelingVehicle))

//> get Trip from TravelingVehicle

(var vehicle.trip (from vehicle))

//> get each Traveler from Trip

(var vehicle.trip.travelers (from vehicle.trip get:Trip->travelers))

//> each Traveler has to be included in accident.victims

(forall (traveler vehicle.trip.travelers) (and

//> there is in self.victims one equal to each traveler

(exists (victim accident.victims) (= victim traveler))

))

))

)

//> constraint 4

(cl:comment 'Every vehicle, in which there is a victim of an accident, is

involved in that accident'

(forall (victim accident.victims) (and

//> cast Victim to supertype Traveler

(var victim.asTraveler (is victim as:Traveler))

//> get the Trip of the victim

(var trip (from victim.asTraveler))

//> get the Vehicle of the trip of the victim

(var trip.vehicle (from trip get:Trip->vehicle))

//> try to cast it to subtype CrashedVehicle (empty if it can't cast)

(var trip.vehicle.asCrashedVehicle (is trip.vehicle as:CrashedVehicle))

//> get the accident from the crashed vehicle of the victim

//.. (empty if the Vehicle wasn't a CrashedVehicle)

(var trip.vehicle.accident (from trip.vehicle.asCrashedVehicle))

//> ensure the crashed vehicle is included in this accident

//.. (also fails if the Vehicle wasn't a CrashedVehicle)

(= accident trip.vehicle.accident)

))

)

))

)

end of package;

These constraints can be compared to the OCL constraints presented in section 3.1 of the equivalent model, also in that same section.

Page 45: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

6. Implementation of the Editor

In this chapter, we'll show how we implemented the textual editor for CLIFO in the Eclipse Modeling Framework. We have used Xtext to generate the interpreter of the language and the associated textual editor. The meta-model is constrained by OCL invariants. These constraints are implemented in Xtend classes that run an OCL interpreter to validate the models.

When the model contains an error, it is shown in the editor, with a customized message, as we can see in the image below. Note that this example is a specialization problem, so an error is shown not only in the classes involved, but also in the generalization set, since any of them could be the source of the problem, and the correction depends on the modeler's intention.

Figure 7 - Demonstration* of the errors raised when an OCL constraint or an Xtend validation is violated in the model.

* The screenshot was edited to display many error messages; the editor only shows one message at a time.

Part of the implementation of the constraints is in OCL and part in Xtend methods. Also, some operations in the Xcore meta-models were implemented specifically to be used by the OCL constraints in the validators. They can, however, be also used outside of the OCL interpreter, in the Xtend classes.

The following figure shows the main components of the architecture. Note that the editor is compiled as an Eclipse Plug-in, and runs inside an Eclipse application. The editor is aware of all opened CLIFO files, as long as they are in the same Eclipse project and the project is configured with the "Xtext Nature".

Page 46: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Figure 8 - Main components of the CLIFO textual Editor and their dependencies.

In the top right corner, we have the OntoUMLPrime meta-model, in the Xcore format. An Xcore file contains an Ecore model, which can be used by all the other tools in the Eclipse Modeing Framework. We can see in the picture that this meta-model is required by almost all the components. This is the meta-model that we have revised in chapter 4; the file is available in appendix A.

In the top left corner, we can see that we have an independent class that runs the OCL interpreter. This wrapper class is used by the validators of OntoUMLPrime and of CLIFO. These validators are separated, since each of them have their own set of OCL constraints. The OCL constraints are embedded in these classes, along with the customized error messages that should appear when the constraints are violated. The OCL constraints are in appendix B.

In the right of the figure, we can see the meta-model and the grammar of CLIFO. We have discussed them in the last chapter. The complete syntax is available as a diagram in appendix C, along with the meta-model. Note that they depend on OntoUMLPrime, but OntoUMLPrime and its validator are independent of CLIFO.

In the center, we have a file used by Eclipse to provide default template proposals in the editor. This file contains some of the templates we used in the last chapter to explain the grammar. The template proposals are essential for the usability of the editor both in the model part (since the sublanguage is more verbalized, and at first it may be hard to remember the syntax) and in the constraints part (since all structures are enclosed in parentheses). The templates are very practical and also convenient for beginners to learn the language.

Page 47: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Figure 9 - Insertion of a "context" template in the constraints. The "forall" and "and" constructs were inserted at once.

We have also a file for custom completion proposals, as an addition the default proposals (of keywords and cross-references) that Xtext provides for the language.

The last resource on the left provides more meaningful icons and more convenient textual representations for the outline tree, which summarizes the language elements of the CLIFO file opened in the editor. We can see an example in the image below (the outline tree is on the left and the textual file is on the right).

Page 48: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Figure 10 - The CLIFO textual editor and the outline tree for the example CLIFO file of section 5.3.7.

Note that the role selected in the text is highlighted in the outline. The outline displays not only the name of the element, but also an icon and some additional information about it. In the case of the role, the connected mediation is displayed, with the cardinality of the associated relator. The name of the substance sortal identity provider is also displayed, inside the parentheses. Note also, inside "Accident", that the characterization of "fatalVictims" already shows the datatype (Cardinal) that is assigned to the characterizing quality universal, along with the cardinality.

These textual representations are also shown when the mouse is over an element in the text, even if it's a reference of it. This is very useful in the constraints, to understand what universal is the type of a declared variable, as we can see in the image:

Page 49: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Figure 11 - Description of the variable "accident.vehicles" showing the type of the individuals that will be on it.

The description appears when the mouse is over the element (the mouse pointer isn’t visible in the screenshot).

These features can indeed improve the usability of the editor, allowing it to be suitable for modeling, even with the language being textual.

Page 50: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

7. Conclusions

In this work, we have revised the OntoUMLPrime meta-model and its constraints, and we defined CLIFO as a textual language to describe OntoUMLPrime models and fill them with CLIF constraints. We have made an editor for this language, using the Eclipse Modeling Framework.

The syntax and semantics of this language are described in this work, in an informative way. The syntax was described using templates that define valid elements of the language, and some examples. In the sublanguage that defines the OntoUMLPrime model, the semantics are defined as the corresponding OntoUML elements. In the sublanguage that is a dialect of CLIF, used for the constraints, the semantics are textually described.

7.1 Contributions

This work is important for anyone that wants to deal with OntoUML models. The OntoUMLexperts can now easily and quickly make models that conform to OntoUMLPrime. Since the editor is textual, we expect that creating and verifying a model will be usually much faster than the same task in a graphical editor, such as OLED, assuming this task is done by an expert that already knows the language and the OntoUML concepts.

While the user is typing, the errors are displayed immediately in the editor, instead of requiring a validation action. Also, the editor takes care of the binding between the OntoUMLPrime model and the constraints, to ensure that the modeler is not doing anything invalid in the constraints. If there is anything wrong in the constraints, the error is displayed immediately, too.

Additionally, the user doesn’t have to worry about the graphical aspects of the model anymore, since it’s a textual language. For example, a graphical editor requires that the modeler worries about the position and size of the classes in the diagram, otherwise the model might be hard to read. A textual editor doesn’t have such requirement.

Also, since the language used for the model is more verbalized, we expect to be easy for a modeler to explain the model to non-experts, too.

Regarding OntoUMLPrime, we have identified in this work some possible types of generalization sets that we believe will cover most practical uses in the models. These types are capable of separating static classification from many types of dynamic classifications, and are based on the ontology from UFO-A. We've NOT formally proved in this work that these are the only possible types of generalization sets we need; we're not even making that statement. However, we have presented some examples of these types, which is enough to affirm that they exist and are different from each other. We believe they can help clarify the models a lot.

Page 51: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

7.2 Future works

By using the Eclipse Modeling Framework to build the editor, we have two advantages. The first is that the editor runs on top of Java, therefore, it is platform-independent. The second is that the meta-model is instantiated in the editor (as the model), and it is possible to define actions in the editor that serialize the model, converting it into anything desired.

For example, a possible future work could generate an OntoUML project that opens in OLED, and contains the converted model. The modeler could then create a class diagram for it, or use the other tools that OLED provides, such as the Alloy Analyzer. It's also possible to build a converter from the constraints defined here to OCL.

Another possible future work would be a second editor in Eclipse that allows to create instances of the model, for example, as JSON or another language. This editor would make the binding to the model of the editor defined here. It would display errors in invalid instances of the model. The instances are invalid when they don’t obey the constraints, so this would be a way to verify if the model might be under-constrained or over-constrained. Building this tool would require following the semantics of the constraints described in this work.

As for the revised version of OntoUMLPrime from this work, it can still be incremented with some other concepts. For example, the notion of qua-individuals is missing, so it's currently not possible to separate from the relator what are the properties of the relator itself and what are the properties that come from a specific participant. A future work can add increment the meta-model of OntoUMLPrime from the version we presented in this work.

Page 52: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

References

GUIZZARDI, Giancarlo. Ontological foundations for structural conceptual models. PhD Thesis, Centre for Telematics and Information Technology, University of Twente, 2005.

CARRARETTO, Roberto. A modeling infrastructure for OntoUML. Graduation Thesis, Federal University of Espírito Santo, 2010.

GUERSON, John; ALMEIDA, João Paulo A.; GUIZZARDI, Giancarlo. Support for Domain Constraints in the Validation of Ontologically Well-Founded Conceptual Models. Ontology and Conceptual Modeling Research Group, Federal University of Espírito Santo, 2011.

ALMEIDA, João Paulo A. ontoumlprime. 2013.Disponível em: <https://github.com/nemo-ufes/ontoumlprime>.Acesso em: 01 de Março de 2016.

INTERNATIONAL ORGANIZATION FOR STANDARDIZATION. ISO/IEC 24707: Information technology – Common Logic (CL): a framework for a family of logic based languages. Switzerland, 2007.

INTERNATIONAL ORGANIZATION FOR STANDARDIZATION. ISO/IEC 19507: Information technology – Object Management Group Object Constraint Language (OCL). [S.l.] 2012.

THE ECLIPSE FOUNDATION. Xtext – Documentation.Disponível em: <http://www.eclipse.org/Xtext/documentation/>.Acesso em: 01 de Março de 2016.

THE ECLIPSE FOUNDATION. Xtend – Documentation.Disponível em: <http://www.eclipse.org/xtend/documentation/index.html>.Acesso em: 01 de Março de 2016.

THE ECLIPSE FOUNDATION. Eclipse Modeling Project.Disponível em: <http://www.eclipse.org/modeling/emf/>.Acesso em: 01 de Março de 2016.

JACKSON, Daniel. Software Abstractions: logic, language, and analysis. MIT press, 2012.

MYLOPOULOS, J. Conceptual Modeling, Databases, and CASE: An Integrated View of Information Systems Development. Wiley, Chichester, 1992.

Page 53: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Appendix A – Revised OntoUMLPrime Meta-Model

The file "ontoumlprime.xcore", containing the revised version of the OntoUMLPrime meta-model, is below:

@Ecore(

nsPrefix="ontouml-prime", //Used for XMI serialization

nsURI="http://nemo.inf.ufes.br/ontouml/ontoumlprime"

)

@GenModel(

testsDirectory="/br.ufes.inf.nemo.ontouml.ontoumlprime.tests/src-gen",

editDirectory="/br.ufes.inf.nemo.ontouml.ontoumlprime.edit/src-gen",

editorDirectory="/br.ufes.inf.nemo.ontouml.ontoumlprime.editor/src-gen",

fileExtensions="pouml"

)

package br.ufes.inf.nemo.ontouml.PrimeOntoUML

/**

* This file specifies the OntoUMLPrime metamodel.

*

* The purpose of this is to reimplement a metamodel for OntoUML that is independent of the UML.

* The previous OntoUML metamodel implementation by Carraretto was based on the UML 2.0

implementation

* in Eclipse. This means that it is too polluted with UML constraints. Strictly speaking this is not

* UML anymore (so OntoUMLPrime is strictly speaking a misnomer).

*

* We have used the Xcore syntax. If you want to export a genmodel and ecore model from it, this can

be done by following the steps in:

* http://wiki.eclipse.org/Xcore#Converting_an_Xcore_Model_to_a_GenModel

* This is not necessary if you just want to create dynamic instances of the model, and if you want

to generate code, as it is generated

* automatically when you save the xcore file. However, this is necessary to use the OCL constraints

in ontoumlprime.ocl, as that refers

* to the ecore and not the xcore file, and also to use tools that depend on ecore (diagramming tool,

xtext).

*

* If you create a genmodel/ecore, make sure you do not generate code from the genmodel. The code is

already produced at src-gen

* when the xcore file is saved.

*

* History:

* created by João Paulo A. Almeida

*/

// namespaces like in UML (with package imports) Ramon: added Importation element

// @TODO: support for comments

// @TODO:

// create a separate metamodel for "ocurrences" of the elements in views

// (similar to ocurrences and definitions in ARIS)

// keep this metamodel for definitions and create a metamodel for occurrences.

Page 54: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

// this will enable a strict separation between model and views

// FIXME change from default optional cardinalities to [1]

class Model extends PackageableContainer {

// if we were to add validation method directly in xcore, this is how it is done (but so far we are

using OCL instead

// This is an easy way to make Xcore generate a Validator

// op boolean initializeValidator(org.eclipse.emf.ecore.EDiagnosticChain diagnostics,

org.eclipse.emf.ecore.EMap<Object, Object> context)

// { return true }

//Ramon: I created 2 classes: DynOCL.xtend, a OCL wrapper that is able to

//.. dynamically validate the model with OCL invariants and

//.. the other class is OntoUMLPrimeConstraints.xtend, a validator which

//.. uses the first one and contains all the OCL over OntoUMLPrime

//.; This class has to be called from the editor validators

}

//Ramon: changing many abstract classes to interfaces

interface Element {}

interface PackageableElement extends Element {

container PackageableContainer[1] pack opposite elements

}

//Ramon: adding this

interface PackageableContainer {

contains unordered unique PackageableElement[*] elements opposite pack

}

interface NamedElement extends Element {

String name

}

class Package extends NamedElement, PackageableElement, PackageableContainer {}

//Ramon: adding support to importations

class Importation extends PackageableElement, Representable {

String[1] importedNamespace

op String[1] getRepr() { '(' + importedNamespace + ')' }

}

// @TODO: abstract class HigherOrderClass extends NamedElement, PackageableElement {}

interface Universal extends NamedElement, PackageableElement {

// isAbstract is unnecessary, as the type of Universal already defines whether a corresponding

// uml class would be abstract

// Ramon: that is not true, as I understand, a sortal would be abstract if it has any partition

(covering generalization set)

// e.g.: http://www.inf.ufes.br/~gguizzardi/OFSCM.pdf @page 113 @figure 4.9 "Crate"

// I am gonna declare this here and implement in the subclasses

op boolean[1] isAbstract()

// Boolean isDerived ?

Page 55: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

// @TODO: refers unordered unique HigherOrderClass[*] instanceOf

//Ramon: NOTE: bidirectional reference needs to be transient<->local

//.. (transient on the derived) or the editor will have problems

//.. when it imports elements from an external file

refers transient unordered unique GeneralizationSet[*] isSpecializedVia opposite

specializedUniversal

// @TODO: make this derived https://bugs.eclipse.org/bugs/show_bug.cgi?id=282486#c13

// subclasses can be derived from isSpecializedVia

refers transient unordered unique GeneralizationSet[*] specializesVia opposite

specializingUniversals

// @TODO: make this derived https://bugs.eclipse.org/bugs/show_bug.cgi?id=282486#c13

// superclasses can be derived from specializesVia

// The query parents() gives all of the immediate ancestors of a generalized Classifier.

op unordered unique Universal[*] parents() { specializesVia.map[specializedUniversal].toSet.toEList

}

// The query allAncestors() gives all of the direct and indirect ancestors of a generalized

Classifier.

op unordered unique Universal[*] allAncestors() {

val ancestors = newHashSet()

specializesVia.forEach[val parent = specializedUniversal

ancestors+=parent; ancestors+=parent.allAncestors

]

ancestors.toEList

}

//Ramon: adding children and allDescendants

op unordered unique Universal[*] children() { isSpecializedVia.map

[specializingUniversals].flatten.toSet.toEList }

op unordered unique Universal[*] allDescendants() {

val descendants = newHashSet()

isSpecializedVia.forEach[val children = specializingUniversals

descendants+=children; descendants+=children.map[allAncestors].flatten

]

descendants.toEList

}

op boolean[1] isConsidered(Universal possibleAncestor) {

if(this==possibleAncestor) return true

specializesVia.exists[specializedUniversal.isConsidered(possibleAncestor)]

}

}

interface AbstractWhenHasPartition extends Universal {

op boolean[1] isAbstract() { isSpecializedVia.exists[isCovering] }

}

class GeneralizationSet extends NamedElement, PackageableElement, Representable {

boolean isCovering // default is false in UML, however, for OntoUML, ideally, the default would

// depend on the classes involved, and there are constraints

// use different GeneralizationSets if necessary to represent disjointNess

Page 56: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

refers local Universal[1] specializedUniversal opposite isSpecializedVia

// here we diverge from UML, which refers to Generalizations from a GeneralizationSet

refers local unordered unique Universal[1..*] specializingUniversals opposite specializesVia

// @TODO: add constraints for universals of the same metaclass

// @TODO: refers HigherOrderUniversal[0..1] powertype

op String[1] getRepr() {

val parent = specializedUniversal?.name ?: '?'

val specialized = if(isCovering) ' := ' else ' += '

val by = name ?: ''

val children = specializingUniversals.join('(', ' | ', ')', [name ?: '?'])

parent + specialized + by + children

}

}

// differentiate dynamic and static classification?

// or is this only in the semantics, given by the patterns of metaclasses involved?

//Ramon: CLIFO supports 5 different types of gensets

interface DataType extends NamedElement, PackageableElement {}

class PrimitiveDataType extends DataType {

PrimitiveDataTypeType[1] _type

}

enum PrimitiveDataTypeType {

// this is a direct way to implement built-in types, differently from UML

// in which this should be a library of built-ins at model level

Boolean, String, Real, UnlimitedNatural

}

interface UserDefinedDataType extends DataType, NamedElement, Representable {

refers local AbstractDataType[?] genericType opposite specificTypes

op String[1] getRepr() {

if(genericType == null) return name

name + ' : ' + (genericType?.name ?: '?')

}

}

class ComplexDataType extends UserDefinedDataType {

//Ramon: changing from [2..*] to [1..*]; I beleive it is always a better practice to admit the

trivial case

contains unordered unique DataTypeAttribute[1..*] attributes opposite complexDataType

}

class DataTypeAttribute extends NamedElement, Representable {

refers DataType[1] isOfType

container ComplexDataType[1] complexDataType opposite attributes

op String[1] getRepr() {

name + ' : ' + (isOfType?.name ?: '?')

}

}

//Ramon: since a quality can have many possible datatypes (dunno why), I am creating this

//.. it allows datatypes that work as a generalization of others

//.. ex.: generic Color can be complex Color_RGB or complex Color_HSV

//.. otherwise, qualities would always have to specify the measurement of the data, instead of the

concept

Page 57: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

class AbstractDataType extends UserDefinedDataType {

refers transient unordered unique UserDefinedDataType[*] specificTypes opposite genericType

}

class Enumeration extends UserDefinedDataType {

//Ramon: changing from [2..*] to [1..*]; I beleive it is always a better practice to admit the

trivial case

String[1..*] enumerationLiterals

}

////////////////////// whole-part relations

/// this part on whole-part relations should be redesigned, considering that it is too permissive

// have a general meronymic relation and leave all the details to the constraints?

// enforce also some constraints in the concrete syntax for example, since subQuantityOf is never

// shareable, partIsShareable should not even apply to it

//Ramon: I implemented this

interface MeronymicRelation extends BinaryDirectedRelationship, PackageableElement {

//Ramon: uhh... swapped because Dsl contradicted with this... about source and target...

refers SubstantialUniversal[1] whole // target

refers SubstantialUniversal[1] part // source

op int[1] getWholeLowerBound() { targetLowerBound }

op int[1] getWholeUpperBound() { targetUpperBound }

op int[1] getPartLowerBound() { sourceLowerBound }

op int[1] getPartUpperBound() { sourceUpperBound }

//FIXME Ramon: The concept of qua-individuals is missing

//.. should be a special metaclass that specializes mode, inheres in 1 role and is part of 1

relator (only)

//.. or a class contained directly in the mediation

//.. IMHO, Relators should be redesigned to contain only mediations and/or qua universals and

optionally the relator kind

//.. this relator kind would be part of the relator and contain the properties of the relator

itself (e.g: "date of marriage")

//.. the quas would contain the properties of the relata (e.g: "name after marriage")

//.. the relator itself wouldnt contain properties

//;. I think you should not need BOTH roles and quas specified for a relator, but at least one of

them

//.. depending on the counting principle you need in your model

//;. Since my task is not to redesign this, I am not implementing, but leaving it as a suggestion

:)

//FIXME redesign this

//Ramon: as I understand, this is derived; changing from boolean attr with default false

//reference: "only rigid universals can participate as wholes in essential parthood relations"

http://www.inf.ufes.br/~gguizzardi/OFSCM.pdf

//reference "Of course, every essential part is also immutable" http://www.inf.ufes.br/

~gguizzardi/OFSCM.pdf

derived boolean[1] partIsEssential get { partIsImmutable && whole instanceof RigidUniversal }

boolean[1] partIsInseparable = 'false' //TODO inseparable implies whole min 1

boolean[1] partIsImmutable = 'false' // essential implies immutable, TODO immutable implies part

Page 58: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

min 1

//Ramon: as I understand, this is derived; changing from boolean attr with default true

derived boolean[1] partIsShareable get { wholeUpperBound>1 || wholeUpperBound==-1 } // not

shareable iff whole max 1

}

interface SingleImmutablePartRelationship extends MeronymicRelation, SingleSourceRelationship {

op boolean getPartIsImmutable() { true }

}

class ComponentOfRelation extends MeronymicRelation, CustomBinaryDirectedRelationship {}

class MembershipRelation extends MeronymicRelation, CustomBinaryDirectedRelationship {}

class SubCollectionRelation extends SingleImmutablePartRelationship, CustomTargetRelationship {}

class SubQuantityRelation extends SingleImmutablePartRelationship, SingleTargetRelationship {

//Ramon: SingleTargetRelationship (exactly 1 whole) ensures that it is not shareable

}

// @TODO (scope of transitity?)

/////////////

//Ramon: adding this to facilitate understanding classes

interface Representable extends Element {

op String[1] getRepr()

}

interface EndurantUniversal extends Universal, Representable {

// TODO: all universals but Roles and Rolemixins ????????

// the current metamodel allows Roles and Rolemixins to be characterizedBy

// this seems to be a problem, because it is the relator that should appear with the properties of

the relata

//Ramon: see qua-individuals note above, or note in ocl in relators invariant

contains unordered unique Characterization[*] characterizedBy opposite source

//Ramon: I believe this should be moved to IntrinsicMomentContainer below

//I dont think qualities should be able to have characterizations, or more than one datatype (see

GenericDataType above)

}

// QUESTION: Why isn't it an Universal?

// Ramon: It should be SubstantialUniversal, I added this.

interface ExternallyDependentUniversal extends SubstantialUniversal {

//Ramon: NOTE: bidirectional reference needs to be transient<->local

//.. (transient on the derived) or the editor will have problems

//.. when it imports elements from an external file

refers transient Mediation[?] directMediation opposite target

//> Recursively get the mediation from the parent role/rolemixin

op Mediation[?] getInheritedMediation() {

val genset = specializesVia?.findFirst[specializedUniversal instanceof

ExternallyDependentUniversal]

(genset?.specializedUniversal as ExternallyDependentUniversal)?.mediation

}

// QUESTION: Why is it required?

//Ramon: in fact, a role can inherit a mediation from a role mixin, should change to [?]

//.. these constraints should be enforced by OCL, not the metamodel, because they often involve

Page 59: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

inheritance

//.. I am changing this so I can get the mediation even if it is indirect (direct is now optional,

indirect is still required)

refers derived Mediation mediation get { directMediation ?: inheritedMediation }

// should be derived https://bugs.eclipse.org/bugs/show_bug.cgi?id=282486#c13 instead

// An opposite reference within the same resource can be modeled through a read-only derived

property which traverses the model and looks for the incoming reference.

// A cross-resource, bidirectional reference has to be explicit (i.e. non transitive) on both

sides.

// I've detected this because

// the xtext editor that implements this forces us to specify this manually the opposite relation

// but mediations are not named. Making this derived should solve this.. but have to check later in

Xtext

}

//Ramon: replacement for hasKindInstance, etc.

enum Nature { KIND, QUANTITY, COLLECTIVE, MIXED, UNSPECIFIED }

//Ramon: easier to check rigidity

enum Rigidity { RIGID, SEMIRIGID, ANTIRIGID }

// SubstantialUniversals

interface SubstantialUniversal extends EndurantUniversal, IntrinsicMomentContainer {

op Nature[1] getNature()

op Rigidity[1] getRigidity()

op boolean[1] isExtensionalCollective()

}

interface SortalUniversal extends SubstantialUniversal, AbstractWhenHasPartition {

op Nature[1] getNature() { substanceSortal?.nature ?: Nature.UNSPECIFIED }

op boolean[1] isExtensionalCollective() {

val patriarch = substanceSortal

if(patriarch instanceof CollectiveUniversal) patriarch.isExtensional else false

}

op SubstanceSortalUniversal[?] getSubstanceSortal() {

var SubstanceSortalUniversal patriarch

for(parent : parents.filter(SortalUniversal))

if((patriarch = parent.substanceSortal) != null) return patriarch

}

op String[1] getReprSortal () {

val abstractrepr = if(abstract) 'abstract, ' else ''

val sort = substanceSortal

val sortrepr = if(sort==null) '?' else sort.name

name + ' (' + abstractrepr + sortrepr + ')'

}

op String[1] getRepr() { reprSortal }

}

interface RigidUniversal extends SubstantialUniversal {

op Rigidity[1] getRigidity() { Rigidity.RIGID }

}

interface AntiRigidUniversal extends SubstantialUniversal {

op Rigidity[1] getRigidity() { Rigidity.ANTIRIGID }

}

interface RigidSortalUniversal extends SortalUniversal, RigidUniversal {}

Page 60: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

interface AntiRigidSortalUniversal extends SortalUniversal, AntiRigidUniversal {}

interface SubstanceSortalUniversal extends RigidSortalUniversal {

op SubstanceSortalUniversal[1] getSubstanceSortal() { this }

op String[1] getRepr() {

val abstractrepr = if(abstract) ' (abstract)' else ''

name + abstractrepr

}

}

class Kind extends SubstanceSortalUniversal {

op Nature[1] getNature() { Nature.KIND }

}

class QuantityUniversal extends SubstanceSortalUniversal {

op Nature[1] getNature() { Nature.QUANTITY }

}

class CollectiveUniversal extends SubstanceSortalUniversal {

op Nature[1] getNature() { Nature.COLLECTIVE }

op boolean[1] isExtensionalCollective() { isExtensional }

boolean[1] isExtensional

}

class SubKind extends RigidSortalUniversal {}

class Role extends AntiRigidSortalUniversal, ExternallyDependentUniversal {

op String[1] getRepr() {

val med = mediation

val m = med?.sourceEndName ?: med?.source?.name ?: '?'

val bounds = if(med == null) '' else ' [' + (

if(med.sourceLowerBound==med.sourceUpperBound) med.sourceUpperBound + ''

else if(med.sourceLowerBound==0) {

if(med.sourceUpperBound==-1) '*'

else '0..' + med.sourceUpperBound

} else if(med.sourceUpperBound==-1) med.sourceLowerBound + '..' + '*'

else med.sourceLowerBound + '..' + med.sourceUpperBound

) + ']'

reprSortal + ' <-> ' + m + bounds

}

}

class Phase extends AntiRigidSortalUniversal {}

// changing from Universal to SubstantialUniversal, according to the metamodel

interface MixinUniversal extends SubstantialUniversal {

op boolean[1] isAbstract() { true }

op Nature[1] getNature() {

var Nature nature

for(child : children.filter(SubstantialUniversal)) {

val n = child.nature

if(n == Nature.UNSPECIFIED) return Nature.UNSPECIFIED

if(nature == null) nature = n

else if(nature != n) nature = Nature.MIXED

}

nature

}

op boolean[1] isExtensionalCollective() {

Page 61: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

allDescendants.filter(CollectiveUniversal).forall[isExtensional]

}

op String[1] getReprMixin() {

name + ' (abstract)'

}

op String[1] getRepr() { reprMixin }

}

interface RigidMixinUniversal extends MixinUniversal, RigidUniversal {}

class Category extends RigidMixinUniversal {}

interface NonRigidMixinUniversal extends MixinUniversal {}

interface SemiRigidMixinUniversal extends NonRigidMixinUniversal {

op Rigidity[1] getRigidity() { Rigidity.SEMIRIGID }

}

class Mixin extends SemiRigidMixinUniversal {}

interface AntiRigidMixinUniversal extends NonRigidMixinUniversal, AntiRigidUniversal {}

class RoleMixin extends AntiRigidMixinUniversal, ExternallyDependentUniversal {

op String[1] getRepr() {

val m = directMediation?.sourceEndName ?: directMediation?.source?.name ?: '?'

reprMixin + ' <-> ' + m

}

}

// Moment Universals

interface MomentUniversal extends EndurantUniversal, AbstractWhenHasPartition {}

class RelatorUniversal extends MomentUniversal, IntrinsicMomentContainer {

contains unordered Mediation[*] mediations opposite source

// @TODO add constraint: may only specialize other RelatorUniversals

//Roberto: soma das cardinalidades mínimas tem que ser 2 (não o número de mediations)

//JP: pq não 2 mediations para a mesma class no caso de relações simétricas?

//Ramon: porque, tecnicamente, um relator pode herdar mediations do pai (mudei de 2..*)

//.. alem disso, eh melhor evitar, pois isso deixaria o modelo mais confuso (se a relacao eh

simetrica, eh melhor que fique claro)

//Ramon: eu, particularmente, acho que essa coisa de permitir heranca entre relators deveria ser

repensada...

op String[1] getRepr() {

val abstractrepr = if(abstract) ' (abstract)' else ''

name + abstractrepr

}

}

//Ramon: I redesigned the relations, now the contraints are more accurately represented in the

metamodel

interface BinaryDirectedRelationship {

String[?] sourceEndName

String[?] targetEndName

//get accessors to be overrided by the features implemented in the classes below

op int[1] getSourceLowerBound()

Page 62: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

op int[1] getSourceUpperBound()

op int[1] getTargetLowerBound()

op int[1] getTargetUpperBound()

//TODO add immutableSource / immutableTarget and implement in subclasses

// source and med.source are specified in specializations of this class

// by doing this, the typing contraints can be directly specified in the metamodel (in metaclasses

// that specialize this abstract metaclass), making some constraints unnecessary

// TODO check how this is implemented in ref ontouml metamodel

// JP: I assume there is no reason to distinguish ordered and non-ordered, as all should be non-

ordered

// JP: I assume all are unique as well (mapping to sets and not bags)

}

interface SingleSourceRelationship extends BinaryDirectedRelationship {

readonly int[1] sourceLowerBound = '1'

readonly int[1] sourceUpperBound = '1'

}

interface SingleTargetRelationship extends BinaryDirectedRelationship {

readonly int[1] targetLowerBound = '1'

readonly int[1] targetUpperBound = '1'

}

interface CustomSourceRelationship extends BinaryDirectedRelationship {

int[1] sourceLowerBound = '0' //default = 0 (least restrictive if unspecified)

int[1] sourceUpperBound = '-1' //default = infinite (avoids the need of a value converter in xtext)

}

interface CustomTargetRelationship extends BinaryDirectedRelationship {

int[1] targetLowerBound = '0' //default = 0 (least restrictive if unspecified)

int[1] targetUpperBound = '-1' //default = infinite (avoids the need of a value converter in xtext)

}

interface CustomBinaryDirectedRelationship extends CustomSourceRelationship, CustomTargetRelationship

{}

class BinaryMaterialRelation extends BinaryDirectedRelationship, NamedElement, PackageableElement {

//Ramon: implemented derivations, according to http://www.inf.ufes.br/~gguizzardi/OFSCM.pdf @page

331

refers RelatorUniversal[1] derivedFrom

derived int[1] tupleLowerBound get { source.mediation.mediatedLowerBound *

target.mediation.mediatedLowerBound }

derived int[1] tupleUpperBound get { source.mediation.mediatedUpperBound *

target.mediation.mediatedUpperBound }

refers ExternallyDependentUniversal[1] source

derived int[1] sourceLowerBound get { source.mediation.mediatedLowerBound *

target.mediation.relatorLowerBound }

derived int[1] sourceUpperBound get { source.mediation.mediatedUpperBound *

target.mediation.relatorUpperBound }

Page 63: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

refers ExternallyDependentUniversal[1] target

derived int[1] targetLowerBound get { target.mediation.mediatedLowerBound *

source.mediation.relatorLowerBound }

derived int[1] targetUpperBound get { target.mediation.mediatedUpperBound *

source.mediation.relatorUpperBound }

// TODO: typing constraints for source and target based on the relation universal

// should also be a set, even if there are two relators relating the same entities, there

// should not be two material relations between the same entities... the tuples are identical

// e.g., you should not say that there are two "student at" relations between "Student" and

// "University" even if there are two "Enrollments".

op String[1] getRepr() {

val s = sourceEndName ?: source?.name ?: '?'

val t = targetEndName ?: target?.name ?: '?'

val r = derivedFrom?.name ?: '?'

s + ' ' + name + ' ' + t + ' (' + r + ')'

}

}

class BinaryFormalRelation extends CustomBinaryDirectedRelationship, NamedElement,

PackageableElement, Representable {

refers Universal[1] source

refers Universal[1] target

op String[1] getRepr() {

val s = sourceEndName ?: source?.name ?: '?'

val t = targetEndName ?: target?.name ?: '?'

s + ' ' + name + ' ' + t

}

}

class Mediation extends CustomBinaryDirectedRelationship, Representable {

//Ramon: adding a way to show the name in the editor

derived String[1] name get { targetEndName }

// source -> relator

container RelatorUniversal[1] source opposite mediations

derived int[1] relatorLowerBound get { sourceLowerBound }

derived int[1] relatorUpperBound get { sourceUpperBound }

//target -> mediated

refers local ExternallyDependentUniversal[1] target opposite directMediation

derived int[1] mediatedLowerBound get { targetLowerBound }

derived int[1] mediatedUpperBound get { targetUpperBound }

// check source and target direction for correspondence to Roberto's metamodel to facilitate

// transformations

//Ramon: adding a way to show the property in the editor

op String[1] getRepr() {

val related = targetEndName + ' : ' + (target?.name ?: '?')

val bounds =

Page 64: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

if(targetLowerBound==targetUpperBound) targetUpperBound + ''

else if(targetLowerBound==0) {

if(targetUpperBound==-1) '*'

else '0..' + targetUpperBound

} else if(targetUpperBound==-1) targetLowerBound + '..' + '*'

else targetLowerBound + '..' + targetUpperBound

related + ' [' + bounds + ']'

}

}

class Characterization extends SingleSourceRelationship, CustomTargetRelationship, Representable {

//Ramon: I seriously believe we should change this to IntrinsicMomentContainer

//.. I believe qualities souldnt be able to have characterizations

container EndurantUniversal[1] source opposite characterizedBy

refers local IntrinsicMomentUniversal[1] target opposite directCharacterization

//Ramon: adding a way to show the property in the editor

op String[1] getRepr() {

val intrinsic = target?.repr ?: '?'

val bounds =

if(targetLowerBound==targetUpperBound) targetUpperBound + ''

else if(targetLowerBound==0) {

if(targetUpperBound==-1) '*'

else '0..' + targetUpperBound

} else if(targetUpperBound==-1) targetLowerBound + '..' + '*'

else targetLowerBound + '..' + targetUpperBound

intrinsic + ' [' + bounds + ']'

}

}

// QUESTION: Why is Derivation missing?

// Is it because it should be implicit and automatically created for every (MaterialAssiciation,

RelatorUniversal) pair?

// Yes, I implemented the derived cardinalities in the BinaryMaterialRelation (but I didnt do it for

the nAry, though...)

interface IntrinsicMomentContainer extends EndurantUniversal {}

interface IntrinsicMomentUniversal extends MomentUniversal {

//Ramon: NOTE: bidirectional reference needs to be transient<->local

//.. (transient on the derived) or the editor will have problems

//.. when it imports elements from an external file

refers transient Characterization[?] directCharacterization opposite target

//> Recursively get the characterization from itself or the parent

op Characterization[?] getIndirectCharacterization() {

val genset = specializesVia?.findFirst[specializedUniversal instanceof IntrinsicMomentUniversal]

(genset?.specializedUniversal as IntrinsicMomentUniversal)?.characterization

}

// QUESTION: This cardinality is conflicting with the constraint "A Mode must be connected

(directly or indirectly) to a Characterization", isn't it?

//Ramon: I think yes, I am doing here the same I did with the

ExternallyDependentUniversal#directMediation

//.. I am changing this so I can get the characterization even if it is indirect (direct is now

Page 65: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

optional, indirect is still required)

refers derived Characterization characterization get { directCharacterization ?:

indirectCharacterization }

//> Recursively checks if there is a loop in the characterization

op boolean isCharacterizingSelf() { isCharacterizing(this) }

op boolean isCharacterizing(IntrinsicMomentUniversal aspect) {

switch(characterizing : characterization?.source) {

case aspect: true // characterizing the aspect: there is a loop

IntrinsicMomentUniversal: characterizing.isCharacterizing(aspect) // characterizing another

aspect

default: false // characterizing a type that cant be characterizing anything else: no loop

}

}

// should be derived https://bugs.eclipse.org/bugs/show_bug.cgi?id=282486#c13 instead

//Ramon: I suggest to have an attribute here to specify if the moment individual can change

(equivalent of essentialPart for characterization)

//.. e.g: compare "age" (mutable) with "date of birth" (immutable)

//.. by the way, Im not implementing this

}

class ModeUniversal extends IntrinsicMomentUniversal, IntrinsicMomentContainer {

op String[1] getRepr() {

if(characterizingSelf) return '?'

val abstractrepr = if(abstract) ' (abstract)' else ''

name + abstractrepr

}

}

//Ramon: why can QualityUniversal have a characterization? this seems wrong.

//Ramon: QUESTION: why would a quality inherit from another? is it for "overriding" the other?

class QualityUniversal extends IntrinsicMomentUniversal {

//Ramon: according to http://www.inf.ufes.br/~gguizzardi/OFSCM.pdf @page 235 @figure 6.12

//.. a quality universal can be associated only with exactly 1..1 quality structure

//.. this quality structure is implied from the assigned datatype

//.. I am changing from unordered unique 0..* to 1..1

refers DataType[1] datatype

//Ramon: note, qualities can now be assigned a general abstract datatype (the conceptual space)

//.. with multiple subdatatypes (basis for the space). see AbstractDataType

op String[1] getRepr() {

if(characterizingSelf) return '?'

val abstractrepr = if(abstract) ' (abstract)' else ''

val datatyperepr = datatype?.name ?: '?'

name + abstractrepr + ' : ' + datatyperepr

}

}

///////////////////////////////////////////////////////////////////////////////

/// some advance stuff being considered, really work in progress

Page 66: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

//QUESTION: Why does it have multiple source bounds if there is only 1 source (derivedFrom)

//Ramon: I didnt understand either... I wont implement this

class nAryMaterialRelation extends NamedElement, PackageableElement {

refers RelatorUniversal[1] derivedFrom

// fixme: should be at least 3

refers ExternallyDependentUniversal[*] targetRelata // ordered relata

String[*] targetEndNames

// int[*] targetLowerBound // always 1

// int[*] targetUpperBound // always 1

int[*] sourceLowerBound

int[*] sourceUpperBound

// cardinality constraints are derived

// typing constraints for source and target based on the relation universal

}

class nAryFormalRelation extends NamedElement, PackageableElement {

// fixme: should be at least 3

refers Universal[*] targetRelata // ordered relata

String[*] targetEndNames

// int[*] targetLowerBound // always 1

// int[*] targetUpperBound // always 1

int[*] sourceLowerBound

int[*] sourceUpperBound

}

Page 67: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Appendix B – Revised OntoUMLPrime Validator

The file "OntoUMLPrimeConstraints.xtend", containing the validator class that uses an OCL interpreter to impose constraints over the meta-model, is below:

package br.ufes.inf.nemo.ontouml.PrimeOntoUML.validation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.AntiRigidSortalUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.BinaryDirectedRelationship

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.BinaryMaterialRelation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.CollectiveUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.ComponentOfRelation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.CustomSourceRelationship

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.CustomTargetRelationship

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.EndurantUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.ExternallyDependentUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.GeneralizationSet

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.IntrinsicMomentUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.MembershipRelation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.MeronymicRelation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.MixinUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.MomentUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.Phase

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.RelatorUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.RigidMixinUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.RigidSortalUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.RigidUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.SortalUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.SubCollectionRelation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.SubQuantityRelation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.SubstanceSortalUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.SubstantialUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.Universal

import org.eclipse.emf.ecore.EClassifier

import static br.ufes.inf.nemo.ontouml.PrimeOntoUML.PrimeOntoUMLPackage.Literals.*

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.nAryMaterialRelation

class OntoUMLPrimeConstraints {

new(br.ufes.inf.nemo.ontouml.PrimeOntoUML.util.DynOCL ocl) { this.ocl = ocl }

private val br.ufes.inf.nemo.ontouml.PrimeOntoUML.util.DynOCL ocl

private var define = true

def context(EClassifier c, Object x) { if(define) defs() ocl.context(c, x) }

def private defs() {

ocl.context(UNIVERSAL)

//TODO move all methods to xcore to allow other places to access them

.op("isAncestorOf(descendant : Universal) : Boolean =

let c : Set(Universal) = children() in

Page 68: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

c->includes(descendant) or c->exists(u|u.isAncestorOf(descendant))")

.op("substanceSortalAncestors() : Set(SubstanceSortalUniversal) =

allAncestors()->select(x|x.oclIsKindOf(SubstanceSortalUniversal)).oclAsType

(SubstanceSortalUniversal)->asSet()")

//TODO should I change the context to IntrinsicMomentContainer?

ocl.context(ENDURANT_UNIVERSAL)

.op("isConvertibleTo(target : EndurantUniversal) : Boolean =

isConsidered(target) or allDescendants()->includes(target)")

.op("isPartOf(whole : EndurantUniversal) : Boolean =

MeronymicRelation.allInstances()->exists(r|whole.isConsidered(r.whole) and self.isConsidered

(r.part))")

.op("containsPart(part : EndurantUniversal) : Boolean = part.isPartOf(self)")

.op("containsAspect(aspect : EndurantUniversal) : Boolean =

allAncestors()->including(self).oclAsType(EndurantUniversal).characterizedBy->exists(c|c.target

= aspect)")

ocl.context(GENERALIZATION_SET)

.op("allDescendants() : Set(Universal) =

specializingUniversals->union(specializingUniversals.allDescendants())->asSet()")

define = false

}

def dispatch Universal(Universal x) {

context(UNIVERSAL, x)

.inv('E', '"' + x.name + '" has multiple identity providers.',

NAMED_ELEMENT__NAME,

"substanceSortalAncestors()->size() <= 1")

}

def dispatch Universal(EndurantUniversal x) {

_Universal(x as Universal)

context(ENDURANT_UNIVERSAL, x)

}

def dispatch Universal(SubstantialUniversal x) {

_Universal(x as EndurantUniversal)

if(x instanceof RigidUniversal) RigidUniversal(x)

if(x instanceof ExternallyDependentUniversal) ExternallyDependentUniversal(x)

context(SUBSTANTIAL_UNIVERSAL, x)

}

def RigidUniversal(RigidUniversal x) {

context(RIGID_UNIVERSAL, x)

//> GeneralizationSet/all[4]

.inv('E', '"' + x.name + '" cannot specialize an anti-rigid being rigid.',

NAMED_ELEMENT__NAME,

"not parents()->exists(u|u.oclIsKindOf(AntiRigidUniversal))")

}

def ExternallyDependentUniversal(ExternallyDependentUniversal x) {

context(EXTERNALLY_DEPENDENT_UNIVERSAL, x)

.inv('E', 'Could not find a relator mediating "' + x.name + '" or an ancestor.',

NAMED_ELEMENT__NAME,

"Mediation.allInstances()->exists(m|self.isConsidered(m.target))")

}

Page 69: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

def dispatch Universal(SortalUniversal x) {

_Universal(x as SubstantialUniversal)

context(SORTAL_UNIVERSAL, x)

.inv('E', '"' + x.name + '" is not abstract, so it must have a substance sortal ancestor.',

NAMED_ELEMENT__NAME,

"not isAbstract() implies getSubstanceSortal()<>null")

}

def dispatch Universal(RigidSortalUniversal x) {

_Universal(x as SortalUniversal)

}

def dispatch Universal(SubstanceSortalUniversal x) {

_Universal(x as RigidSortalUniversal)

context(SUBSTANCE_SORTAL_UNIVERSAL, x)

.inv('E', '"' + x.name + '" cannot specialize a sortal being a substance sortal.',

NAMED_ELEMENT__NAME,

"not parents()->exists(u|u.oclIsKindOf(RigidSortalUniversal))")

}

def dispatch Universal(CollectiveUniversal x) {

_Universal(x as SubstanceSortalUniversal)

context(COLLECTIVE_UNIVERSAL, x)

.inv('E', '"' + x.name + '" is extensional, so all the parts must be essential.',

NAMED_ELEMENT__NAME,

"isExtensional implies MeronymicRelation.allInstances()->forAll(r|

r.whole.isConsidered(self) and r.whole.oclIsKindOf(RigidSortalUniversal)

implies r.partIsEssential)")

//TODO add warning in the meronimic relations

}

def dispatch Universal(Phase x) {

_Universal(x as AntiRigidSortalUniversal)

context(PHASE, x)

.inv('E', '"' + x.name + '" needs to be in exactly 1 partition of phases.',

NAMED_ELEMENT__NAME,

"let genset : Set(GeneralizationSet) = specializesVia->select(g|

g.specializedUniversal.oclIsKindOf(SortalUniversal)) in

if genset->size() <> 1 then false else

let siblings : Set(Universal) = genset.specializingUniversals->asSet() in

genset->forAll(g|g.isCovering) and siblings->size() > 1 and

siblings->forAll(u|u.oclIsKindOf(Phase)) endif")

}

def dispatch Universal(MixinUniversal x) {

_Universal(x as SubstantialUniversal)

context(MIXIN_UNIVERSAL, x)

.inv('E', '"' + x.name + '" cannot specialize a sortal being a non-sortal.',

NAMED_ELEMENT__NAME,

"not parents()->exists(u|u.oclIsKindOf(SortalUniversal))")

}

def dispatch Universal(RigidMixinUniversal x) {

_Universal(x as MixinUniversal)

}

def dispatch Universal(MomentUniversal x) {

_Universal(x as EndurantUniversal)

}

def dispatch Universal(IntrinsicMomentUniversal x) {

Page 70: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

_Universal(x as MomentUniversal)

context(INTRINSIC_MOMENT_UNIVERSAL, x)

.inv('E', 'Could not find a type characterized by "' + x.name + '" or an ancestor.',

NAMED_ELEMENT__NAME,

"Characterization.allInstances()->exists(c|self.isConsidered(c.target))")

.inv('E', '"' + x.name + '" cannot characterize itself.',

NAMED_ELEMENT__NAME,

"not isCharacterizingSelf()")

}

def dispatch Universal(RelatorUniversal x) {

_Universal(x as MomentUniversal)

context(MOMENT_UNIVERSAL, x)

.inv('E', '"' + x.name + '" needs to contain a mediation or inherit one from another

relator.',

NAMED_ELEMENT__NAME,

"Mediation.allInstances()->exists(m|self.isConsidered(m.source))")

.inv('E', '"' + x.name + '" must always be mediating at least 2 participants.',

NAMED_ELEMENT__NAME,

"let mediations : Set(Mediation) = Mediation.allInstances()->select(m|self.isConsidered

(m.source)) in

mediations->isEmpty() or mediations.targetLowerBound->sum() >= 2")

}

//TODO are there rules involving quality inheritance?

// e.g. Person.weight is Weight, FatPerson.weight should be Weight or subdatatype, like

FatWeight or sth...

//TODO rules for datatype inheritance (such as cannot be ancestor of itself)

def GeneralizationSet(GeneralizationSet x) {

val sup = x.specializedUniversal

val not = if(sup instanceof SubstantialUniversal) 'not ' else ''

val c = context(GENERALIZATION_SET, x)

//TODO deal with duplicate specialization

if(c.all('E', '"' + sup.name + '" is an ancestor of itself because of the child "%s".',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"specializingUniversals->select(u|u=specializedUniversal or u.isAncestorOf

(specializedUniversal))",

NAMED_ELEMENT__NAME).invalid) return;

if(c.inv('E', 'Cannot repeat a specializing type.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"specializingUniversals->asSet()->size()=specializingUniversals->size()").invalid) return;

c.all('E', '"' + sup.name + '" cannot be specialized by "%s" because "%s" is '

+ not + ' a substantial universal.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"specializingUniversals->select(u|" + not + "u.oclIsKindOf(SubstantialUniversal))",

NAMED_ELEMENT__NAME, NAMED_ELEMENT__NAME)

.all('W', '"%s" cannot specialize "' + sup.name + '" and have another identity provider.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"allDescendants()->select(u|u.substanceSortalAncestors()->size() > 1)->asSet()",

NAMED_ELEMENT__NAME)

//> SubstanceSortalUniversal/inv[1]

Page 71: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

.all('W', '"%s" cannot specialize sortals such as "' + sup.name + '".',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"if specializedUniversal.oclIsKindOf(RigidSortalUniversal) then

specializingUniversals->select(u|u.oclIsKindOf(SubstanceSortalUniversal))

else Set{} endif",

NAMED_ELEMENT__NAME)

//> RigidUniversal/inv[1]

.all('W', '"%s" cannot specialize the anti-rigid "' + sup.name + '".',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"if specializedUniversal.oclIsKindOf(AntiRigidUniversal) then

specializingUniversals->select(u|u.oclIsKindOf(RigidUniversal))

else self->select(false) endif",

NAMED_ELEMENT__NAME)

//> MixinUniversal/inv[1]

.all('W', '"%s" cannot specialize sortals such as "' + sup.name + '".',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"if specializedUniversal.oclIsKindOf(SortalUniversal) then

specializingUniversals->select(u|u.oclIsKindOf(MixinUniversal))

else self->select(false) endif",

NAMED_ELEMENT__NAME)

.inv('E', 'A generalization set containing a phase has to be a partition of phases.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"let children : Set(Universal) = specializingUniversals->asSet() in

if children->exists(u|u.oclIsKindOf(Phase))

then isCovering and children->size() > 1

else true endif")

.all('W', '"%s" cannot be in a generalization set with a phase.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"let children : Set(Universal) = specializingUniversals->asSet() in

if children->exists(u|u.oclIsKindOf(Phase))

then children->select(u|not u.oclIsKindOf(Phase))

else self->select(false) endif",

NAMED_ELEMENT__NAME)

//> UML would ensure: (disjoint) gensets forbid any type inheriting from 2 disjoint types

.all('W', '"%s" cannot be a descendant of two of the disjoint types specified here.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL,

"specializingUniversals->collect(a|

specializingUniversals->excluding(a)->collect(b|

Universal.allInstances()->select(u|u.isConsidered(a) and u.isConsidered(b))

)

)",

NAMED_ELEMENT__NAME)

}

def dispatch BinaryDirectedRelationship(BinaryDirectedRelationship x) {

if(x instanceof CustomSourceRelationship) CustomSourceRelationship(x)

if(x instanceof CustomTargetRelationship) CustomTargetRelationship(x)

}

def CustomSourceRelationship(CustomSourceRelationship x) {

Page 72: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

context(CUSTOM_SOURCE_RELATIONSHIP, x)

.inv('E', 'Maximum cardinality must be positive.',

CUSTOM_SOURCE_RELATIONSHIP__SOURCE_UPPER_BOUND,

"sourceUpperBound > 0 or sourceUpperBound = -1")

.inv('E', 'Cardinality bounds are inverted:' + x.sourceLowerBound + ' > ' + x.sourceUpperBound,

CUSTOM_SOURCE_RELATIONSHIP__SOURCE_LOWER_BOUND,

"sourceUpperBound >= 0 implies sourceLowerBound <= sourceUpperBound")

}

def CustomTargetRelationship(CustomTargetRelationship x) {

context(CUSTOM_TARGET_RELATIONSHIP, x)

.inv('E', 'Maximum cardinality must be positive.',

CUSTOM_TARGET_RELATIONSHIP__TARGET_UPPER_BOUND,

"targetUpperBound > 0 or targetUpperBound = -1")

.inv('E', 'Cardinality bounds are inverted:' + x.targetLowerBound + ' > ' + x.targetUpperBound,

CUSTOM_TARGET_RELATIONSHIP__TARGET_LOWER_BOUND,

"targetUpperBound >= 0 implies targetLowerBound <= targetUpperBound")

}

def dispatch BinaryDirectedRelationship(MeronymicRelation x) {

_BinaryDirectedRelationship(x as BinaryDirectedRelationship)

context(MERONYMIC_RELATION, x)

.inv('E', 'A whole must always have at least 2 parts.',

MERONYMIC_RELATION__PART,

"MeronymicRelation.allInstances()->select(r|r.whole = self.whole).getPartLowerBound()->sum()

>= 2")

}

def dispatch BinaryDirectedRelationship(ComponentOfRelation x) {

_BinaryDirectedRelationship(x as MeronymicRelation)

context(COMPONENT_OF_RELATION, x)

.inv('E', 'Only a functional complex may have components.',

MERONYMIC_RELATION__WHOLE,

"let n : Nature = whole.getNature() in n=Nature::KIND or n=Nature::UNSPECIFIED")

.inv('E', 'A component must be a functional complex.',

MERONYMIC_RELATION__PART,

"let n : Nature = part.getNature() in n=Nature::KIND or n=Nature::UNSPECIFIED")

}

def dispatch BinaryDirectedRelationship(SubQuantityRelation x) {

_BinaryDirectedRelationship(x as MeronymicRelation)

context(SUB_QUANTITY_RELATION, x)

.inv('E', 'Only a sort of quantitiy may have subquantities.',

MERONYMIC_RELATION__WHOLE,

"let n : Nature = whole.getNature() in n=Nature::QUANTITY or n=Nature::UNSPECIFIED")

.inv('E', 'A subquantity must be a sort of quantity.',

MERONYMIC_RELATION__PART,

"let n : Nature = part.getNature() in n=Nature::QUANTITY or n=Nature::UNSPECIFIED")

.inv('E', 'A subquantity is always an essential part (immutable with a rigid whole).',

MERONYMIC_RELATION__PART,

"partIsEssential")

}

def dispatch BinaryDirectedRelationship(SubCollectionRelation x) {

_BinaryDirectedRelationship(x as MeronymicRelation)

context(SUB_COLLECTION_RELATION, x)

.inv('E', 'Only a sort of collective may have subcollectives.',

MERONYMIC_RELATION__WHOLE,

Page 73: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

"let n : Nature = whole.getNature() in n=Nature::COLLECTIVE or n=Nature::UNSPECIFIED")

.inv('E', 'A subcollective must be a sort of collective.',

MERONYMIC_RELATION__PART,

"let n : Nature = part.getNature() in n=Nature::COLLECTIVE or n=Nature::UNSPECIFIED")

}

def dispatch BinaryDirectedRelationship(MembershipRelation x) {

_BinaryDirectedRelationship(x as MeronymicRelation)

context(MEMBERSHIP_RELATION, x)

.inv('E', 'Only a sort of collective may have members.',

MERONYMIC_RELATION__WHOLE,

"let n : Nature = whole.getNature() in n=Nature::COLLECTIVE or n=Nature::UNSPECIFIED")

.inv('E', 'A member must be a sort of collective or a functional complex.',

MERONYMIC_RELATION__PART,

"let n : Nature = part.getNature() in n=Nature::KIND or n=Nature::COLLECTIVE or

n=Nature::UNSPECIFIED")

.inv('E', 'The member is essential, so the whole must be extensional.',

MERONYMIC_RELATION__WHOLE,

"partIsEssential implies whole.isExtensionalCollective()")

}

def dispatch BinaryDirectedRelationship(BinaryMaterialRelation x) {

_BinaryDirectedRelationship(x as BinaryDirectedRelationship)

context(BINARY_MATERIAL_RELATION, x)

.inv('W', 'The material relation cannot be optional for the source (check the relator "' +

x.derivedFrom + '").',

CUSTOM_SOURCE_RELATIONSHIP__SOURCE_LOWER_BOUND,

"sourceLowerBound>=1")

.inv('W', 'The material relation cannot be optional for the target (check the relator "' +

x.derivedFrom + '").',

CUSTOM_TARGET_RELATIONSHIP__TARGET_LOWER_BOUND,

"sourceLowerBound>=1")

}

def nAryMaterialRelation(nAryMaterialRelation x) {

context(NARY_FORMAL_RELATION, x)

.inv('E', 'The material relation cannot be optional for the participant (check the relator "' +

x.derivedFrom + '").',

NARY_FORMAL_RELATION__SOURCE_LOWER_BOUND,

"sourceLowerBound->forAll(x|x>=1)")

}

}

Page 74: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Appendix C – Complete Syntax of the CLIFO Language

The diagram below represents the syntax of the CLIFO language. It was generated from the "Clifo.xtext" file.

Page 75: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 76: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 77: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 78: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 79: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 80: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 81: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 82: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 83: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 84: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor
Page 85: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

Appendix D – CLIFO Validator

The file "ClifoValidator.xtend", containing the validator class that uses an OCL interpreter to impose constraints over CLIFO, is below. This class ensures that the modeler is manipulating the model classes correctly in the constraints, as discussed in the section 3.2, item "Conformance of semantics". It is also responsible for calling the OntoUMLPrime validator of appendix B.

package br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.validation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.BinaryDirectedRelationship

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.ExternallyDependentUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.GeneralizationSet

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.IntrinsicMomentUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.RelatorUniversal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.Universal

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.nAryMaterialRelation

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.util.DynOCL

import br.ufes.inf.nemo.ontouml.PrimeOntoUML.validation.OntoUMLPrimeConstraints

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.CastFunction

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.ClifoFile

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.ClifoLanguages

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.IntrinsicFunction

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.IteratedIndividual

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.PartsFunction

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.RelatedFunction

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.WholesFunction

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.ontoprime.IteratedUniversal

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.ontoprime.Recognition

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.ontoprime.StaticDistinction

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.ontoprime.Status

import org.eclipse.emf.ecore.EStructuralFeature

import org.eclipse.xtext.validation.Check

import static br.ufes.inf.nemo.ontouml.PrimeOntoUML.PrimeOntoUMLPackage.Literals.*

import static br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.clifo.ClifoPackage.Literals.*

import static br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.ontoprime.OntoprimePackage.Literals.*

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.ontoprime.SubroleDistinction

import br.ufes.inf.nemo.ontouml.ontoumlprime.clifo.ontoprime.AutomaticSortDistinction

class ClifoValidator extends AbstractClifoValidator {

//=== DYNOCL WRAPPER FOR THIS CLASS ===

new() {

val ocl = new DynOCL {

val char I = 'I' val char W = 'W'

override display(char severity, String message, EStructuralFeature where) {

if (severity == I) ClifoValidator.super.info(message, where)

else if(severity == W) ClifoValidator.super.warning(message, where)

else ClifoValidator.super.error(message, where)

}

override internalError(String message, EStructuralFeature where) {

Page 86: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

ClifoValidator.this.internalError(message, where)

}

}

onto = new OntoUMLPrimeConstraints(ocl)

}

val OntoUMLPrimeConstraints onto

def internalError(String message, EStructuralFeature where) {

super.info('[CLIFO INTERNAL ERROR] ' + message, where)

}

//=== CLIFO HEADER VALIDATION ===

@Check def inv(ClifoFile x) {

if(x.version>0)

super.warning('Not compatible with versions greater than 0.', CLIFO_FILE__VERSION)

}

@Check def inv(ClifoLanguages x) {

if(x.concepts!='OntoUMLPrime')

super.warning('Not compatible with this metamodel. Use OntoUMLPrime.',

CLIFO_LANGUAGES__CONCEPTS)

if(x.constraints!='CLIF')

super.warning('Not compatible with this language for the constraints. Use CLIF.',

CLIFO_LANGUAGES__CONSTRAINTS)

}

//=== ONTOUMLPRIME VALIDATION ===

@Check def inv(Universal x) { onto.Universal(x) }

def inv(GeneralizationSet x) { onto.GeneralizationSet(x) }

@Check def inv(BinaryDirectedRelationship x) { onto.BinaryDirectedRelationship(x) }

@Check def inv(nAryMaterialRelation x) { onto.nAryMaterialRelation(x) }

//=== SUBCLASSIFICATION CHECKS ===

@Check def inv(StaticDistinction x) {

inv(x as GeneralizationSet)

if(x.hasValidTypes) return;

super.error('A static distinction does not deal with non-rigid types.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL)

}

@Check def inv(AutomaticSortDistinction x) {

inv(x as GeneralizationSet)

if(x.hasValidTypes) return;

super.error('An automatic distinction specializes only non-rigid mixin types.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL)

}

@Check def inv(SubroleDistinction x) {

inv(x as GeneralizationSet)

if(x.hasValidTypes) return;

super.error('A subrole distinction should imply an inherited mediation from a sortal role.',

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL)

}

@Check def inv(Status x) {

inv(x as GeneralizationSet)

if(x.hasValidTypes) return;

super.error('A status of a substantial type has to be a partition of phases.',

Page 87: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

GENERALIZATION_SET__SPECIALIZED_UNIVERSAL)

}

@Check def inv(Recognition x) {

inv(x as GeneralizationSet)

if(x.hasValidTypes) return;

val children = x.specializingUniversals

if(children.size == 1) super.error('The specializing type '

+ children.get(0).name.quoteName + 'in this recognition needs to be mediated by the relator '

+ x.recognizedWith.name.quoteName +'specified.', GENERALIZATION_SET__SPECIALIZED_UNIVERSAL)

else super.error('The specializing types in this recognition need to be mediated by the relator '

+ x.recognizedWith.name.quoteName +'specified.', GENERALIZATION_SET__SPECIALIZED_UNIVERSAL)

}

//=== CLIF BINDINGS ===

def private quoteName(String name) {

if(name == null) '' else '"' + name + '" '

}

@Check def inv(IteratedIndividual i) {

val v = i.value

try {

val type = v.universal

if(v instanceof IteratedUniversal) {

if (type instanceof IntrinsicMomentUniversal)

super.error('Needs to specify the individual that contains the intrinsic "' + type.name +

'". Use a "of as" declaration for the intrinsic individual.',

INDIVIDUAL_DECLARATION__NAME)

}

} catch(IllegalArgumentException e)

super.error('' + i.name.quoteName + 'cannot iterate on itself', INDIVIDUAL_DECLARATION__NAME)

catch(Exception e)

super.warning('Type of individual ' + i.name.quoteName + 'was not found.',

INDIVIDUAL_DECLARATION__NAME)

}

@Check def inv(CastFunction i) {

val individual = i.individual

val concept = i.universal

try if(individual.universal?.name == null) throw null

else onto.context(CAST_FUNCTION, i)

.inv('E', 'Individual ' + individual.declared?.name.quoteName + 'of type "' +

individual.universal.name

+ '" is not convertible to type "' + concept.name + '" specified.',

INDIVIDUAL_FUNCTION__INDIVIDUAL,

"individual.getUniversal().isConvertibleTo(self.getUniversal())")

catch(Exception e)

super.warning('Type of individual ' + individual.declared?.name.quoteName + 'was not found.',

INDIVIDUAL_FUNCTION__INDIVIDUAL)

}

@Check def inv(WholesFunction i) {

val individual = i.individual

try switch(concept : i.universal) {

case individual.universal?.name == null: throw null

default:

onto.context(INTRINSIC_FUNCTION, i)

Page 88: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

.inv('E', 'Individual ' + individual.declared?.name.quoteName + ' of type "' +

individual.universal.name

+ '" cannot be part of the type ' + concept.name.quoteName + 'specified.',

INDIVIDUAL_FUNCTION__INDIVIDUAL,

"individual.getUniversal().isPartOf(self.getUniversal())")

} catch(Exception e)

super.warning('Type of individual ' + individual.declared?.name.quoteName + 'was not found.',

INDIVIDUAL_FUNCTION__INDIVIDUAL)

}

@Check def inv(PartsFunction i) {

val individual = i.individual

try switch(concept : i.universal) {

case individual.universal?.name == null: throw null

default:

onto.context(INTRINSIC_FUNCTION, i)

.inv('E', 'Individual ' + individual.declared?.name.quoteName + ' of type "' +

individual.universal.name

+ '" cannot contain as a part the type ' + concept.name.quoteName + 'specified.',

INDIVIDUAL_FUNCTION__INDIVIDUAL,

"individual.getUniversal().containsPart(self.getUniversal())")

} catch(Exception e)

super.warning('Type of individual ' + individual.declared?.name.quoteName + 'was not found.',

INDIVIDUAL_FUNCTION__INDIVIDUAL)

}

@Check def inv(IntrinsicFunction i) {

//TODO access dimensions of a datatype

val individual = i.individual

try switch(concept : i.universal) {

case individual.universal?.name == null: throw null

IntrinsicMomentUniversal:

onto.context(INTRINSIC_FUNCTION, i)

.inv('E', 'Individual ' + individual.declared?.name.quoteName + ' of type "' +

individual.universal.name

+ '" does not contain the aspect ' + concept.name.quoteName + 'specified.',

INDIVIDUAL_FUNCTION__INDIVIDUAL,

"individual.getUniversal().containsAspect(self.getUniversal())")

default:

super.error('"of" declaration is invalid, because "' + concept.name + '" is not an intrinsic

aspect.',

INDIVIDUAL_FUNCTION__INDIVIDUAL)

} catch(Exception e)

super.warning('Type of individual ' + individual.declared?.name.quoteName + 'was not found.',

INDIVIDUAL_FUNCTION__INDIVIDUAL)

}

@Check def inv(RelatedFunction i) {

val individual = i.individual

try { try switch(i.universal) {

case individual.universal?.name == null: throw null

ExternallyDependentUniversal:

onto.context(RELATED_FUNCTION, i)

.inv('E', 'Individual ' + individual.declared?.name.quoteName + 'of type "' +

individual.universal.name

+ '" does not contain the mediation to ' + i.quaMediation.mediation.targetEndName.quoteName

Page 89: CLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints · PDF fileCLIFO: A Textual Editor for OntoUMLPrime with CLIF constraints Vitória - ES, ... The grammar of the editor

+ 'specified.',

INDIVIDUAL_FUNCTION__INDIVIDUAL,

"individual.getUniversal().isConvertibleTo(self.quaMediation.concept)")

RelatorUniversal: null

}

catch(ClassCastException e)

super.error('Navigation from individual ' + individual.declared?.name.quoteName + switch(u :

individual.universal) {

RelatorUniversal: 'of type "' + u.name + '" needs to specify the mediation with "as ->".'

default: 'of type "' + u.name + '" cannot be linked to a mediation.'

}, INDIVIDUAL_FUNCTION__INDIVIDUAL)

} catch(Exception e) {

super.warning('Type of individual ' + individual.declared?.name.quoteName + 'was not found.',

INDIVIDUAL_FUNCTION__INDIVIDUAL)

}

}

}