How to start your first ATML3 training

Aug 17 2015

First steps writing your ATML3 trainings

We are happy that you are using the AX Semantics platform and ATML3, the Automated Text Markup Language (version) 3. In this tutorial we'll show you some first steps to create an ATML3 training.

The things you need:

  1. Credentials for our self-service platform (myAX): username and password;

  2. Credentials for our training database and editor: username and password;

  3. The ATML3 Training Editor downloaded from [].

If you're missing your credentials or if this tutorial is not working for you, please do not hesitate to ask for help via mail using

Signing in to myax:

Go to the website and use your username and password to log in (or register for free). There you can see our brand new dashboard functionality which looks like this:

View of the dashboard

Click on the button which states "You have 1 active content project" and you will get to the content project list.

View of the content project list in myAX

If you've already uploaded some data, you should find your data after clicking on the active content project.

View of your things in the content project

Use this view to edit one of the data items by clicking on it and then hitting the button "edit this object".

View of a thing in a content project

In this view you can see the data and the generated stories of your objects.
Now it's time to start up the training editor.

The ATML3-Training Editor

In the previous ATML3 tutorial we showed how to set up the ATML3-Training Editor. You can download the tool from our website The jar can be directly executed but requires Java 8 (update 45) or a newer version of Java. When you open the app it will look like this:

atml3 editor opened

If you haven't done this already please enter your credentials using the AX-Backend menu und choose the option "Training settings" to enter your credentials.

training api settings in the menu

Download the blank engine training we have prepared for you.

open training menu open tranining dialog

The editor window should open.

opened training in the atml3 editor

Let's build a small training now that consists of two sentences.

The first sentence

Click the "Sentences" tab and use the "Add" button to add a new sentence.

add sentence

Set the base data for the sentence by clicking on it. We will choose use the "Auto" trigger for this sentence which means that it will always appear in the text. Next, open the dropdown "Variants for de-DE" in order to create a new "variant".

sentence base data variants opened

If you have multiple variants for a sentence, the one to appear in the text will be selected randomly. Use this feature if you want to make your stories more variant.

The next step is entering a sentence to appear in the text.

Writing a sentence variant

enter sentence variant

We want to get a sentence like:

  • Gestern wurden 15 Vorfälle angelegt.
  • Gestern wurde 1 Vorfall angelegt.

The verb of the sentence has to react to the data - the number of events ("Vorfälle"). We will later define a "property" called "DATA_num_new_events".

In this sentence, we will just print the value. We write the container "[DATA_num_new_events.value()]". The verb of the sentence ("werden") and the subject ("Vorfall") have to react to this container's value, becoming singular or plural depending on the value. To be able to inherit grammatical properties from a container, the container needs to have a name, so the final container is "[DATA_num_new_events.value(),id=numEvents]". Note that the id of a container should always be unique within a variant.

The next step is the verb of the sentence. The verb is "werden", so the container to generate this verb is "[G:verb=werden]". The default for verb inflection is third person, so we can skip "person=3rd" as a parameter (which would be "[G:verb=werden,person=3rd]"). Since the container should inherit singular/plural as a grammatical property, it has to reference the value container from before, so the final container is "[G:verb=werden,grammar-from=numEvents]".

The last part of the sentence that has to react to the data is the subject ("Vorfall"). The subject is implemented by using a noun phrase and a property vocabulary. The property is called "VOC_case", so the container to call is "[VOC_case]". Since we want it to react to the grammatical properties of our value container and become plural if necessary, we also use the "grammar-from" parameter on this container: "[VOC_case,grammar-from=numEvents]". On a sidenote, the adjective "neu" does not appear either in the "VOC_case" container: You can add the parameter "adj=yes" to that container making it "[case_voc,grammar-from=numEvents,adj=yes]" to make the adjective appear in the text.

Our first sentence in ATML3 is done. Now it's time to generate the properties for it.

Using the sentence

