🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
VerbalizePatterns
This page was created by Hans.karlsen on 2019-08-04. Last edited by Wikiadmin on 2026-07-29.

You can customize how OCL expressions are described in plain language by editing the verbalization pattern file downloaded from MDriven Designer.

What verbalization patterns do

A verbalization pattern maps a recognized part of an OCL expression to descriptive text. MDriven Designer uses these patterns when it verbalizes an expression, such as an attribute access, link navigation, iteration, operation, constant, or variable.

For example, the default attribute pattern:

[ATTRIBUTE:<NAME>:<T>] '''* take the attribute <NAME> that has the type <T>

can describe an attribute named Name as: take the attribute Name that has the type System.String.

Use verbalization to make a complex expression easier to review, document, or explain. It describes the expression; it does not change how the expression evaluates.

Get and edit a pattern file

Download the verbalization pattern from MDriven Designer, edit a copy, and use the edited file as the pattern for verbalization. The downloaded content starts with STARTMARKER and contains the built-in pattern entries.

When you customize a pattern:

  1. Keep STARTMARKER at the start of the file.
  2. Keep one pattern entry per line, except where you intentionally include line breaks in the translated text.
  3. Preserve placeholders such as <NAME>, <T>, and <ARG_1> when you want their resolved values to appear in the description.
  4. Make the pattern signature unique. If more than one entry can match, MDriven uses the first occurrence.
  5. Test the changed pattern against an expression of the matching kind.

Gotcha: The available source material does not state the Designer menu or button used to download or load the pattern. Confirm the current UI path in your installed MDriven Designer version.

Pattern entry format

Each entry has two parts separated by three asterisks, with a space on each side:

[pattern signature] '''* verbalized text

The part before * identifies the expression structure to match. The part after * is the text that MDriven emits.

[OPERATION:first:<T>] '''* take the first object

In this example, OPERATION identifies the expression kind, first is the operation name, and <T> accepts the result type. The phrase take the first object is the resulting verbalization.

Matching order

The signature before * must be unique. MDriven uses the first matching occurrence. Put a more specific pattern before a general fallback pattern.

For example, keep a specific operation signature before the generic one-argument operation pattern:

[OPERATION:oclisinstate:(<ARG_1>):System.Boolean] '''* and object is in state: <ARG_1>
[OPERATION:<NAME>:(<ARG_1>):<T>] '''* apply operation <NAME> with argument <ARG_1>, it will return a value of type <T>

Placeholders

Placeholders are replaced with information from the expression being verbalized.

Placeholder Meaning in a pattern Example use
<NAME> Name of an attribute, link, operation, variable, or type. take the attribute <NAME>
<T> Type of the result or referenced value. of type <T>
<COLLECTION(T)> A collection whose element type is T. list of <T> objects
<ARG_1>, <ARG_2> First and second argument expressions. with argument <ARG_1>
<ARG_N0> First argument in a variable-length argument list. See variable-length argument lists.
<ARG_NMINUS1> Argument immediately before the last argument in a variable-length argument list. See variable-length argument lists.
<ARG_N> Last argument in a variable-length argument list. See variable-length argument lists.
<LOOPVARNAME> Name assigned to the current item in an iteration. current object <LOOPVARNAME>
<LOOPVARTYPE> Type of the iteration variable. of type <LOOPVARTYPE>
<CONSTVALUE> Literal value of a constant. <CONSTVALUE> (of type <T>)
<LETASSIGNEXP> Expression assigned by a let expression. result of <LETASSIGNEXP>
<LETACTEXP> Expression evaluated using the let variable. in this expression: <LETACTEXP>

Variable-length argument lists

Use <ARG_N0>, <ARG_NMINUS1>, and <ARG_N> for an operation or iteration with more than two arguments and an unknown number of arguments.

[OPERATION:<NAME>:(<ARG_N0>,<ARG_NMINUS1>,<ARG_N>):<T>] '''* Execute the method <NAME> with argument <ARG_N0>, <ARG_NMINUS1> and <ARG_N>; get a result of type <T>

