Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The purpose of a rule is to constrain data. Refer to the chapter about rules in the tutorial for examples and a practice oriented explanation.
A rule statement defines something that should be true. It does not define the enforcement.
A <rule>
has the following syntax:
A <label>
is optional. It can be a single word or a string (enclosed by double brackets) followed by a colon (:
).
An expression can be any of:
Expression BinaryOperator Expression
UnaryOpPre Expression
Expression UnaryOpPost
a (reference to a) relation (including an optional signature, when required to disambiguate):
A relation by name
I
(the Identity relation)
V
(carthesian product) Note that this can also be used to denote the empty relation, by using the unary negation operator: '-v'
A singleton expression (the value of an atom)
an expression enclosed in brackets.
The following operators are available to build expressions:
Binary operators
equivalence: =
composition: ;
inclusion: |-
intersection: /\
union: \/
difference: -
left residual: /
right residual: \
diamond: <>
relative addition: !
cartesian product: #
Unary operator (pre-operator)
complement: -
Unary operators (post-operator)
conversion (flip): ~
Reflexive, transitive closure: *
(Kleene star) --currently not implemented
transitive closure: +
(Kleene plus) --currently not implemented
The meaning of a rule can be written in natural language in the Meaning part of the RULE statement. It is a good habit to specify the meaning! The meaning will be printed in the functional specification. The meaning is optional.
The <text>
part is where the the meaning is written down. We support both:
a simple string, enclosed by double quotes
any text, starting with {+
and ending with -}
The optional language is specified as
IN ENGLISH
or
IN DUTCH
.
The optional Markup is one of :
REST
(Restructured text)
HTML
LATEX
MARKDOWN
If you need specific markup, there are several options to do so. The default markup is used, but you can override that here. We rely on Pandoc to read the markup.
Messages may be defined to give feedback whenever the rule is violated. The message is a predefined string. Every message for a rule should be for another Language.
A violation message can be constructed so that it gives specific information about the violating atoms:
Every segment must be of one of the following forms:
TXT
String
SRC
Expression
TGT
Expression
A rule is violated by a pair of atoms (source, target). The source atom is the root of the violation message. In the message the target atoms are printed. With the Identity relation the root atom itself can be printed. You can use an expression to print other atoms. Below two examples reporting a violation of the rule that each project must have a project leader. The first prints the project's ID, the second the project's name using the relation projectName:
VIOLATION ( TXT "Project ", SRC I, TXT " does not have a projectleader")
VIOLATION ( TXT "Project ", SRC projectName, TXT " does not have a projectleader")
By default rules are invariant rules. By preceding the rule statement with a role specification for this rule, the rule becomes a process rule.
tbd
To facilitate reusing code, Ampersand allows its user to divide code over different files.
The INCLUDE
-statement includes the code of another Ampersand-script or the data of a .xlsx-file into the context.
This statement specifies files that need to be included before compiling. The filename is given in double quotes, including a path that is relative to the position of the main adl-file. The main adl-file is the file that is called with the command Ampersand.
Possible files to include are:
other adl-files
xlsx-files to include population
All code in the included adl-files will become part of the context of the main adl-file.
Make sure to include the adl-files before including xlsx-files.
Included files may contain INCLUDE
statements themselves. The files mentioned there are treated as though they were included in the main file. So their code is also part of the same context. Nested adl-files can have their own xlsx-files included.
For formatting your excel-file see the text on the Excel Importer.
RJ/20161220: the CONTEXT statement is currently being revised. It is expected that this will lead to changes in syntax in the course of 2017.
The data contained in a business system represents a view of (a very small part of) the real world. Ideally, this view must be consistent, meaning that there may be no contradictions within that view. Since different business systems have different ways of viewing the real world, and/or look at different parts of the real world, we need to be able to distinguish between such views. We use the term 'Context' to refer to an individual view. Thus, a Context is defined in terms of concepts, relations and rules, and it consists of atoms and links to populate them.
Any Ampersand model has one context. The model is true within its context and there is no knowledge in a model about other contexts.
The model is specified between the keywords CONTEXT and ENDCONTEXT. A context has a name.
Other models included with the INCLUDE statement become part of the context they are included in.
To tell Ampersand what language your context is in, you can append a language directive to your context. Currently English and Dutch are supported. To do so, directly following the name of your context, you can specify
Where can be ENGLISH
or DUTCH
.
Directly following the optional language definition, you can optionally specify the format of your texts (see PURPOSE statement). Ampersand understands some different markup styles. The default style is REST (Restructured Text)
where can be one of
REST
,
HTML
,
LATEX
,
MARKDOWN
.
(For details on these formats, see pandoc.org).
A concept statement defines a concept in natural language. A concept is a name for similar things. For example: Peter
, John
, and Barack
are things you might want to call Person
, whereas 45-NP-88
and KD-686-D
could be instances of the concept LicensePlate
.
This statement may occur anywhere within a context, either inside or outside a pattern.
This statement means that there exists a concept called <Uppercase identifier>
in the current context.
<Uppercase identifier>
specifies the name of the concept.
String
contains a definition of the concept. This definition is used by the documentation generator, which expects it to be a grammatically correct and complete sentence.
String?
is an (optional) reference to the source of the definition. It is meant for traceability.
The name of a concept starts with an uppercase.
A concept should be used for immutable concepts. E.g. use a concept Person
to express that a person will always be a person and will not change in, let us say, a table. However, don't use Employee
, because termination of an employee's contract causes a person to be an employee no longer. So employees are not immutable. To be an employee is a dynamic property, so model it as a relation.
The description will be printed in the functional specification, so please check that your definition is a complete sentence.
Concepts need not be defined. If you use a concept without a definition, Ampersand defines it for you (regardless of whether you defined it or not).
A relation statement says that there exists a relation in a context. It introduces (defines, declares) the relation in the context. Each relation is a set that contains pairs of atoms. Over time, pairs can be inserted into or deleted from a relation.
A relation statement can have one of the following forms:
The second and third ways will become obsolete in future versions of Ampersand.
All three ways define a relation by its name, its source concept and its target concept. The name of a relation is a single word that starts with a lower case letter. The source and target concepts start with an upper case letter.
A relation statement may occur anywhere inside a context, both inside and outside of a pattern.
The optional <properties>
, <pragma>
, and <meaning>
-parts are discussed in the sequel.
A relation statement means that there exists a relation in the current context with the specified name, source concept and target concept.
The name, source concept and target concept together identify a relation uniquely within its context. As a consequence, the name of a relation does not have to be unique. E.g. name[Book*Name]
can be specified in the same context as name[Person*Name]
. Because they have different source concepts, these are different relations.
The <properties>
-part is meant for writing multiplicity constraints in a comma separated list between square brackets '[' and ']'. E.g. [UNI,TOT]
. The following multiplicity constraints are available:
UNI
(univalent)
INJ
(injective)
SUR
(surjective)
TOT
(total)
SYM
(symmetric)
ASY
(antisymmetric)
TRN
(transitive)
RFX
(reflexive)
IRF
(irreflexive)
PROP
(property)
Let's assume that we want to express that any person can live in one city only. So under this constraint "Joe Smith lives in New York" and "Joe Smith lives in Denver" cannot both be true at the same time.
In relation algebra, we say that the relation is univalent, which means that every atom in the source concept can only be paired with a single atom in the target concept. This is modeled as
A pragma is optional and is characterized by the reserved word PRAGMA
. The PRAGMA
is followed by two or three strings. It is used to construct sentences in natural language, using pairs from the actual population of a relation. A pragma specifies how we speak (in natural language) about any pair in the relation. Ampersand also uses pragmas to generate examples in the functional specification. Example of a pragma with three strings:
To use this pragma on the pair (John,Amsterdam)
results in the sentence "Student John flies the flag of Amsterdam in top."
. The two atoms are fitted in between the three strings. A pragma with two strings is identical to a pragma in which the third string is empty.
(The PRAGMA
keyword will become obsolete in a future version of Ampersand. It will be replaced by the VIEW
-statement which offers more flexibility in composing sentences.)
Example:
The PRAGMA
tells us that it makes sense to utter the phrase "Provider Mario's Pizza's has accepted order 12345."
A meaning is optional and is characterized by the reserved word MEANING
. It specifies the meaning of a relation in natural language. It is is meant to say in natural language what it means for a pair to be in the relation. The meaning is used to generate documentation with and is printed in the functional specification. A <meaning>
has the following form:
The <text>
-part is where the the meaning is written down. We support both:
a string, enclosed by double quotes,
e.g.
any text, starting with {+
and ending with +}
e.g.
The optional <language>
is specified as
IN ENGLISH
or
IN DUTCH
.
Example :
This is a way to override the default language.
Sometimes you need formatting in the meaning, such as dotted lists, italics, or mathematical symbols. For this purpose you have a choice in which syntax you specify the meaning. The optional <markup>
is one of :
REST
(Restructured text)
HTML
LATEX
MARKDOWN
Example :
Ampersand uses Pandoc to offer a choice for your markup. See pandoc.org for details.
To keep this chapter as readable as possible, we have chosen to omit some details that are irrelevant for practically all &-modelers. In the very rare case that these technicalities are of interest, the reader could have a look in , where all EBNF statements are in comments.
This page is meant as a reference for syntactical details and conventions, reserved words, etc.
The most effective way to learn Ampersand's syntax is to copy from existing scripts. This is learning by examples. This reference chapter is suitable to check things, and less suitable for learning.
Ampersand has reserved words, such as RELATION
, CONTEXT
, CONTAINS
. All reserved words are written in capital letters. They are introduced on the fly. You will find an exhaustive list of reserved words at the end of this page.
Untyped atoms are written between double quotes, e.g. "Peter"
or "KD-686-D"
. If you want to introduce a double quote inside an atom, escape it with a backslash, e.g. "the symbol \" is called double quote"
.
Numeric atoms always start with a digit, e.g. 4711
or 75.88E3
. The boolean atoms are TRUE
and FALSE
. Dates and timestamps follow the Excel-syntax, e.g. ??? The atom _SESSION
indicates the current user session, and is an instance of concept SESSION
. It is used in services.
Brackets must always match. For terms, we use round brackets (
and )
. For populations and services we use square brackets [
and ]
.
Constructs that contain ampersand statements are contexts and patterns. They always come in pairs: PATTERN
and ENDPATTERN
, and CONTEXT
and ENDCONTEXT
.
White space characters (spaces, tabs, CRLF) are meaningless. You can use them freely to layout your script in a way that helps you to recognize its structure.
A comment on a single line starts with --
. Everything after a --
symbol is ignored until the line ends. Multiline comments are wrapped between comment brackets {-
and -}
. Multiline comments may be nested.
Identifiers always start with a letter. Concepts start with a capital letter, as in Person
, Case
, A
, and Order
. Relation names start with a lower case letter, as in contains
, attr
, sessionLogin
, or r
.
terms are combined with operators. Binary operators may require brackets to avoid ambiguity. To save writing unneccessary brackets, some precedence rules are in place.
Within an operator category, you must place brackets to disambiguate. E.g. r/\s\/t
is not allowed. You have to write either (r/\s)\/t
or r/\(s\/t)
. Across categories, you may omit brackets because a higher precedence binds stronger. So r;s\/t
means (r;s)\/t
. (Note that (r;s)\/t
and r;(s\/t)
have different meanings). Associative operators (\/
, /\
, ;
) need not be disambiguated with brackets. So r\/s\/t
and (r\/s)\/t
and r\/(s\/t)
all mean exactly the same.
Keywords in Ampersand are always written in CAPITALS.
Keywords for the main structure of the code
ENDCONTEXT
ENGLISH
DUTCH
META
THEMES
ENDPATTERN
PRAGMA
UNI
INJ
SUR
TOT
SYM
ASY
TRN
RFX
IRF
PROP
CONTAINS
RULE
MESSAGE
VIOLATION
TXT
SRC
TGT
I
V
ONE
ROLE
MAINTAINS
Keywords for documentation
REF
REST
HTML
LATEX
MARKDOWN
INTERFACE
FOR
LINKTO
BOX
Keywords for identities
Keywords for views
VIEW
ENDVIEW
DEFAULT
TEMPLATE
HTML
Keywords for generalisations:
CLASSIFY
ISA
IS
Keywords for TType:
REPRESENT
TYPE
ALPHANUMERIC
BIGALPHANUMERIC
HUGEALPHANUMERIC
PASSWORD
BINARY
BIGBINARY
HUGEBINARY
DATE
DATETIME
BOOLEAN
INTEGER
FLOAT
AUTOINCREMENT
Reserved words for values of atoms:
TRUE
FALSE
--for booleans
_SESSION
Reserved words for concepts
ONE
SESSION
Experimental keywords:
SERVICE
EDITS
Deprecated keywords:
SPEC
KEY
PROCESS
ENDPROCESS
Services are meant to expose functionality and data from a , to let users or information systems interact with the system by creating, reading, updating, and deleting data.
Note: The service definition must be outside a pattern
The following figure is an example of a user interface, which shows the name, status, e-mail and co-workers of a person called "J. Lovell".
The specification of this user interface is given in the following service definition:
To understand this fragment, take notice of:
The name of this service is Person
. This name immediately follows the keyword INTERFACE
.
The term following the colon, I[Person]
, is the interface term of this service.
The service can be applied to any atom from the domain of the interface term. So this particular service is applicable to any atom of type Person
. In the screenshot, it applies to "J. Lovell"
.
The labels "Name", "Status", "Email", and "Works with" correspond to field names in the user interface.
Each term at the right of a field name specifies which data is presented in the field. For this reason it is called the field term for that field. Field name and field term are separated by a colon.
Of all pairs <"J. Lovell", x>
from the field term, the field displays the right atom x
. A field term always works on one specific atom on the left, which is "J. Lovell"
in this example.
Field terms are subject to type checking. The following relations provide an example for getting a type-correct service:
The source concepts of a field term must match the target concept of the interface term.
Looking at the screenshot, we can tell that "J. Lovell"
has one personName (which is "J. Lovell"
), it has no personStatus, one personEmail and three persons to work with in RELATION workswith
.
You can create structure in a service by nesting. Here is an example:
The specification of this service is given in the following code fragment.
Notice the following features:
1. The structure of a service is hierarchical. It consists of boxes within a box. This is because a field term may be followed by a BOX
with a list of subservices. Without it, it is just a field term. 2. When a field term is followed by a BOX
, every atom in the codomain of the field term is displayed in a box of its own on the screen. That box behaves like a service with the field term serving as interface term of that subservice. 3. By this mechanism, the hierarchical structure of the entire service translates directly to the hierarchical structure of the web-page in which it is displayed. 4. The source concept of a field term must match with the target concept of the field term outside the box.
5. The target concept of a field term that has a box, must match with the source concepts of each field inside that box.
Especially in more complicated services, you will find it nice to adapt the layout of the fields in the user interface. For this purpose, you can substitute the word BOX
by COLS
, ROWS
, or TABS
, as in the following code fragment. Note that these annotation have no meaning other than to change what the user interface looks like.
Notice the effect that these changes have on the user interface.
Notice the following features:
1. The keyword TABS
turns the box into a tabulated layout.
2. The keyword COLS
turns the layout 90 degrees into columns.
3. The keyword ROWS
is default for any box. It does not change the effect of BOX
.
After finishing your assignment, you have learned:
to explain how a service definition is displayed on the screen of a user.
to predict which data items a service applies to, if you know which pairs are in an interface term.
to predict which data items are displayed, if you know which pairs are in a field term.
to explain which atoms are used in a sub-interface.
to understand what the keywords TABS
, COLS
, and ROWS
do to your display.
More than one service may apply to the same atom. That gives you a choice on runtime to which service you want to navigate. If no service applies, that atom is not navigable.
Keywords for
Keywords for
Keywords for
Compile and run the script . Start by reproducing everything that is shown above. It is quite likely that you will be trying out your own ideas before you get to the end... Have fun!
operator category | precedence | operators |
logic | 1 (weakest) | |- (subset), |
binary boolean | 2 |
|
binary relational | 3 |
|
unary prefix, unary postfix | 4 (strongest) |
|
To store data in a database corresponds to populating the relations in a context. Atoms are the data and pairs of atoms are inserted and deleted during the lifetime of a relation.
All pairs in a relation are called the population of that relation. All atoms in a concept constitute the population of that concept. The population of all relations and concepts in a context make the population of that context.
There are two ways to populate a concept with atoms:
A POPULATION
statement defines the initial population of a concept or a relation.
An INCLUDE
statement defines the initial population from an xlsx-file (i.e. an Excel speadsheet)
Using spreadsheets to define an initial population allows you to work with larger populations. Often you can use an existing spreadsheet and adapt it to become acceptable as Ampersand input.
You can define atoms separately and you can define the pairs in a relation. Both methods result in added population for each concept.
The list of pairs is a comma-separated list between square brackets. Pairs are comma-separated pairs between round brackets. Each atom is enclosed in double quotes.
Most things in your model are in it for a reason. To document these, you should use the PURPOSE statement.
PURPOSE
<type of thing>
<name>
<language>?
<markup>?
<list of references>?
{+
<anything>
+}
Where <type of thing>
and <name>
are the type and name of the thing that is refered to. This could be one of: CONCEPT
, RELATION
, RULE
, IDENT
, VIEW
, PATTERN
, INTERFACE
, CONTEXT
The optional and can be used to override the settings for language and markup. If omitted, these are inherited from the pattern of context where the PURPOSE statement is specified in.
This statement will be available in Ampersand vs. 4.
This statement provides syntactic sugar for defining tabular information conveniently. It introduces a number of relations and rules in a single statement, to simplify a script.
where:
<label>
is the name of the rule. It can be a single word or a string (enclosed by double brackets). It is followed by a colon (:
) to distinguish the label from the concept that follows.
<Concept>
is the name of the Concept for atoms of which the rule specifies an identity
Between brackets are terms whose source concept must be <Concept>
. This is enforced by the type system.
translates into the following declarations:
Multiplicity annotations are allowed. For example:
translates into the following declarations:
This statement makes nice combinations with the IDENT statement. For example to define two identities for persons:
This states that a person is uniquely defined by ssn
, but also by the combination of name
, birthplace
, and birthdate
. This statement can also be used to objectify (reify) an term e
If a user is tempted to replace the Create/Delete pair with a single equivalence, this becomes:
This statement is a rule, which defines an identity on a concept. It is syntactic sugar for specifying a set of relations that identify atoms in a specific concept. For example, if relations pi
and rho
determine an atom of concept T
uniquely, you can write:
As the IDENT statement defines a rule, it can be in the same places as any other RULE.
where:
<label>
is the name of the rule. It can be a single word or a string (enclosed by double brackets). It is followed by a colon (:
) to distinguish the label from the concept that follows.
<Concept>
is the name of the Concept for atoms of which the rule specifies an identity
Between brackets are terms whose source concept must be <Concept>
. This is enforced by the type system.
translates into the following rule:
Note that
in case everye
is both univalent and total, e<>e~
equals e;e~
, and the rule is equivalent to:
in case every e
is univalent but not total, you should use the IDENT
statement (or the rule that it implements), because that also works when an e
is not populated.
Patterns are meant to isolate discussions and make solutions reusable, as known from design patterns.
A pattern is a set of rules that describes a theme or a general reusable solution to a commonly occurring problem.
For instance, if specific concerns about security arise, you might want to discuss this with stakeholders in security. With them you can discuss which rules in particular constitute your solution. Divide your problem in smaller pieces and discuss each piece with just the right stakeholders. This allows you to go deeper by talking to the right people. It saves time as well by freeing others from having to participate. An even larger benefit arises if you reuse patterns that have been discussed and scrutinized before. The best thing comes once your stakeholders agree. By that time, your pattern represents their agreement formally in Ampersand, so you can use it in the larger context of the information system.
Every pattern has the following form:
A pattern consists of any number of pattern elements in an arbitrary order. The following pattern elements are allowed:
A model can have as many patterns as you want. It has no effect on how the code is processed.
The service definition must be outside a pattern
A pattern contains rules in an arbitrary order. The context in which these rules are valid must contain the definition for each of the relations that are used in those rules. It is good practice to declare all relations in the pattern itself. That practice makes the pattern self-contained and therefore more suitable for reuse.
Ampersand advocates one theme in one pattern. Stakeholders confine their discussion to one theme, and deliver the result in one pattern.
In the current implementation of Ampersand, patterns are defined within a context. (This will change in a future version.) If you want to reuse patterns, you have to cut-and-paste them from one context to another. In the future, there will be a better mechanism for reusing patterns in different contexts.
In this section we will make an Ampersand script that is based on an existing spreadsheet. This technique is useful for quickly adding population to an information system. Ampersand has a facility that allows you to import existing .xlsx files with minimal changes.
We can consider Ampersand as a finite system of relations. Every relation is a set of (ordered) pairs and each pair contains two atoms. However, in the real world we also store information in wider tables, as we do in spreadsheets and relational databases. Here is the trick. If we have two pairs that share the same left atom, e.g. (1, Abraham) and (1, Lincoln), we can put them in the same row. Using the same trick, we can interpret a row in a spreadsheet as a number of pairs.
Let us look at an example:
Since Ampersand works with relations, it must represent this table as relations. Three relations can do the job in the following manner:
Notice that the column names in the table correspond with the relation names in Ampersand. In the table we call them "attributes". So it makes sense to say that a relation in Ampersand can correspond with an attribute in a table.
In theory, the population of the Hawaii-script might just as well be given in a spreadsheet. This works in practice too. It looks like this:
Please copy this in a spreadsheet of your own. The element in the first column with square brackets tells Ampersand that a new table starts. The first row contains relation names. The second row contains concept names. The rows that follow contain pairs. Ampersand reconstructs those pairs as in the example above.
In practical applications, you might want to reuse data from existing spreadsheets. People tend to have lots of "informal administration" in spreadsheets, which gives you access to authentic population. Surely you need that data organized in rows, but fortunately that is reasonably common. In such cases, you just add two lines above each table to inform Ampersand about the relations that are populated. In other cases, you have some work organizing the spreadsheet for importing it.
You will find the Excel import function in the menu bar on the top right of your screen
.
This is what your upload screen looks like:
You can upload one or more .xlsx-files by dropping them in the drop zone or by selecting them. You have to upload the population with the green
Upload
button. At that time, all population from the .xlsx-file is added to the context and checked for inconsistencies. As a result, you may get errors when uploading. Only error-free spreadsheets will be uploaded successfully. As long as an error remains, the population in your context will not change.
Make a population of your own for the Hawaii-script and put it in a .xlsx spreadsheet. As described above. Make sure to delete the population statements from your Hawaii source code, to make sure that you get to see the population from your .xlsx-file. Generate a prototype from your Hawaii-application, upload your population in Excel and play around with the results.
After finishing your assignment, you have learned:
to upload population to your Ampersand application in the form of a spreadsheet in .xlsx-format;
to understand how a POPULATION
-statement relates to the contents of a spreadsheet;
that the contents of the spreadsheet is added to the population of your context, provided this does not lead to any conflict.
<rule>
a statement that declares a rule
<classify>
a statement that specifies generalization/specialization of concepts
<relation>
a declaration of a relation, stating the existence of a relation within the context
<conceptDef>
a description of a concept, to document its meaning
<representation>
a statement that defines the atomic type of a concept
<roleRule>
a statement that makes a role responsible for satisfying a rule
<ident>
a rule that defines an identity on a concept
<viewDef>
a statement for presenting facts in a readable sentence
<purpose>
a statement to describe the purpose of a pattern or a pattern element
<population>
a statement that sums up the initial population of a relation
[Subject] | pass | required |
Subject | Student | Destination |
Surfing | Brown | Hawaii |
Surfing | Conway |
Latin | Brown | Rome |
World Religions | Applegate |
World Religions | Brown | Rome |
firstname | lastname | birth |
1 | Abraham | Lincoln | February 12, 1809 |
2 | Barack | Obama | August 4, 1961 |
3 | Calvin | Coolidge | July 4, 1872 |
4 | Dwight | Eisenhower | October 14, 1890 |
To generate documentation, Ampersand is language aware.
Ampersand assigns a language to every text written as documentation, whether it is a MEANING
, PURPOSE
or other text except comment.
Ampersand does not recognize any language, so you must tell which language is meant. To tell Ampersand what language you use, you can append a language directive to a context, a meaning, and to a purpose statement. Currently English and Dutch are supported.
A language directive has the following syntax
Where <language>
can be ENGLISH
or DUTCH
.
The first example is a context declaration in which the language ENGLISH
is specified.
This means that all natural language elements within this context are written in ENGLISH
, unless specified otherwise.
The second example is a MEANING
, which can be used in a RULE
statement and in a RELATION
statement. This example uses a MEANING
in ENGLISH
:
The language directive IN ENGLISH
means that the meaning of the relation ptpic[Pattern*Image]
is written in ENGLISH
.
The third example is a PURPOSE
statement in which the language DUTCH
is specified.
This means that the contents of this purpose statement is written in DUTCH
.
Ampersand assumes that whatever is written is written in the language denoted in the language directive. It doesn't check whether that language is actually used, because it cannot recognize languages.
If a CONTEXT
has no language directive, IN ENGLISH
is used by default. If a CONTEXT
has a language directive, that language will be the default language of all natural language items within that context.
If a PURPOSE
statement or a MEANING
has no language directive, Ampersand assumes this to be the language of its context. So, the user needs to specify a language only if it is an exception to the default.
Documentation generated by the Ampersand-compiler is written in a single language, which is specified when the compiler is called.
Documentation generated by RAP3 is written in DUTCH
. Natural language items written in any other language are ignored. This is not a mistake, but a feature. RAP3 only "speaks Dutch" and ignores anything else.