Now it's time to define the story and actually use the sentence in our final text. In order to do this, use the "Product Types" tab and open the default product type. Then, add the sentence and select it from the list.

product types product type - sentence added

Go to the tab "Properties".

Writing properties

The "VOC_case" property

Every property in ATML3 is made up of three parts:
* the truth value defined by the truth expression which must always be of Boolean value; * the value, defined by the mapping expression; * vocabularies in different languages, probably using the value.

The "truthExpression" makes it possible to use a property as a trigger. A container involving a property will only be rendered if the property becomes true. The "mappingExpression" is evaluated only if the property's truth value is true. It is used to map data into the engine. The vocabularies are used to represent the data mapped by the mapping value.

In the "Properties" tab, click the "New Property" button and create the "VOC_case" property.

case voc property creation

Now we have to define a truth expression. Doubleclick the correct cell of the table and enter a truth expression. In our case we just use the word "true".

truth expression entered for case_voc

The next step is adding the vocabulary. Click on the "de-DE" button to add a vocabulary variant and enter a noun and an adjective. Vocabulary variants are chosen randomly to make your texts more variant.

open de-DE dialog added vocabulary

Now you have created a common type of property, one to render a noun phrase, like: * Vorfall, * Vorfälle, * neue Vorfälle, * die neuen Vorfälle, etc.

We will show you what to do with a property like that later.

The "data" property

The next step is the data property "DATA_num_new_events" which can be created just like the "VOC_case" property. Set the following mapping and truth expressions:

  • "mappingExpression: count(list(#events))",
  • "truthExpression: count(list(#events)) > 0",
  • vocabulary: not needed.

finished result for num events property

We want to access our data, in our case the "#events" property, in our input JSON in the myax object. We have to tell the text-engine that the property has to be interpreted as a list, so a "list()" cast has to be added: "list(#events)". Now, the number of events needs to be considered in the property. The mapping expression has to be altered to "count(list(#events))". Since the truth expression is true only if there is at least one new event, we will compare it to "0": "count(list(#events)) > 0".

You have written a property to access your data in your myax objects.

Putting it all together.

The last thing to do is to save the progress by using the "Save" or "Save as" dialog.

saving the training

We can access the myax platform and generate a text.

generate text

A few seconds later, this is what we get:

myax generated text

Apparently, there is something left to be done: We need to change the verb to past tense.

corrected verb container

We can add the "tense=past" property to our verb, altering the verb container to "[G:verb=werden,grammar-from=numEvents,tense=past]".

Save everything and go back to myax and generate the text. You will be asked if you want to regenerate the text again, please do so.

myax regenerate text

Extending the text

The next step is to write two more sentences to broaden the content covered by the automated texts. The first sentence tells us that there are no critical events and the second sentence tells us how many critical events there have been.

Create a property for that:

In this case, we have a similar construction. We count the elements of a list but we filter the events list, so the correct mapping expression looks like this:

"count(filter(list(#events), { "priority": "Critical" }))"

We create two more logic properties:

  • "LOGIC_has_critical_events",
  • "LOGIC_no_critical_events",

to determine whether there are critical events. In this example, while you access data from the myax through the "#" operator, you can access data in your properties using a "$".

new properties for has or has no events

In the next step, we add some sentences to outline if there have been critical events or not. Add the "LOGIC_has_critical_events" or "LOGIC_no_critical_events" as triggers to the sentences to make only one of them appear:

critical events sentence no critical events sentence corrected sentence

Save and go to myax and regenerate your texts to view your results:

no critical sentence myax one critical myax two criticals myax

That's it - your first steps in creating your own engine training

These are the first steps on creating your engine training. There will be more in detail tutorials on containers, properties and vocabularies as well as multi-language trainings. Come to our slack community ( There, you can share your experience with other people and find our staff members, who are able to help you in every aspect of your ATML3 development. Feel free to ask questions at any time and best wishes for your ATML3 development endeavour.

Category: ATML3 Tagged: tech atml3 tutorial