<ARG_N0> represents the first argument, <ARG_NMINUS1> represents the argument before the last, and <ARG_N> represents the last. Separators written between these placeholders are retained and repeated for intervening arguments.

Default pattern entries

The following entries are the supplied default pattern set. You can use them as a baseline and change the text after * to match your documentation style.

Context, links, attributes, and types

[SELF:<NAME>:<T>] '''* From the current context (of type <T>)
[MULTI:<NAME>:<COLLECTION(T)>] '''* take the multilink named <NAME> that holds objects of type <T>
[SINGLE:<NAME>:<T>] '''* take the singlelink named <NAME> that has an object of type <T>
[LOOPVAR:<NAME>:<LOOPVARNAME>:<T>] '''* current object of iteration <LOOPVARNAME> of type <T>
[ATTRIBUTE:<NAME>:<T>] '''* take the attribute <NAME> that has the type <T>
[TYPE:<NAME>:<T>] '''* From type <NAME>

Collections and iterations

[OPERATION:allinstances:<COLLECTION(T)>] '''* Take all existing objects
[ITERATION:select:<LOOPVARNAME>:<LOOPVARTYPE>:(<ARG_1>):<COLLECTION(T)>] '''* filter the list by going over all objects; in each iteration call the current object <LOOPVARNAME> and check <ARG_1>; keep the objects that evaluate to true; the result is a reduced list of objects of <T>
[ITERATION:foreach:<LOOPVARNAME>:<LOOPVARTYPE>:(<ARG_1>):<COLLECTION(T)>] '''* for each item, call the current object <LOOPVARNAME> and do the following: <ARG_1>; the incoming list of objects of <T> is returned
[ITERATION:exists:<LOOPVARNAME>:<LOOPVARTYPE>:(<ARG_1>):System.Boolean] '''* return true if the criteria <ARG_1> is met at least once for items in the list called <LOOPVARNAME>
[ITERATION:collect:<LOOPVARNAME>:<LOOPVARTYPE>:(<ARG_1>,<ARG_2>):<COLLECTION(T)>] '''* collect <ARG_1> and <ARG_2> and build a list of a new resulting tuple type <T>
[ITERATION:collect:<LOOPVARNAME>:<LOOPVARTYPE>:(<ARG_N0>,<ARG_NMINUS1>,<ARG_N>):<COLLECTION(T)>] '''* collect the following arguments <ARG_N0>, <ARG_NMINUS1>, and <ARG_N> and build a list of a new resulting tuple type <T>
[ITERATION:<NAME>:<LOOPVARNAME>:<LOOPVARTYPE>:(<ARG_1>):<COLLECTION(T)>]
[LISTCOERCION:<NAME>:(<ARG_1>):<T>] '''* _
[LISTCOERCION:<NAME>:(<ARG_1>):<COLLECTION(T)>] '''* _

A select entry describes filtering. For a collection of customers, a predicate that tests each customer is verbalized as going through each current customer, evaluating the predicate, and keeping customers for which it is true.

Constants, variables, and let expressions

[CONST:<NAME>:<CONSTVALUE>:<T>] '''* <CONSTVALUE> (of type <T>)
[CONST:<NAME>:<CONSTVALUE>:<Enum Literal>] '''* <CONSTVALUE>
[VAR:<NAME>:System.Boolean] '''* value of <NAME>
[VAR:<NAME>:<T>] '''* <NAME>
[VAR:selfVM:<T>] '''* selfVMXXX
[VAR:<NAME>:<COLLECTION(T)>] '''* <NAME> is a list of <T> objects
[LET:<NAME>:<LOOPVARTYPE>:<LETASSIGNEXP>:<LETACTEXP>:<T>] '''* let <NAME> represent the result of <LETASSIGNEXP> in this expression: <LETACTEXP>
[LET:<NAME>:<LOOPVARTYPE>:<LETASSIGNEXP>:<LETACTEXP>:<COLLECTION(T)>] '''* let <NAME> represent the result of <LETASSIGNEXP> in this expression: <LETACTEXP>

