The Interface between
the NLP and DM modules
in OVIS3
Gert Veldhuijzen van Zanten May 27, 1999
Introduction
Within the NWO priority programme on Language and Speech Technology a number of demonstrator systems are being developed. This document describes the in-terface between the natural language processing mod-ule and the dialogue modmod-ule in the OVIS3 demonstra-tor, the successor of OVIS2.
As in OVIS2, the natural language processing modules send update expressions to the dialogue module. These update expressions represent the meaning of user utter-ances as the intentions of the user to change the ‘men-tal’ state of the system. The updates for OVIS2 are formulated in the update language that was described in TST document #24 “Semantics of Update Expressions” (Veldhuijzen van Zanten 1995). For the new version of the system, OVIS3, we revised the update language. This is because in the larger domain of OVIS3 some additional expressions are needed to represent different kinds of tickets and their prices. Furthermore, from our
experience with OVIS2 we have learned that particular properties of the update formalism were hardly used, and some others were missing. In particular, the focus brackets for assertions, confirmations and corrections could not be placed accurately without the use of pros-ody or contextual information. Neither of which is available to the NLP modules at present. This means that extensive robustness algorithms had to be built into the dialogue module that would deal with incorrectly placed focus brackets. In the revised update language, the topic-focus distinction will be simplified.
1
Architecture
Figure 1 shows the architecture of the OVIS3 demon-strator. The whole system is controlled by a controller module. This module also manages the interface to the ISDN telephone line. The input from that line is passed on to a speech recognizer. The speech recognizer gen-erates a word graph that is passed on to the natural lan-guage processor. The natural lanlan-guage processor dis-ambiguates the word graph and generates an update expression that is passed on to the dialogue manager. The dialogue manager governs the behavior of the dialogue system. It maintains an information state, which records the progress that is made during the dialogue and it determines which actions are appropri-ate depending on the status of information in the in-formation state. When appropriate speech acts have been determined, the language generator attempts to generate a natural language utterance that expresses these acts. It reports back to the dialogue manager which acts have actually been expressed and passes a prosodically annotated natural language utterance onto the speech recognizer. The speech recognizer produces speech, and sends it to the controller, who passes it on to the ISDN line.
In this document, we will focus on the interface be-tween the natural language processor and the dialogue manager. The update expressions contain instructions for changing information state that is maintained by the dialogue manager. The information state for OVIS3 is different from the one used in OVIS2. In OVIS2, we Figure 1: OVIS3 architecture
Speech Recognizer
Language
Processor GeneratorLanguage Speech Synthesizer Controller Dialogue Manager Database ISDN line
used sets of objects with relations. In OVIS3, we use slots that can have values. In the domain of OVIS3, we have slots for origin and destination stations, dates and times, etc. Values for these slots are the actual stations, dates and times. E.g. Amsterdam CS, November 16, 1999. Slots are part of a hierarchical structure. At the top of the hierarchy, we have the main slot. The values of the main slot represent a ‘possible world’.
2
Information States
The semantics of an update expression is defined as a change of the information state. In OVIS2, the infor-mation state consists of a set of objects and relations between them. A pair of objects serves as a slot, and the relationship served as a value for that slot. In OVIS3, we use a fixed set of slots, and a number of constants can serve as values for these slots. The slots form a hierarchy, in the sense that we have sub- and super-slots, and the value of a slot depends on the val-ues of its sub-slots and vice versa. For instance, a date slot may have sub-slots for the year, the month and the day. Given the values for the sub-slots “1999”, “june” and “28”, respectively, the value for the date super-slot will be “6/28/1999”. Thus, the features between slots have a functional interpretation. As in
year (6/28/1999) = 1999
month(6/28/1999) = june
day(6/28/1999) = 28
In OVIS3, the information state consists of a number of propositions and issues with associated grounding status. A proposition is a statement about the value of a slot. There are two kinds of propositions. Both involve a slot and a value. The positive proposition [s=v] states that slot s has a value v, and the negative proposition [s≠v] states that slot s does not have the value v. Slots
for which no proposition is given can have any value. Issues describe what is under discussion. Typically, issues are raised by questions. There are five forms of issues. An open issue [s?] asks what the value of s is. An alternatives issue [s?v1...vn] asks which of the
val-ues v1 through vn is the value of s. A yes/no issue [s?v]
asks whether v is the value of s. A verification issue [s?+v] verifies if the dialogue partner intends to convey that v is the value of s. And finally, a check issue [s?!v] checks whether the dialogue partner literally said that v is the value of s. Issues are important to determine the semantics of updates that contain underspecifications
or anaphora, and for the updates yes, no, neither, both and okay.
3
Update expressions
Update expressions consist of paths, communicative functions, and values. The paths determine which slots are updated, and the communicative functions deter-mine the kind of update. We will first describe the syntax of update expressions, and explain their seman-tics.
The grammar for update expressions is given in Figure 2. Compared to OVIS2 the following should be noted;
• Focus brackets are omitted, and the scope of com-municative functions always runs down to the value level.
• Communicative functions are denoted differently, using :=, +=, != and # for assertion, confirmation, correction and denial, respectively.
update ::= update ; … ; update
| path | yes | no | both | neither | okay | sorry | hello | goodbye | error message
path ::= commfunc value
| path2
path2 ::= feature . path2
| [feature commfunc] value | ( path ; … ; path )
| @
value ::= ( value ; … ; value )
| feature . value | identifier | integer feature ::= identifier commfunc ::= := | != | += | # message ::= not_understood | nothing_recorded Figure 2: Update Grammar
• The communicative function for answering has been deleted. Use assertions instead.
• Update expressions without communicative func-tions are still allowed. Their semantics is similar to assertions.
• Conjunctions can no longer be extended to the right using a dot anymore. Thus, an update like (origin; destination).town := amsterdam is not allowed.
• Anaphors (@) are added.
• The dialogue manager will generate alternatives questions. An alternative question is a question like
“Do you want information about the return trip or about the price?”, in which several alternative
an-swers are suggested. Because alternatives are not necessarily mutually exclusive, possible answers are both and also neither. Here, both means that all given alternatives are accepted, and neither means that none of the alternatives is accepted. Paths may contain values that are not an argument of a communicative function. Such paths are called refer-ences. The typical use of a reference is in cases where the user refers to an already grounded item. For in-stance, “Ik wil om tien uur in Amsterdam aankomen”, while Amsterdam is already grounded, would be translated as
user.wants.arrival.(town.amsterdam; time := hour.10) References will be treated by the dialogue manager, however, as uncertain communicative functions, so when the referenced information is not grounded in the information state, then it will be asserted. As a new feature in OVIS3 updates, we have added a special kind of references, called anaphora. Anaphora are de-noted by @, and are used to refer to unnamed values. For instance, “Ik wil daar om tien uur aankomen” may be translated as
user.wants.arrival.(place.@;
time := hour.10
The semantics of update expressions is defined in terms of dialogue acts. A list of dialogue acts and corre-sponding typical forms of update expressions is shown in Figure 3. The communicative functions that appear in update expressions determine the dialogue acts. A dialogue acts operates on a slot that is determined by the path expression that leads to the communicative function, and the value expression behind the commu-nicative function is the operand of the dialogue act.
The semantics of value expressions is a set of values. This set contains all values that are consistent with the expression. For simple values, such as integers and constants like “monday”, the semantics is a singleton set containing the value that corresponds to the integer or constant. For more complex value expressions we have the following
[[ f.v ]] = { v’ | f (v’) ∈ [[ v]] } [[ ( v1; ... ; vn)]] = [[ v1]] ∩ ... ∩ [[ vn]]
[[ c]] = { c }
where f is the function that corresponds to the feature f, and c is the value that corresponds to the constant c. For example, we note that
[[ hour.19]] = { 19:m | m ∈ {0,...,59} } [[ minute.30]] = { h:30 | h ∈ {0,...,23} } [[ hour.19;minute.30]] = { 19:30 }
The semantics of an update expression is an set of in-formation state changes. We use a set, because update expressions may be ambiguous, and each element in the set represents one interpretation. For the specifica-tion, we define a semantic funcspecifica-tion, that returns a set of
Assertion s := v Confirmation s += v Correction s != v Denial s #(p1; … ; pn) Reference s . v Anaphor s .@
Boolean confirmation Yes
Boolean denial No
Accept all alternatives Both
Deny all alternatives Neither
Handshaking Okay Greeting Hello Closing Goodbye Apology Sorry Error Error m p: linear path ::= s . v s: slot ::= f1. … . fn v: value f: feature
pairs, whose first element is a slot and the second ele-ment is the information state change. The first eleele-ment is needed for the semantics of parts of update expres-sions. For complete update expressions the fist element is ignored. The simplest update expressions consist of a communicative function and a value. They correspond to the basic information state changes assert, confirm,
correct and deny that will be defined in section... . [[ :=v]] = {(s, Assert (s, [[ v]] )) | s∈ slots [[ v]] } [[ :+v]] = {(s, Confirm (s, [[ v]] )) | s∈ slots [[ v]] } [[ :!v]] = {(s, Correct (s, [[ v]] )) | s∈ slots [[ v]] } [[ #v]] = {(s, Deny (s, [[ v]] )) | s∈ slots [[ v]] } where the function slots returns the set of slots that are appropriate for storing the values in its argument. More complex update expressions contain paths. Each path leads to a slot that serves as the locus of change for the dialogue act. The communicative function and the value determine which kind of change is to be ap-plied. A path expression can be seen as a roadmap through the slot hierarchy. Each feature describes the next road to take. The paths, however, may be incom-plete and underspecify the slots. Therefore, update ex-pressions may ambiguously refer to several slots. As in OVIS2, we make sure that this ambiguity is kept within limits by requiring that the type of a conjuction is cho-sen as low as possible.
[[f.p]] = { (s’,a) | (s,a) ∈[[p]] , f(s’)=s } [[ p1;...; pn ]] = { (s0, a1; ...; an)
| (si, ai) ∈[[pi]], s0∈ s1∧...∧sn }
Here, a1; ...; an means that the information state
changes a1 through an are to be applied in sequence.
Thus, we have that
f ; g (x) = g( f (x))
The meet operator ∧ determines a set of slots that are super-slot of both arguments, and that are of a type that is the lowest super-type of the type of the arguments. This set is empty for slots that are too far apart. For instance,
departure.moment.time.hour∧
arrival.moment.time.minute = ∅ while
arrival.moment.time.hour∧
arrival.moment.time.minute
= { arrival.moment.time}
Anaphora and referring expressions don’t change the information state, but they do affect where updates take place. Anaphora and referring expressions refer to in-formation that is already in the inin-formation state. We
model this information rather loosely as a set of topics. The maintenance of the topic set is the responsibility of the dialogue manager and will not be described in this document. We will assume that the reader has some intuitive notion of what slots are accessible for anaph-ora and which are not.
[[@]] = { (s, I) | s∈ topics }
[[v]] = { (s, I) | s∈ topics ∩ slots( [[v]]) } The semantics of anaphora and referring expressions depends heavily on the meet operation that was intro-duced for the semantics of conjunctions.
We have expressed the semantics of update expressions in terms of basic dialogue acts assert, confirm, correct and deny. We will now define these basic dialogue acts. Each act takes a slot and a set of values as argu-ments. In principle, the meaning of the dialogue acts could be defined as follows.
Assert (s,V) The information that the value of s is an element of V is added to the in-formation state.
Confirm (s,V) If the information that the value of s is an element of V is in the informa-tion state, then it is grounded, other-wise it is added.
Correct (s,V) The information that the value of s is an element of V is added to the in-formation state, while any informa-tion that is inconsistent with it is re-moved.
Deny (s,V) The information that the value of s is not an element of V is added to the information state.
Unfortunately, the information state can only store in-formation in terms of propositions. I.e. slots can only have one value and we cannot store “the information that the value of s is an element of V” for sets V other than singleton sets or their inverses. We can, however, construct sets of propositions that approximate the same information, by referring to sub-slots.
props (s, V)
= case V of
∅: ∅ {v}: {[s=v]}
V:
∪
{props (f(s), {f(v) | v∈V} )| f∈F such that f(s) is defined }
The function props takes a slot and a set of values, and returns a set of propositions, that approximates the in-formation that the value of the slot should be one of the values in the set. The approximation does not cause
problems, because for value sets that occur as the se-mantics of an update expression, the approximation is exact. We can now define the semantics of dialogue acts as follows.
Assert (s,V) Add propositions props(s,V) to the in-formation state.
Confirm (s,V) Ground the propositions in props(s,V) that are already present, and add the other ones.
Correct (s,V) Add propositions props(s,V) to the in-formation state, while any inin-formation that is inconsistent with it is removed.
Deny (s,V) If props(s,V) is a singleton set {v}, then add the proposition [s≠v].
Other-wise, remove the propositions from the information state, and put them up for questioning by the dialogue manager. Besides update expressions that paths, consist of com-municative functions and values, there are also the atomic update expressions, such as yes and no. The semantics of these is defined as follows.
Yes Add the proposition [s=v] for any issue [s?v] or [s?+v] in the information state.
No If there is only one issue of the form [s?v] or [s?+v] then add the proposition [s≠v]. Otherwise, remove all
proposi-tions [s=v] such that [s?v] or [s?+v] is an issue in the information state.
Both Add propositions [s=vi] for any issue
[s?v1,...,vn] in the information state
Neither Remove propositions [s=vi] for any
issue [s?v1,...,vn] in the information
state.
Okay Same as yes.
A consequence of the way that we have defined the semantics of update expressions, is that most of the communicative functions distribute over the
;-operator. Therefore, it is possible to transform paths into a sequence of basic paths of the form
basic_path ::= slot comm_func basic_value slot ::= feature . … . feature
For example, the update
the_route.moment.date := (month.november; day.25)
is semantically equivalent to
the_route.moment.date.month := november; the_route.moment.date.day := 2
The only communicative function that does not distrib-ute over the ;-operator, and for which this transforma-tion is therefore not possible, is the denial (#).
For instance, the update
the_route.moment.date # (month.november; day.25)
does not mean the same as
the_route.moment.date.month # november; the_route.moment.date.day # 25
The latter is too strong; it says that neither is the month November nor is the day the 25th, while the latter says that at least one of the two is not the case.
4
Variants
In OVIS2, we allowed update expressions such as user.wants.info.the_route
in which no value occurs. These were not very useful in OVIS2 because there was only one kind of informa-tion that the system could supply. However, in OVIS3, something similar could be useful. We would like to have update expressions such as.
user.wants.info := the_route or user.wants.info := the_price
However, we also want to have updates like the fol-lowing.
user.wants.info.the_route.origin := amsterdam Thus, the identifier “the_route” serves a dual role, as a feature and as a value. To allow this we introduce so-called variants. Variants are represented by identifiers that can serve both as features and as values. They serve a similar role as cases in PASCAL-like variant record structures. An update expression like
user.wants.info := the_route
sets the variant to “the_route”, and therefore disables all slots below other variants (such as “the_price”). An update such as
user.wants.info.the_route.origin := amsterdam implicitly sets the variant. To deal with the semantics of variants, we add a feature named variant in the ap-propriate position, and the dialogue manager uses an internal dialog act called presupposition. For such
up-dates, the dialogue manager adds a presupposition dia-logue act.
user.wants.info.variant %= the_route The semantics of presuppositions are very similar to those of assertions, except that they apply only to vari-ants and they are less easily overruled by contradicting information.
5
Ambiguities
The NLP modules will try to disambiguate the word graph as much as possible, but should not attempt to remove all ambiguities, because the dialogue manager may have information that would yield certain alterna-tive interpretations as invalid. For example, when an explicit verification was disconfirmed. In such cases, we should select a second or third best alternative. This is particularly useful in cases where two or more words are hard to distinguish acoustically.
For this purpose, we allow alternatives interpretations in the update expressions. The update grammar will be extended by the following rules.
update ::= { update_alt | … | update_alt } update_alt ::= update
path ::= { path_alt | … | path_alt } path_alt ::= path
value ::= { value_alt | … | value_alt } value_alt ::= value
This way, we can have updates of the following form. user.wants.place := {weesp | beesd} The most likely alternative should be listed first.
6
Confidence Measures
In order to decide whether to generate an explicit veri-fication, or to just give feedback, the dialogue manager needs some form of confidence measures. In the first version of OVIS3 these measures will not be used, and the DM will generate explicit verification questions for all newly acquired information. We foresee, however, that the user-friendliness of the system could be en-hanced if confidence measures were used. Therefore, we propose to add syntactic means for adding confi-dence measures in update expressions.
update_alt ::= confidence update path_alt ::= confidence path
value_alt ::= confidence value
confidence ::= <. {digit}* >
An example of an update with confidence measures is. user.wants.place := {<.31> weesp |
<.22> beesd}
7
Annotations
In OVIS2 we added annotation to the update expres-sions, that showed which words the user used to ex-press parts of the update. It is yet unclear whether the language generator will make user of such annotations. However, they may be added using the following syn-tactic constructs.
update ::= update annotation
path ::= path annotation
value ::= value annotation
annotation ::= " word … word "
8
The Domain Specification
The dialogue module of the OVIS3 system is param-eterized by a domain specification. This specification determines which slots and values are present in the domain, and what their semantics is. Every slot and value is associated with a type. In this document, we will not discuss the specification of the semantics, but only give the type declarations, for as far as they are relevant for the interface between the NLP and DM modules.
8.1.
Type declarations
Part of the frame specification consists of a list of type declarations. Each type declaration consists of a type name and a body. In the body, six different sections can occur: a keys-section, a features-section, a variants -section, a relations-section, a values-section, a refs -section (and a semantics-section, which will not be dis-cussed in the document). Type declarations determine which slots occur, what the relations between slots are and what values each slot can contain.
The simplest kinds of type declarations simply list the values that can be assigned to a slot of the declared
type. For instance, a DayOfWeek type is declared as follows.
DayOfWeek = { values monday, tuesday, wednesday, thursday, friday, saturday, sunday }
Slots of type DayOfWeek can hold either of the days of the week as a value. Other types of slots have more structured imposed on their values. These slots have sub-slots that are accessed via keys are accessed via keys, features or variants. For instance, the Date type is declared as follows. Date = { keys year: Year, month: Month, day: Day features week: Week, day_of_week: DayOfWeek, kind_of_day: KindOfDay
refs today, tomorrow, day_after_tomorrow }
The Date type has keys, features and referents. Keys are special kinds of features. The difference between keys and features is a pragmatic one and can, for the purpose of this document, be ignored.
For the Date type, no values are specified, but there are some referents. A referent is similar to a value, except that values are mutually exclusive, while referents do not exclude values from being assigned to a slot. So, when a date slot contains the referent tomorrow, it does not exclude a date value constructed from the year
1998, the month november and the day 24. This is par-ticularly useful on November 23rd, 1998. Also, when a slot contains a referent, the slot is not necessarily con-sidered known.
8.2.
Variants
Some types have variants. For instance, the Info type is declared as Info = { variants the_route: Connection the_price: Ticket, the_return_trip: Connection }
This means that the info slot has three sub-slots, of which only one can be active at a time. The active one is stored in a separate slot that is automatically added as if declared as follows. Info = { variants the_route: Connection the_price: Ticket, the_return_trip: Connection features variant: InfoVariant } InfoVariant = {
values the_route, the_price, the_return_trip }
8.3.
Relations
The informational state of the dialogue is expressed as constraints on the slots. The user, for instance, will constrain a connection slot, by supplying values for some of its sub-slots, e.g. origin, destination, date and arrival time. The effect of this is that a set of connec-tion values will be limited to the appropriate set of hy-pothetical connections. The system can then apply its knowledge about real train connections, and tell the user about them. Almost all constraints can be ex-pressed in terms of values that are associated to sub-slots, but not all. For instance, a constraint like “a co n-nection that arrives before 10 o’clock” cannot be e x-pressed in such a way, because there is no functional relation between a connection and the time before which it arrives. For this purpose, we define reference slots. Reference slots exist purely for the purpose of constraining other slots. The constraint is defined by a relation between the slot and a reference slot. Relations are defined in the relations-section of a type declara-tion. We assume that the reference slot is of the same type as the slot that is being constrained. Therefore, no type needs to be specified for a relation.
Moment = { keys date: Date, time: Time refs now relations after, before }
Relations can occur in updates in the same way as fea-tures (and keys) can. Their omission, however, will never be interpreted as underspecification of the rela-tion. Thus, the update
user.wants.info.the_route.moment := now will mean that the moment is now, and not after or be-fore now. “Ik wil voor vijf uur aankomen” can be translated as
8.4.
Selectors
An example of other kind of constraint that cannot be described in terms of features, is the following: “Ik wil
de snelste verbinding” ( I want to know the fastest
con-nection). This constraint is relative to a set of connec-tions, it selects a connection based on a comparison with the other connections that satisfy the constrained mentioned so far. For this purpose, we have added se-lectors to the slot structure.
Connection = { keys trajectory: Trajectory, moment: Moment, mom_ref: Reference features departure: Event, arrival: Event, repeat: Bool selectors
earlier, later, fastest, least_changes, first, last }
The effect is that a kind of feature named selector is added whose value can be one of the selectors. Thus, an update
the_route.selector := least_changes
becomes possible. Selectors are mainly used in the navigation phase after a train connection has been given, but they can also be used in the slot filling phase, e.g. “Ik wil met de eerste trein na negen uur”
user.wants.(means.train;
after.clock_hour.9; selector.first)
9
Appendix A:
the frame specification
TYPES World = { keys user: User } User = { keys
wants: set of Want, features
is: Place,
status: UserStatus }
UserStatus = { values ok, confused } Want = { variants info: Info, repeat: Repeat, more, quit }
Repeat = { values connection, price, last_utterance } Info = { variants the_route: Connection the_price: Ticket, the_return_trip: Connection } Ticket = { keys trajectory: Trajectory, kind: TicketKind features repeat: Bool } TicketKind = { keys class: Class, fare: Fare, sort: TicketSort }
Class = { values first_class, second_class } Fare = { values normal, reduction }
TicketSort = { values one_way, return, weekend_return }
Connection = { keys trajectory: Trajectory, moment: Moment, mom_ref: Reference features departure: Event, arrival: Event, repeat: Bool selectors
earlier, later, fastest, least_changes, first, last } Trajectory = { keys origin: Place, destination: Place features means: MeansOfTransport } Reference = { values depart, arrive }
MeansOfTransport = { values train, bus, tram, metro } Event = { keys place: Place, moment: Moment } Place = { keys town: Town, suffix: Suffix
values from Stations (column 1) } Town = {
values from Stations (column 2),
// Plus some towns that have no train station drachten, dronten, emmeloord, kaatsheuvel, nes, oosterhout, schiermonnikoog, spijkenisse, stadskanaal, terschelling, uden, uithoorn, veendam, zierikzee } Suffix = {
values from Stations (column 3),
// Plus some suffixes that are used to refer to // non-existent train stations
arena, busstation, capelsebrug, efteling,
kralingse_zoom, leidscheplein, marconiplein, markt, marnixstraat, metro_centrum, van_knobelsdorfplein, zuidplein } Moment = { keys date: Date, time: Time features in: Interval refs now relations after, before }
Date = { keys year: Year, month: Month, day: Day features week: Week, day_of_week: DayOfWeek, kind_of_day: KindOfDay, special: SpecialDate
refs today, tomorrow, day_after_tomorrow, same } SpecialDate = {
keys
celebration: Celebration, rank: Rank }
Celebration = {
values easter, ascention, pentecost, sinterklaas, christmas } Rank = { values first, second }
Year = { refs next
values 1995..2010 } Month = {
refs next
values january, february, march, april, may, june, july, august, september, october, november, december } Day = { refs next values 1..31 } Week = { refs next values 1..53 } DayOfWeek = {
values monday, tuesday, wednesday, thursday, friday, saturday, sunday }
KindOfDay = { values weekend, weekdays } Interval = { features months: MonthsInterval, weeks: WeeksInterval, days: DaysInterval, hours: HoursInterval, minutes: MinutesInterval } MonthsInterval = { values 1..12 } WeeksInterval = { values 1..52 } DaysInterval = { values 1..31 } HoursInterval = { values 1..48 } MinutesInterval = ( values 1..1440 } Time = { keys hour: Hour, minute: Minute refs currtime } Hour = { keys clock_hour: ClockHour, ampm: AmPm features part_of_day: PartOfDay values 0..23 }
AmPm = { values am, pm } PartOfDay = {
values night, morning, afternoon, evening } ClockHour = { values 1..12 }
Hour = { values 0..24 } Minute = { values 0..59 } Bool = { values true, false }
Stations (Place, Town, Suffix) {
(a, aachen, no_suffix),
(atn, aalten, no_suffix),
(ac, abcoude, no_suffix),
(akm, akkrum, no_suffix),
(amr, alkmaar, no_suffix),
(amrn, alkmaar, noord),
(aml, almelo, no_suffix),
(amri, almelo, de_riet),
(alm, almere, cs),
(alm, almere, no_suffix),
(almb, almere, buiten),
(almm, almere, muziekwijk),
(almp, almere, parkwijk),
(apn, alphen, aan_den_rijn),
(amf, amersfoort, no_suffix),
(amfs, amersfoort, schothorst),
(asa, amsterdam, amstel),
(asb, amsterdam, bijlmer),
(asd, amsterdam, cs),
(asdl, amsterdam, lelylaan),
(asdm, amsterdam, muiderpoort),
(asdv, amsterdam, de_vlugtlaan),
(asdz, amsterdam, zuid_wtc),
(ass, amsterdam, sloterdijk),
(rai, amsterdam, rai),
(ana, anna_paulowna, no_suffix),
(atw, antwerpen, no_suffix),
(apd, apeldoorn, no_suffix),
(apg, appingedam, no_suffix),
(akl, arkel, no_suffix),
(arn, arnemuiden, no_suffix),
(ah, arnhem, no_suffix),
(ahp, arnhem, velperpoort),
(ahpr, arnhem, presikhaaf),
(asn, assen, no_suffix),
(brn, baarn, no_suffix), (bf, baflo, no_suffix), (brd, barendrecht, no_suffix), (bnc, barneveld, centrum), (bnn, barneveld, noord), (bdm, bedum, no_suffix), (bk, beek, elsloo), (bsd, beesd, no_suffix), (bl, beilen, no_suffix), (bgn, bergen_op_zoom, no_suffix), (rdr, berkel, rodenrijs),
(bet, best, no_suffix),
(bv, beverwijk, no_suffix), (bhv, bilthoven, no_suffix), (bll, bloemendaal, no_suffix), (bdg, bodegraven, no_suffix), (bn, borne, no_suffix), (bsk, boskoop, no_suffix), (bkf, bovenkarspel, flora), (bkg, bovenkarspel, grootebroek), (bmr, boxmeer, no_suffix), (btl, boxtel, no_suffix), (bd, breda, no_suffix), (bdpb, breda, prinsenbeek), (bkl, breukelen, no_suffix), (bmn, brummen, no_suffix),
(brusc, brussel, centraal),
(brusc, brussel, no_suffix),
(brusn, brussel, noord),
(brusz, brussel, zuid),
(bp, buitenpost, no_suffix),
(bde, bunde, no_suffix),
(bnk, bunnik, no_suffix),
(bsmz, bussum, zuid),
(cps, capelle, aan_de_ijssel),
(cas, castricum, no_suffix),
(cvm, chevremont, no_suffix),
(co, coevorden, no_suffix),
(cl, culemborg, no_suffix),
(ck, cuyk, no_suffix),
(da, daarlerveen, no_suffix),
(dln, dalen, no_suffix),
(dl, dalfsen, no_suffix),
(dei, deinum, no_suffix),
(ddn, delden, no_suffix), (dt, delft, cs), (dtz, delft, zuid), (dz, delfzijl, no_suffix), (dzw, delfzijl, west), (dld, den_dolder, no_suffix), (gv, den_haag, hs), (gvc, den_haag, cs), (gvc, den_haag, no_suffix), (gvm, den_haag, mariahoeve), (gvmw, den_haag, moerwijk),
(laa, den_haag, laan_van_noi),
(hdr, den_helder, no_suffix),
(hdrz, den_helder, zuid),
(dn, deurne, no_suffix),
(dv, deventer, no_suffix),
(dvc, deventer, colmschate),
(did, didam, no_suffix),
(dmn, diemen, noord), (dmnz, diemen, zuid), (dr, dieren, no_suffix), (dtc, doetinchem, no_suffix), (dtch, doetinchem, de_huet), (ddr, dordrecht, no_suffix), (ddrs, dordrecht, stadspolders), (ddzd, dordrecht, zuid), (ddr, dordt, no_suffix), (db, driebergen, zeist), (drh, driehuis, no_suffix), (drp, dronrijp, no_suffix), (dvn, duiven, no_suffix), (dvd, duivendrecht, no_suffix), (dussel, duseldorf, no_suffix),
(ec, echt, no_suffix),
(ed, ede, wageningen),
(edc, ede, centrum),
(ehb, eindhoven, beukenlaan),
(ehv, eindhoven, no_suffix),
(est, elst, no_suffix),
(emn, emmen, no_suffix),
(emnb, emmen, bargeres),
(ekz, enkhuizen, no_suffix),
(es, enschede, no_suffix),
(esd, enschede, drienelo),
(eml, ermelo, no_suffix),
(egh, eygelshoven, no_suffix),
(edn, eysden, no_suffix),
(fn, franeker, no_suffix),
(gdk, geerdijk, no_suffix),
(gdm, geldermalsen, no_suffix),
(gp, geldrop, no_suffix),
(gln, geleen, oost),
(lut, geleen, lutterade),
(gz, gilze, rijen),
(gs, goes, no_suffix),
(go, goor, no_suffix),
(gr, gorinchem, no_suffix), (gd, gouda, no_suffix), (gdg, gouda, goverwelle), (gbg, gramsbergen, no_suffix), (gk, grijpskerk, no_suffix), (gn, groningen, no_suffix), (gnn, groningen, noord), (gw, grouw, irnsum), (hlm, haarlem, no_suffix), (hlms, haarlem, spaarnwoude), (hdg, hardegarijp, no_suffix), (hdb, hardenberg, no_suffix), (hd, harderwijk, no_suffix), (gnd, hardinxveld, giessendam), (hrn, haren, no_suffix), (hlg, harlingen, no_suffix), (hlgh, harlingen, haven), (hk, heemskerk, no_suffix),
(had, heemstede, aerdenhout),
(hr, heerenveen, no_suffix),
(hwd, heerhugowaard, no_suffix),
(hrl, heerlen, no_suffix),
(hze, heeze, no_suffix),
(hlo, heiloo, no_suffix),
(hno, heino, no_suffix),
(hm, helmond, no_suffix),
(hmbh, helmond, brouwhuis),
(hmh, helmond, t_hout),
(hmn, hemmen, dodewaard),
(hgl, hengelo, no_suffix),
(hglo, hengelo, oost),
(hvs, hilversum, no_suffix), (hvsn, hilversum, noord), (hvsp, hilversum, sportpark), (hnp, hindeloopen, no_suffix), (hld, hoek_van_holland, haven), (hlds, hoek_van_holland, strand), (hb, hoensbroek, no_suffix),
(hor, hollandsche_rading, no_suffix),
(hon, holten, no_suffix),
(hfd, hoofddorp, no_suffix), (hgv, hoogeveen, no_suffix), (hgz, hoogezand, sappemeer), (hks, hoogkarspel, no_suffix), (hn, hoorn, no_suffix), (hnk, hoorn, kersenboogerd), (hrt, horst, sevenum), (htn, houten, no_suffix), (sgl, houthem, sint_gerlach),
(yt, ijlst, no_suffix),
(kpn, kampen, no_suffix), (bzl, kapelle, biezelinge), (krd, kerkrade, centrum), (ktr, kesteren, no_suffix), (kbk, klarenbeek, no_suffix), (rtkw, kleiweg, no_suffix), (kmr, klimmen, ransdaal), (kbw, koog, bloemwijk), (kzd, koog, no_suffix), (kzd, koog, zaandijk), (kmw, koudum, molkwerum), (kbd, krabbendijke, no_suffix),
(kma, krommenie, assendelft),
(kw, kropswolde, no_suffix), (krg, kruiningen, yerseke), (zlw, lage_zwaluwe, no_suffix), (lg, landgraaf, no_suffix), (ldm, leerdam, no_suffix), (lw, leeuwarden, no_suffix), (lwc, leeuwarden, camminghaburen), (dvnk, leiden, de_vink), (ldl, leiden, lammenschans), (ledn, leiden, cs), (ldv, leidschendam, voorburg), (lls, lelystad, centrum), (ltv, lichtenvoorde, groenlo), (lc, lochem, no_suffix), (lp, loppersum, no_suffix),
(luik, luik, no_suffix),
(ltn, lunteren, no_suffix),
(mrn, maarn, no_suffix),
(mas, maarssenbroek, no_suffix),
(mss, maassluis, no_suffix), (msw, maassluis, west), (mt, maastricht, no_suffix), (mtr, maastricht, randwijk), (mg, mantgum, no_suffix), (mrb, marienberg, no_suffix), (mth, martenshoek, no_suffix),
(mes, meerssen, no_suffix),
(mp, meppel, no_suffix),
(mdb, middelburg, no_suffix),
(ndb, naarden, bussum),
(na, nieuw_amsterdam, no_suffix), (nvp, nieuw_vennep, no_suffix), (nwk, nieuwerkerk, aan_den_ijssel), (nsch, nieuweschans, no_suffix), (nkk, nijkerk, no_suffix), (nm, nijmegen, no_suffix), (nmd, nijmegen, dukenburg), (nmh, nijmegen, heyendaal), (nvd, nijverdal, no_suffix), (ns, nunspeet, no_suffix), (nh, nuth, no_suffix),
(obd, obdam, no_suffix),
(ot, oisterwijk, no_suffix),
(odz, oldenzaal, no_suffix),
(ost, olst, no_suffix),
(omn, ommen, no_suffix),
(otb, oosterbeek, no_suffix),
(op, opheusden, no_suffix),
(o, oss, no_suffix),
(ow, oss, west),
(odb, oudenbosch, no_suffix),
(paris, parijs, no_suffix),
(pnk, pijnacker, no_suffix),
(pmo, purmerend, overwhere),
(pmr, purmerend, beatrixplein),
(pt, putten, no_suffix),
(rat, raalte, no_suffix),
(rvs, ravenstein, no_suffix), (rv, reuver, no_suffix), (rh, rheden, no_suffix), (rhn, rhenen, no_suffix), (rsn, rijssen, no_suffix), (rsw, rijswijk, no_suffix), (rb, rilland, bath), (rm, roermond, no_suffix), (rd, roodeschool, no_suffix), (rsd, roosendaal, no_suffix), (rs, rosmalen, no_suffix), (rlb, rotterdam, lombardijen),
(rta, rotterdam, alexander),
(rtb, rotterdam, blaak), (rtbw, rotterdam, bergweg), (rtd, rotterdam, cs), (rtd, rotterdam, no_suffix), (rth, rotterdam, hofplein), (rtkw, rotterdam, kleiweg), (rtn, rotterdam, noord), (rtwp, rotterdam, wilgenplas), (rtz, rotterdam, zuid), (rl, ruurlo, no_suffix), (ht, s_hertogenbosch, no_suffix), (hto, s_hertogenbosch, oost),
(sptn, santpoort, noord),
(sptz, santpoort, zuid),
(spm, sappemeer, oost),
(swd, sauwerd, no_suffix),
(sgn, schagen, no_suffix),
(sda, scheemda, no_suffix),
(nwl, schiedam, nieuwland),
(sdm, schiedam, rotterdam_west),
(sog, schin_op_geul, no_suffix),
(sn, schinnen, no_suffix), (shl, schiphol, no_suffix), (std, sittard, no_suffix), (sdt, sliedrecht, no_suffix), (sk, sneek, no_suffix), (sknd, sneek, noord), (ws, sodom, no_suffix), (st, soest, no_suffix), (stz, soest, zuid), (sd, soestdijk, no_suffix), (sdn, soestduinen, no_suffix), (sbk, spaubeek, no_suffix), (stv, stavoren, no_suffix), (stm, stedum, no_suffix), (swk, steenwijk, no_suffix), (srn, susteren, no_suffix), (sm, swalmen, no_suffix),
(hde, t_harde, no_suffix),
(tg, tegelen, no_suffix),
(tbg, terborg, no_suffix),
(tl, tiel, no_suffix),
(tb, tilburg, no_suffix),
(tbwt, tilburg, west),
(utg, uitgeest, no_suffix),
(uhz, uithuizen, no_suffix),
(uhm, uithuizermeeden, no_suffix),
(ust, usquert, no_suffix),
(ut, utrecht, cs),
(ut, utrecht, no_suffix),
(utl, utrecht, lunetten),
(uto, utrecht, overvecht),
(vk, valkenburg, aan_de_geul), (vsv, varsseveld, no_suffix), (klp, veenendaal, de_klomp), (vndc, veenendaal, centrum), (vndw, veenendaal, west), (vwd, veenwouden, no_suffix), (vp, velp, no_suffix), (br, venlo, blerick), (vl, venlo, no_suffix),
(vry, venray, no_suffix),
(vlb, vierlingsbeek, no_suffix),
(vdg, vlaardingen, centrum),
(vdg, vlaardingen, no_suffix),
(vdo, vlaardingen, oost),
(vdw, vlaardingen, west), (vtn, vleuten, no_suffix), (vs, vlissingen, no_suffix), (vss, vlissingen, souburg), (vdl, voerendaal, no_suffix), (vb, voorburg, no_suffix), (vbl, voorburg, t_loo), (vh, voorhout, no_suffix), (vst, voorschoten, no_suffix), (vd, vorden, no_suffix), (vz, vriezenveen, no_suffix), (vhp, vroomshoop, no_suffix), (vg, vught, no_suffix),
(wad, waddinxveen, no_suffix),
(wadn, waddinxveen, noord),
(wfm, warffum, no_suffix), (wt, weert, no_suffix), (wp, weesp, no_suffix), (wl, wehl, no_suffix), (wc, weichen, no_suffix), (wz, wezep, no_suffix), (wc, wiechen, no_suffix), (wdn, wierden, no_suffix), (wh, wijhe, no_suffix), (ws, winschoten, no_suffix), (wsm, winsum, no_suffix), (ww, winterswijk, no_suffix), (wd, woerden, no_suffix), (wf, wolfheze, no_suffix), (wv, wolvega, no_suffix), (wk, workum, no_suffix), (wm, wormerveer, no_suffix), (zd, zaandam, cs), (zdk, zaandam, kogerveld), (zbm, zaltbommel, no_suffix), (zvt, zandvoort, aan_zee),
(za, zetten, andelst),
(zv, zevenaar, no_suffix),
(zvb, zevenbergen, no_suffix),
(dmp, zoetermeer, driemanspolder),
(ley, zoetermeer, de_leyens), (zcw, zoetermeer, centrum_west), (zsh, zoetermeer, stadhuis), (ztm, zoetermeer, no_suffix), (ztmb, zoetermeer, buytenwegh), (ztmd, zoetermeer, dorp), (ztml, zoetermeer, leidsewallen), (ztmm, zoetermeer, meerzicht),
(ztmo, zoetermeer, oost),
(ztmp, zoetermeer, palenstein), (ztms, zoetermeer, seghwaert), (ztmv, zoetermeer, voorweg), (zb, zuidbroek, no_suffix), (zh, zuidhorn, no_suffix), (zp, zutphen, no_suffix), (zh, zuudheurn, no_suffix), (zww, zwaagwesteinde, no_suffix), (zwd, zwijndrecht, no_suffix), (zl, zwolle, no_suffix)}