The following signature describes the state of a photo-management application:
sig ApplicationState {
catalogs: set Catalog,
catalogState: catalogs -> one CatalogState
}
A signature, of course, creates a set. In this case, it creates a set of ApplicationStates:
ApplicationState0
ApplicationState1
...
catalogs is a field. It maps each ApplicationState to a set of Catalog values:
ApplicationState0, Catalog0
ApplicationState0, Catalog1
ApplicationState1, Catalog0
...
catalogState is also a field. It maps each ApplicationState to a relation. The relation is:
catalogs -> one CatalogState
That relation says: Map each value of catalogs to one CatalogState value. We already saw catalogs, which I'll repeat here:
ApplicationState0, Catalog0
ApplicationState0, Catalog1
ApplicationState1, Catalog0
...
So, the relation says to map each of those tuples to one CatalogState, like so:
ApplicationState0, Catalog0, CatalogState0
ApplicationState0, Catalog1, CatalogState0
ApplicationState1, Catalog0, CatalogState0
...
Okay, back to catalogState. Earlier we said that it maps each ApplicationState to a relation, and we just saw what that relation is. So, I believe that catalogState denotes a relation with arity=4, like so:
ApplicationState0, ApplicationState0, Catalog0, CatalogState0
ApplicationState0, ApplicationState0, Catalog1, CatalogState0
ApplicationState0, ApplicationState1, Catalog0, CatalogState0
...
But, when I run the Alloy Evaluator, it says that catalogState is a ternary relation. My takeaway from this example is:
Usually a field name denotes a relation.
A field name used in an arrow expression does not denote a relation. Rather, it denotes column 2 of the relation (the range of the relation).
Is that right? Where is this explained in the Software Abstractions book?
Section 4.2.2 of Sofware Abstractions (p. 97 in the second edition) begins
Relations are declared as fields of signatures.
That addresses at least part of your question, I think. (I think it may be helpful to work through the index entries for 'field' and relation and read every section they point to.)
You say
A field name used in an arrow expression does not denote a relation. Rather, it denotes column 2 of the relation (the range of the relation).
It may sound pedantic, but no: field names always denote relations. Within the context of a signature declaration however, they are implicitly prefixed with this., which removes the first column of the relation. In your declaration catalogState: catalogs -> one CatalogState, the reference to catalogs is indeed a reference to a binary relation over ApplicationState and Catalog. In this context, however, it's silently expanded to this.catalogs, which evaluates to a set of Catalog individuals. The keyword this is introduced in section 4.2.2 of Software Abstractions.
The cardinality constraints on declarations may also be a complicating factor in your example; I won't try to explain their effect here. I'll only say that when I have run into problems with cardinality constraints, I have often found that a very careful reading of the relevant parts of the language reference in Appendix B has generally sufficed to let me understand what was going on. (I admit that sometimes it has taken more than one reading.)
Related
I have to indicate for the Employee class that each employee can be clearly identified by his personal number. I do not know if I think too complicated, because I have no real idea.
Attributes:
final int personelNumber
...
You don't even need an OCL constraint to express that in UML.
There is a property isID on the Property metaclass that ensures this:
From UML 2.5 specification ยง 9.5.3 (p. 111)
A Property may be marked, via the property isID, as being (part of)
the identifier (if any) for Classifiers of which it is a member. The
interpretation of this is left open but this could be mapped to
implementations such as primary keys for relational database tables or
ID attributes in XML. If multiple Properties are marked as isID
(possibly in generalizing Classifiers) then it is the combination of
the (Property, value) tuples that will logically provide the
uniqueness for any instance. Hence there is no need for any
specification of order and it is possible for some of the Property
values to be empty. If the Property is multivalued then all values are
included.
The notation for this property is similar to that of other constraints
using
{id} after the name and type of the attribute
You don't provide your metamodel, and clearly wrt to each Employee their personelNumber is single valued and so necessarily unique. Presumably it is within some scope such as a Company that the personelNumber should be unique, so the answer is often something like.
context Company
inv UniquePersonelNumber: employees->isUnique(personelNumber)
Two alternative OCL expressions can be found in the following question:
Why allInstance not for isUnique?
In your case, it would be:
context Employee
inv personalNumberUnique : Employee.allInstances() -> isUnique(personalNumber)
Through searching I found that in UML, aggregation(assuming that it's used properly) can be used to represent attributes in a class.
For example,
(Assume column can stand alone)
Then, using such example, if I want to replace the attribute: Column[] with map to represent the column's name, would it be correct to use an association class just like below? (In case, I'm not willing to put the column name in Column class as an attribute)
Association classes are used with simple associations. They have m-1-1-n multiplicity. The shared aggregation (as you used) has no defined semantics (and I recommend to simply not use it unless you have a domain specific and documented use for it). It's simply better to put the intended multiplicity on either side of an association.
An association class connects two classes, adding attributes and/or operations. Your example is "unconventional" since Table/Column have a simple relation which would not need an association class. A general example is the Student/Lecture relation where you can put an association class in between to record exam results, times etc.
Yes, I think that is a valid way of modelling the fact that you have some sort of key string that can be used to identify a Column of this Table.
Using a Map is one if the many possible implementations, so it's not a real equal to.
The advantage of modelling using the Association Class is that your model remains at the more abstract functional level and leaves out implementation details.
BTW. I would use a composition instead of an aggregation for the association between Table and Column, as there is an obvious strong ownership relation and life-cycle dependency between the two.
If you want to replace the attribute Column[] with map to represent the column's name and you are not willing to put the column name in Column class as an attribute and assuming that you want to follow UML specification precisely then you'll produce the model shown below:
Map<Key, Value> is usually understood as an associative container that contains key-value pairs Map.Entry<Key, Value> with unique keys. The container is modeled by the directional aggregation from Map<Key, Value> to Map.Entry<Key, Value>.
Map<Key, Value> and Map.Entry<Key, Value> are templates. Clause 7.3.3.1 of UML specification says that:
A template cannot be used in the same manner as a non-template Element of the same kind. The template Element can only be used to generate bound Elements or as part of the specification of another template.
According to clause 7.3.3.3:
A TemplateBinding is a relationship between a TemplateableElement and a template that specifies the substitutions of actual ParameterableElements for the formal TemplateParameters of the template.
Thus we have two bound elements that have TemplateBinding (marked by <> keyword) relationships with their templates:
ColumnNames which essentially is the name for Map<String, Column>
ColumnName which essentially is the name for Map.Entry<String, Column
According to clause 11.5.1 of the UML specification:
An Association classifies a set of tuples representing links between typed instances. An AssociationClass is both an Association and a Class.
ColumnName is AssociationClass representing the link between instances of String and Column classes. We use notation from clause 11.5.5, figure 11.35 to express that.
Finally, the directional composition association between Table and ColumnNames classes tells us that each instance of Table owns an instance of ColumnNames, i.e. set of column names.
Note that while ColumnNames and ColumName classes are usually hidden from the end-user by an implementation, they nevertheless exist.
I used BoUML to draw the diagram.
A few days ago a friend pointed out to me that I had a wrong idea of composition in UML. She was completely right, so I decided to find out what more I could have been wrong about. Right now, there is one more thing that I have doubts about: I have a circular dependency in my codebase that I would like to present in UML form. But how.
In my case the following is true:
Both A and B have a list of C
C has a reference to both A and B to get information from.
C cannot exist if either A or B stops to exist
Both A and B remain to exist after C is deleted from A and/or B
To model this, I've come up with the following UML (I've ommited multiplicities for now, to not crowd the diagram.)
My question is, is this the right way to model such relations?
Problems
Some facts to keep in mind:
Default multiplicity makes your model invalid. A class may only be composed in one other class. When you don't specify multiplicity, you get [1..1]. That default is sad, but true.
The UML spec doesn't define what open-diamond aggregation means.
Your model has many duplicate properties. There is no need for any of the properties in the attribute compartments, as there are already unnamed properties at the ends of every association.
Corrections
Here is a reworking of your model to make it more correct:
Notice the following:
The exclusive-or constraint between the associations means only one of them can exist at a time.
Unfortunately, the multiplicities allow an instance of C to exist without being composed by A or B. (See the reworked model below.)
The property names at the ends of all associations explicitly name what were unnamed in your model. (I also attempted to indicate purpose in the property names.)
The navigability arrows prevent multiple unwanted properties without resorting to duplicative attributes.
Suggested Design
If I correctly understand what your model means, here is how I would probably reverse the implementation into design:
Notice the following:
Class D is abstract (the class name is in italics), meaning it can have no direct instances.
The generalization set says:
An instance cannot be multiply classified by A and B. (I.e., A and B are {disjoint}.)
An instance of D must be an instance of one of the subclasses. (I.e., A and B are {complete}, which is known as a covering axiom.)
The subclasses inherit the ownedC property from class D.
The composing class can now have a multiplicity of [1..1], which no longer allows an instance of C to exist without being composed by an A or a B.
Leave away the open diamonds and make them normal associations. These are no shared aggregations but simple associations. The composite aggregations are ok.
In general there is not much added value in showing aggregations at all. The semantic added value is very low. In the past this was a good hint to help the garbage collection dealing with unneeded objects. But nowadays almost all target languages have built-in efficient garbage collectors. Only in cases where you want an explicit deletion of the aggregated objects you should use the composite aggregation.
Suppose I have A ---r1 {bag} [1..2]--> B in a UML class diagram (that is, r1 is an association from A to B and is annotated with {bag} and multiplicity [1..2].
My Question: if a:A is an instance of A, is the following collection valid?
a.r1={(b1,1),(b1,2),(b2,1)} //collection contains two copies of b1 and one b2
In other words, multiplicity bounds (i.e., [1..2]) apply to the association when it is interpreted purely as r1:A --> B, or it applies to r1: A --> Bag(B)? In the former interpretation, the above collection is valid, since r1 contains at most two instances of B, but in the latter it is not, since r1 contains three elements of Bag(B)! which interpretation is correct?
Multiplicity constraints in UML are explained in Chapter 7.5.3 of UML document as I am referred to in this question.
p.s.1: A similar question arises when we substitute {bag} with {seq}.
p.s.2: I added haskell tag to get comment from large haskell community here as #xmojmr suggested. Thanks to #peter that nicely draw the pictures in his answer.
As stated in specs, Bag is unordered, nonunique collection.
However this describes the relation between the elements you are pointing to.
So your example can be expressed in either way:
This means that A has reference to one to two B instances, and those references are stored in a Bag (or any nonunique, unsorted collection; but that is implementation detail).
To answer your question: no, because the Bag contains three instances of B, whilst the allowed maximum is two B's.
An association defines a semantic relationship between classifiers. The instances of an association are a set of tuples relating instances of the classifiers. Eachtuple value may appear at most once. The Association represents a set of connections among instances of the Classifiers. An instance of an Association is a Link, which is atuple of Instances drawn from the corresponding Classifiers
I wonder if there is someone helps me understand every word of the association definition especially the highlighted ones?because I read about it from different resources but all of them say the same words but I would like a more elaborated definition
semantic relationship
This means there's a structural relationship between the things being associated that arises from the problem space. For example: the association Person owns Dog. In a dog licensing application, this relationship is the central concept; the application exists to manage the links between people and dogs. It's a 'semantic' relationship because it has meaning which originates from the problem space.
set of tuples relating instances of the classifiers
A tuple is 'an ordered set of elements' (wikipedia). An example of the Dog-Ownership association could be ("Fido", "Fred") where "Fido" represents a Dog and "Fred" a Person. An association can be represented as a set of tuples in that there is one tuple for each combination of Dog & Person for which the relation holds; e.g.
[("Fido", "Fred"), ("Angel", "Chuck Norris"), ("Boatswain", "Lord Byron")]
Note there are no tuples for pairs where the relationship doesn't hold; e.g. ("Fido", "Lord Byron").
each tuple value may appear at most once
It's not possible for the set to contain duplicates as this would just be saying the same thing twice. So there's no point adding ("Fido", "Fred") again to the list above; we already know Fred owns Fido.
The Association represents a set of connections among instances of the Classifiers
This is just another way to think about the relationship. For each tuple in the set, you can think of a link - or connection - between the related objects.
An instance of an Association is a Link, which is a tuple of Instances
See above. Each tuple represents one linked pair of objects. Links are to Associations as Objects are to Classes. Classes have many objects; Associations have many Links.
Fundamentally associations exist to show where things are systematically linked to other things. Tuples and sets are a way to think about and/or represent those linked things. (In fact I'd quibble somewhat with the definition in your OP: the links in an association can be represented as as a set of tuples: but that's not what they are, it's how they're modelled. The same information could equally be modelled by a Graph, where each object was represented by a vertex (node) and each association an edge.
hth.
EDIT:
Responding to your questions. Looks like you understand it pretty well; some observations.
First, here's how I would model it:
Now to each of your points:
Name: is the name of Association relationship(optional,you can give it a name or not)
I prefer verb phrase based naming as it brings out the meaning of the relationship. My model can be read directly as:
Each Person owns many Dogs (where 'many' means 0 or more)
Each Dog is owned by exactly one Person
Doing so removes the need to name the association explicitly, although you can still do so if you want.
visibility(I am not care about it,at least for now, I didn't realize its importance until now).
I would agree. Personally, I never annotate models with visibility.
Name:(here is the name of MemberEnd ),so,I left its default name in the screenshot
See comment about association naming above. I prefer verb-based naming to role-based: 'owns' is much more explicit in describing the purpose of a relationship than naming the association end 'dog' or 'dogs'.
the owner of memberEnd [...]
Personally: I don't use this. There's a whole other discussion about this that tbh I don't believe has a material impact in most cases.
Navigable [...]
Again I don't use this personally. In reality navigability should be derived from the underlying behaviour. Does it require navigating one way/both? Then set navigability accordingly. However some people like to specify it explicitly, on basis it makes the implementation clearer (If only navigable one way it can be implemented with reference(s) in one class only; if bi-directional it needs references in both directions - with attendant logic to keep things consistent).
Multiplicity
I agree with your selection.
Hope that helps.