A let pattern describes both parts of the expression: the value assigned to the named variable and the expression that uses that variable.

Operations and comparisons

[OPERATION:>:(<ARG_1>):<T>] '''* if it is larger (>) than <ARG_1>
[OPERATION:<:(<ARG_1>):<T>] '''* check if it is smaller (<) than <ARG_1>
[OPERATION:or:(<ARG_1>):<T>] '''* or (or) the following is true: <ARG_1>
[OPERATION:and:(<ARG_1>):<T>] '''* and (and) also the following is true: <ARG_1>
[OPERATION:first:<T>] '''* take the first object
[OPERATION:<NAME>:(<ARG_1>):<T>] '''* apply operation <NAME> with argument <ARG_1>, it will return a value of type <T>
[OPERATION:<NAME>:<T>] '''* run the operation <NAME>, it will return a value of type <T>
[OPERATION:if:(<ARG_1>,<ARG_2>):<T>] '''* if true then <ARG_1> else <ARG_2>
[OPERATION:if:(<ARG_1>,<ARG_2>):<COLLECTION(T)>] '''* if true then <ARG_1> else <ARG_2>
[OPERATION::=:(<ARG_1>):<T>] '''* and assign it to the result of <ARG_1>
[OPERATION:=:(<ARG_1>):<T>] '''* and check if it is equal to <ARG_1>
[OPERATION:<>:(<ARG_1>):System.Boolean] '''* is NOT equal to <ARG_1>
[OPERATION:;:(<ARG_1>):<T>] '''* . <ARG_1>
[OPERATION:not:System.Boolean] '''* avoid all that match
[OPERATION:oclsingleton:<T>] '''* Get the singleton object of type <T>
[OPERATION:isnull:System.Boolean] '''* is not assigned a value (null)
[OPERATION:notnull:System.Boolean] '''* is assigned a value (not null)
[OPERATION:+:(<ARG_1>):System.String] '''* append <ARG_1> to the string
[OPERATION:<NAME>:(<ARG_1>,<ARG_2>):<T>] '''* Execute the method <NAME> with argument <ARG_1> and <ARG_2>, and get a result of type <T>
[OPERATION:<NAME>:(<ARG_N0>,<ARG_NMINUS1>,<ARG_N>):<T>] '''* Execute the method <NAME> with argument <ARG_N0>, <ARG_NMINUS1>, and <ARG_N>; get a result of type <T>

State tests

[OPERATION:oclisinstate:(<ARG_1>):System.Boolean] '''* and object is in state: <ARG_1>
[OPERATION:oclisinstate:(<ARG_1>):System.Boolean].[CONST:<NAME>:<CONSTVALUE>:<Enum Literal>] '''* test1<CONSTVALUE>
[CONST:<NAME>:<CONSTVALUE>:<Enum Literal>].[OPERATION:oclisinstate:(<ARG_1>):System.Boolean] '''* test2<CONSTVALUE>
[OPERATION:oclisinstate:(<[CONST:<NAME>:<CONSTVALUE>:<Enum Literal>]>):System.Boolean] '''* test3<CONSTVALUE>
[OPERATION:oclisinstate:([CONST:<NAME>:<CONSTVALUE>:<Enum Literal>]):System.Boolean] '''* test4<CONSTVALUE>

The first oclisinstate entry is the general state-test wording. The remaining entries are supplied matching variants for expressions involving enum literals. Replace the test1 through test4 text with meaningful wording if those variants are used in your model.

Customization example

To use shorter language for a single link, change only the translation text and retain its signature and placeholders:

[SINGLE:<NAME>:<T>] '''* follow <NAME> to one <T>

An expression that navigates a single link named Country to a Country object is then described as follow Country to one Country.

Do not change it to a broad signature that could also match a multi-link. Keep the single-link and multi-link entries separate so MDriven can select the intended wording.

See also