Main page

Treebank Semantics Manual

by Alastair Butler and Stephen Wright Horn

Chapter 1: Introduction

1.1   Aims
1.2   Structural analysis
1.3   Overview

Chapter 2: Annotation and normalisation

2.1   Annotation
2.1.1   Word segmentation and classification
2.1.1.1   Multi-word expressions
2.1.1.2   Punctuation
2.1.2   Labelled bracketing of segments
2.1.2.1   Coordination
2.1.3   Indicating grammatical function
2.1.4   Clause linkage types
2.1.5   Scope marking
2.1.6   Null elements
2.1.7   Tracking anaphora
2.1.8   Sense/role disambiguation
2.2   Tree normalisation
2.3   Normalisation to Prolog terms
2.4   Strings with grammatical roles
2.5   Intermediate language
2.6   Basic grammar statements
2.6.1   Building predicates
2.6.2   Enabling subordination
2.6.3   Making closures
2.7   Transformations
2.7.1   Settings for ‘fresh’ and ‘local’ parameters
2.7.2   Closure
2.7.3   Verbs
2.7.4   Past tense
2.7.5   Passivisation
2.7.6   Other predicates
2.7.7   Argument forming structures
2.7.7.1   Proper names
2.7.7.2   Noun phrases with restrictions
2.7.7.3   Noun phrases with quantification
2.7.7.4   Classic arguments
2.7.7.5   Propositional arguments
2.7.7.6   Pronouns
2.7.7.7   Noun phrase conjunction
2.7.7.8   Preposition phrase conjunction
2.7.7.9   Parentheticals
2.7.8   Embedding
2.7.9   Control
2.7.10   Coordination
2.7.11   Further ways to connect expressions
2.7.12   Clause typing
2.7.13   Propositional operations
2.8   Orientation

Chapter 3: Semantic calculation

3.1   Collecting <discourse_referent>s
3.2   Storing <discourse_referent>s
3.2.1   push/4
3.2.2   pop/3
3.2.3   shift/4
3.2.4   shift_last/4
3.2.5   allocate/6 with expression integrity
3.2.6   dispose/5
3.3   From <sct_expr>s to <target_expr>s
3.4   The target discourse representation language

Chapter 1: Introduction

1.1   Aims

This manual presents the techniques behind a parsed annotation approach that has led to the creation of corpus resources with syntactic and semantic information for languages, including:

These corpus resources offer instantiations of the goal to provide fully searchable representations of texts that are described according to interpretations of the meanings of sentences. This involves analysing texts into units and accounting for how the units are composed into meaningful expressions. Units are related by either grammatical functions or semantic relations. These two types of relations are together referred to as ‘dependencies’. The annotation uses unit types, structural relations, and only as a last resort, indices, to describe how dependencies are established. A full description of a sentence tells the story of how information flows through structure to compose complex meanings. In order to achieve this, the annotation uses familiar grammatical categories to name units in an economical way, according to some basic organising principles.

     The principles depend on two fundamental points:

  1. an adequate description of the grammar, and
  2. the ability to calculate a semantic representation.

In essence, we take a text, divide it up into utterances (let's say, sentences), and decide on an interpretation for each sentence. Next we organise the parts of the sentence to show how the parts combine in principled ways to compose the meaning we arrive at in our interpretation. This takes the form of a tree with labeled nodes. Let's call this ‘structure’. The idea behind our annotation is that the meaning is in the structure, and that we can reach, by undertaking transformations between representations that capture the structure, alternative instantiations of the structure that can be more explicit articulations of meaning components and their comprising dependencies.

     Notably, the parse annotated tree structure will be transformed into expressions of a logical language, comprised of: constants, variables, operators, and predicate relations / logical connectives. A logical expression is reached by undertaking a recursive calculation that receives normalised annotation as input. We will refer to this as the ‘semantic calculation’.

     At the start of the calculation, there is a collection of ‘discourse referents’ which are read from the given normalised input. Discourse referents with the form of logical variables are ultimately destined to be bound by operations of closure (e.g., ) in the overall resulting logical expression. The operations of closure are themselves either reflexes of the normalised input, or arise because there is discourse closure. During the runtime of the calculation, the collected discourse referents are released as content for argument slots of predicates that populate the resulting logical expression. The exact makeup of argument slots (valencies) for a given predicate is typically underspecified, with it being the availability of released and accessible discourse referents at the point in the calculation when the predicate is reached and to which the predicate will have been made sensitive that determines the realisation of arguments for the predicate.

     If the logical expression derived from a given sentence annotation corresponds to the original interpretation, this is one kind of confirmation that the structure assigned to that sentence is correct. You can see how the generation of a well-formed (and accurate) logical expression can actually be a driving principle for the design of the structure.

1.2   Structural analysis

The details of the semantic calculation are presented in Chapter 3. But we can immediately observe effects that the semantic calculation has on deciding how to mark up the structure of sentences in the corpora. First let's take a look at how structure is expressed.

     Units of the annotation are contained under nodes in a tree. Words are contained under (dominated by) part of speech nodes, and part of speech nodes are contained under (dominated by) phrasal nodes. For any complex expression, aside from the highest node, every node is ordered to some other node according to the relations of either dominance or precedence (but not both at the same time). The main unit used for describing sentences is the clause. Clauses get the node description ‘IP’ (inflectional phrase), as well as an extension to mark clause type: matrix (-MAT), adverbial (-ADV), relative (-REL), etc. Clauses typically contain a predicate (e.g., a verb or predicate phrase) plus a set of one or more argument positions. The number of positions in a clause depends on the meaning of the predicate in the clause, but there is typically one position for a subject. Positions that are unexpressed in the text may be assigned nodes with null elements, or they may be left empty to inherit the contribution of a non-local argument position. Clauses may also contain modifiers and complements.

     Linking structure and semantics sets constraints on how the whole corpus is designed. Starting from the semantic requirements, at a very basic level, discourse referents need to be introduced as parts (variables or constants) of resulting logical expressions, and there must also be the means for introduced discourse referents to find their way to the appropriate argument slots of predicates, where predicates are used to instantiate the contributions of nouns, verbs, adjectives, adverbs, etc. Such introductions and their subsequent management have to be linked to the structures in the corpus. Needing to establish such links can actually simplify the structure of the corpus. This is a reflection of the fact that languages in general have fixed ways of keeping track of language components. In grammar, we see these facts as the reach (or lack of reach) of an argument dependency through structure, the marking of definiteness and specificity to project scope, accessibility conditions on anaphoric reference, etc.

     A core relation that the majority of clauses serve to instantiate concerns the relation of subject to predicate. We label nodes to indicate the function of the noun phrase with regard to the predicate. And we create a node that corresponds to the unit that their combination creates: a clause (‘IP’). Within the same clause, a subject and a predicate have a subject-predicate relationship. This is one kind of ‘local dependency’. For example, ‘A boy smiles.’ is annotated as in (1), with ‘A boy’ distinguished as the subject. There is also information in (1) to say ‘A boy’ introduces a "PERSON" discourse referent.

(1)

(IP-MAT (NP-SBJ;{PERSON} (D A)
                         (N boy))
        (VBP smiles)
        (PU .))

     Given such a parse tree, there is sufficient information to support calculating lexical properties without having to make reference to a lexicon or dictionary resource. In particular, there is information to resolve argument contributions and so obtain the information for the bindings that the predicates receive, e.g., to return the predicate logic formula of (2).

(2)

exists EVENT[2] PERSON[1].(boy(PERSON[1])
  and smiles(EVENT[2],PERSON[1]))

     In turn, the information made explicit with (2) can be returned to the tree annotation to present detailed indexing information for how sentence content is related, as demonstrated with (3).

(3)

(IP-MAT (NP-SBJ;{PERSON};<PERSON[1]> (D A)
                                     (N;<,PERSON[1]@h,> boy))
        (VBP;<,PERSON[1]@ARG0,EVENT[2]@EVENT,> smiles)
        (PU .))

     A key goal of the annotation is to arrive at a critical mass of information that, in acting collectively, is sufficient to resolve word contribution and indexing information. Although word sense and entity information will remain unknown when not explicitly annotated, what is provided is all the hook information for integrating such lexical content.

1.3   Overview

This manual is organised as follows.

     First, in Chapter 2, syntactic annotation is introduced. The chapter then describes tree transformations that are made to normalise this syntactic analysis. Such normalisation takes parsed data to a level where language particulars are regularised, having the consequence of providing a common interface supportive of further processing the syntactic annotation of different languages with corpus-wide coverage, illustrated with examples from English and Japanese.

     From the normalised analysis, semantic calculation is invoked in Chapter 3 to transform expressions into a target formal language. During this stage information about the allocation of binding dependencies (ie., the accessibility of discourse referents) is calculated to deliver Discourse Representation Structures (Kamp and Reyle 1993). Such output analysis makes explicit connective, predicate, argument and operator-binding information.


Chapter 2: Annotation and normalisation

This chapter starts by introducing syntactic annotation in section 2.1. Applying the annotation produces a language-specific syntactic analysis of the source text. Section 2.2 marks a shift in the discussion, to detail considerations of ‘normalising’ the annotation. The described tree normalisation preserves the information encoded in syntactic structures but expresses that information with a reduced number of structures and categories.

     Section 2.3 changes normalised trees into Prolog terms (<normalised_expr>s). This involves a re-write step to transform node labels into Prolog structures and integrate information about ‘fresh’ and ‘local’ parameters inferable from the normalised tree annotation. Also at this stage, there is creation and integration of ‘discourse referents’ into the resulting structures.

     Once reached, <normalised_expr>s are themselves processed to create expressions of the Scope Control Theory (SCT) language (<sct_expr>s) introduced in section 2.5. This intermediate language has a reduced inventory of Prolog structures on which the semantic calculation mechanism described in Chapter 3 will directly operate. Prolog statements that assist reaching <sct_expr>s from <normalised_expr>s are detailed in section 2.6, with the transformation routine presented in section 2.7.

2.1   Annotation

This section presents an approach to syntactic analysis which, in essence, is an adaptation of the Penn Historical parsing scheme (Santorini 2016), with extensions to specify multi-word expressions and clause linkage types following Sampson (1995), as well as provide markings to establish scope placements. There is also the addition of ‘sort’ information to elements for tracking anaphora, which is able to result in the resolution of anaphoric elements, such as pronouns, when antecedents are accessible in the sense of Discourse Representation Theory (Kamp and Reyle 1993). Finally, a way is given to integrate sense/role disambiguation information, e.g., from lexical semantic annotation frameworks like PropBank and FrameNet. All these aspects of the syntactic annotation are sketched in sections 2.1.1--2.1.8 as forming different layers of information:

  1. Word segmentation and classification (includes ‘multi-word’ tagging)
  2. Labelled bracketing of segments
  3. Indicating grammatical function
  4. Clause linkage types
  5. Scope marking
  6. Null elements
  7. Tracking anaphora
  8. Sense/role disambiguation

This ordering of layers represents a loose hierarchy of informational detail, such that a ‘higher’ layer cannot be added unless a ‘lower’ (i.e. more basic) layer is already available: e.g., 2 is an essential pre-requisite for 3. While it is possible to track anaphora or indicate sense/role disambiguation without the other kinds of information, this would necessitate providing explicit indexing information. A major virtue of the current annotation method is that these high levels of annotation are made possible without recourse to explicit indexing. This is only possible when there are the more basic layers of annotation in place to support the stage of semantic calculation detailed in Chapter 3 that derives as output the equivalence of indexing information.

2.1.1   Word segmentation and classification

A continuous segment is a word, and each word is assigned a part-of-speech (POS) tag --- in practice, the label of an open bracket ‘(LABEL’. A POS tag can be complex, having at least a core label, but potentially including extensions separated by hyphens, and in certain cases, semantic information in curly brackets set off with a semicolon. In (1), being especially relevant for parsing Japanese, particles (P) receive extensions to mark distinct contributions:

(1)

  P-COMP  - complementiser
  P-CONN  - connective with coordination or subordination
  P-FINAL - sentence final, e.g., marker of clause type
  P-OPTR  - operator
  P-ROLE  - marker of grammatical (syntactic or semantic) role

In (2), an article is coded for definiteness by adding semantic information:

(2)

(D;{DEF} the)

The POS tags for a language may be sufficiently fine-grained to mark syntactic features. For example, number (singular vs. plural) for English is distinguished in (3):

(3)

(N boy)
(NS boys)

When applied to the head word of a noun phrase, such number marking influences (when not otherwise given; see section 2.1.7) the ‘sort’ (e.g., singular "ENTITY" or plural "GROUP") of a generated lang variable (discourse referent) that the noun phrase serves to introduce into the discourse.

2.1.1.1   Multi-word expressions

In general, parsing operates on a word-by-word basis. For English, this follows the word-separating spaces of the written text. However, apart from quotation marks, there is an important exception to this principle: A sequence of words which behaves syntactically in an idiomatic way (e.g. ‘as long as’, ‘with regard to’, ‘and so on’) is word tagged by using the word tag appropriate for the sequence as a whole, while each of its components are separated by underscore characters in a single character string, as (4) demonstrates.

(4)

(P-CONN as_long_as)
(P-ROLE with_regard_to)
(ADV and_so_on)

That is, such word sequences are treated as single units for the purposes of parsing.

2.1.1.2   Punctuation

Punctuation points, quotation marks, and brackets (‘.’ ‘?’ ‘!’ ‘:’ ‘;’ ‘,’ ‘-’ ‘(’ ‘)’ etc.) are treated as words for the purposes of word tagging. This makes punctuation part of a sentence in its own right. The full stop which ends most sentences is treated as the last constituent of the highest ‘IP/CP/FRAG’. Other punctuation points and brackets are placed as high in the constituent structure as they can be, subject to other parsing conventions and rules.

2.1.2   Labelled bracketing of segments

Bracketing is a way of grouping together segments which are recognised as having a syntactic integrity as units of various kinds (sentences, clauses, phrases, words). Consider (5):

(5)
Everyone ate at a cafe.

Adding brackets to (5) results in (6), in which ‘a cafe’ is one unit within ‘at a cafe’. ‘Everyone’ is a unit in its own right. The outermost brackets indicate that the whole sentence is a unit. ‘ate’ is part only of the whole sentence unit.

(6)

((Everyone) ate (at (a cafe)) .)

This layer of information is the indication of the formal category of the non-terminal syntactic units or constituents identified by bracketing, which can be further refined with labels such as Noun Phrase (NP), Preposition/Postposition Phrase (PP), and Clause (IP). For example, the labelled analysis of (7) is the result of adding labels to (6).

(7)

(IP (NP Everyone)
    ate
    (PP at
        (NP a
            cafe))
    .)

For the phrase structure annotation, the following categories are assumed:

Annotation for a given language need not utilise all of these categories. For example, ADJP is not used in the annotation of Japanese, where adjectives project IP units.

2.1.2.1   Coordination

Coordination can be coded with the specification of clause linkage (see section 2.1.4 below), but for all other occurrences of coordination, including all non-clause level cases, coordination is marked with coordinated phrase structure involving CONJP units, following the schema of (8).

(8)

(XP (XP ...)
    (CONJP (XP ...))
    (CONJP and
           (XP ...)))

When coordination is marked with CONJP, intermediate phrase levels may be necessary, as the analysis of (9) in (10) illustrates with clause intermediate levels (IML) and noun phrase intermediate levels (NML).

(9)
Only John and Mary ate at either a cafe or a restaurant but drank at a bar.

(10)

(IP (NP Only
        (NML (NP John)
             (CONJP and
                    (NP Mary))))
    (IML (IML ate
              (PP at
                  (NP either
                      (NP a
                          cafe)
                      (CONJP or
                             (NP a
                                 restaurant)))))
         (CONJP but
                (IML drank
                     (PP at
                         (NP a
                             bar)))))
    .)

2.1.3   Indicating grammatical function

The grammatical function of a unit is identified by either:

  1. the combination of the head plus the structural position of that unit (e.g., a P-ROLE heading a PP may specify the function of that PP with respect to a predicate),
  2. the node description of that unit having hyphenated extensions with information about grammatical function, such as -SBJ for subjects, -LOC for locational adjuncts, etc., or
  3. having 1 supplemented by 2.

     Being a further refinement of annotation for (5), (11) illustrates Case 2 with its NP-SBJ at the clause level, as well as Case 3 with its PP having both the -LOC extension and P-ROLE head ‘at’. (For the sake of completeness, the part-of-speech labels QN, VBD, P-ROLE, D, N, and PU have also been added.)

(11)

(IP-MAT (NP-SBJ (QN Everyone))
        (VBD ate)
        (PP-LOC (P-ROLE at)
                (NP (D a)
                    (N cafe)))
        (PU .))

     At the clause level, all units (with the exception of scope marking units; see section 2.1.5) must have grammatical function information. Grammatical function information can in nature be either syntactic (e.g., -SBJ) or semantic (e.g., -LOC).

2.1.4   Clause linkage types

For the annotation of Japanese, a non-final clause that combines with an immediately following clause is specified as either being subordinated or coordinated to that following clause. This specification is carried out by means of syntactic function labels -SCON and -CONJ, respectively. The motivation for encoding coordination with the clause linkage type is that it becomes possible to preserve a flat clause layer, and so avoid IML layers of structure, e.g., seen in (7) above. This works for Japanese where the head final arrangement allows knowing both the start as well as the end of of all conjuncts. For example, (12) can be annotated as in (13), with its tari conjuncts stacked.

(12)
o-matsuri de, kakigoori o tabe tari, kingyo-sukui o shi tari,
festival loc, shaved-ice acc eat conj goldfish acc scoop conj
hanabi o mi tari shi mashi ta.
fireworks acc watch conj do hon past
‘At the festival, I ate shaved ice, scooped goldfish, watched fireworks, and so on.’

(13)

(IP-MAT (NP-SBJ *speaker*)
        (PP (NP (N o-matsuri))
            (P-ROLE de))
        (PU ,)
        (IP-ADV-CONJ (IP-ADV-CONJ (PP-OB1 (NP (N kakigoori))
                                          (P-ROLE o))
                                  (VB tabe)
                                  (P-CONN tari))
                     (PU ,)
                     (PP-OB1 (NP (N kingyo-sukui))
                             (P-ROLE o))
                     (VB shi)
                     (P-CONN tari))
        (PU ,)
        (PP-OB1 (NP (N hanabi))
                (P-ROLE o))
        (VB mi)
        (P-CONN tari)
        (VB2 shi)
        (AX mashi)
        (AXD ta)
        (PU .))

2.1.5   Scope marking

The annotation of (11) without further alteration gives the narrow scope reading for ‘a cafe’ relative to ‘everyone’. The wide scope reading for ‘a cafe’ in (5) can be captured with the alternative annotation of (14).

(14)

(IP-MAT (NP *ICH*-1)
        (NP-SBJ (QN Everyone))
        (VBD ate)
        (PP-LOC (P-ROLE at)
                (NP-1 (D a)
                      (N cafe)))
        (PU .))

By contrast, with the annotation for (15) given in (16), a wide scope reading for ‘the cafe’ is the default, triggered by ‘;{DEF}’.

(15)
Everyone ate at the cafe.

(16)

(IP-MAT (NP-SBJ (QN Everyone))
        (VBD ate)
        (PP-LOC (P-ROLE at)
                (NP (D;{DEF} the)
                    (N cafe)))
        (PU .))

2.1.6   Null elements

The introduction of null elements of various kinds may be necessary to express argument structures fully and to track non-local relations. Null pronouns (*pro*, *speaker*, *hearer*, etc.) may be inserted to indicate otherwise missing arguments, e.g., as demonstrated by *speaker* in (13), above. When relative clauses have no relative pronoun, a trace *T* is inserted to mark the contribution of the modified head noun within the relative clause. For example, (17) is annotated as in (18).

(17)

John wrote the book Mary proofread.

(18)

(IP-MAT (NP-SBJ (NPR John))
        (VBD wrote)
        (NP-OB1 (D;{DEF} the)
                (N book)
                (IP-REL (NP-OB1 *T*)
                        (NP-SBJ (NPR Mary))
                        (VBD proofread)))
        (PU .))

2.1.7   Tracking anaphora

Co-valuation between noun phrases (most typically between an overt antecedent and a following pronoun) is expressed by the use of ‘sort’ information that is placed between curly brackets and appended to the noun-phrase level tag. Both overt and null pronouns can have their reference resolved by this means. This can be illustrated with the annotation for (5) in (19) followed by annotation for (20) in (21) to create a mini discourse in which It is able to take a cafe of the prior sentence as antecedent.

(19)

(IP-MAT (NP *ICH*-1)
        (NP-SBJ;{PERSON} (QN Everyone))
        (VBD ate)
        (PP-LOC (P-ROLE at)
                (NP;{BETTYS}-1 (D a)
                               (N cafe)))
        (PU .))

(20)

It sold great cake.

(21)

(IP-MAT (NP-SBJ;{BETTYS} (PRO It))
        (VBD sold)
        (NP-OB1 (ADJ great)
                (N cake))
        (PU .))

2.1.8   Sense/role disambiguation

This layer of information characterises dependent-target relations by assigning a semantic frame to a predicate and specifying the roles of the participants in that frame. For example the annotation for (5) in (19) can be further refined to give (22).

(22)

(IP-MAT (NP *ICH*-1)
        (NP-SBJ;{PERSON} (QN Everyone))
        (VBD ate)
        (FRAME (LU *4807*)
               (ARG0 *Ingestor*)
               (LOC_at *Place*))
        (PP-LOC (P-ROLE at)
                (NP;{BETTYS}-1 (D a)
                               (N cafe)))
        (PU .))

2.2   Tree normalisation

The structures specific to a given language encode more general grammatical relations. In a program that expresses basic grammatical relations in predicate logic, language-specific structures must first be normalised into forms that integrate into a semantic calculation. This initial normalisation regularises structure and reduces the inventory of tag labels, while redistributing information from basic grammatical categories into offset elements. For example, NP-SBJ tags are changed into NP tags which are placed under a PP projection that contains (P-ROLE ARG0) to retain the contribution of -SBJ. As a consequence, all arguments are PP projections with role information, so, e.g., (PP-LOC (P-ROLE at) (NP (D a) (N cafe))) of (11) warrants no structural change, but still there is repositioning of the semantic tag -LOC to further specify the semantic contribution of the sourced ‘at’, as illustrated by the normalisation of (11) in (23).

(23)

(IP-MAT (ACT past)
        (PP (P-ROLE ARG0)
            (NP (ACT *INDEF*)
                (Q Everyone)))
        (VB ate)
        (PP (P-ROLE LOC_at)
            (NP (D a)
                (N cafe)))
        (PU .))

Note also that VBD (past tense verb) is changed with normalisation to VB in (23). The otherwise lost tense information is retained with the offset (ACT past) at the clause level.

     As part of reducing the inventory of tag labels, tags accompanied by -CONJ as described in section 2.1.4 lead to the introduction of CONJP structure. For example, normalisation changes (13) into (24).

(24)

(IP-MAT (PP (P-ROLE ARG0)
            (NP (SORT *speaker*)
                (PRO *speaker*)))
        (PP (P-ROLE de)
            (NP (N o-matsuri)))
        (PU ,)
        (IML (CONJP (IML (ACT past)
                         (PP (P-ROLE ARG1)
                             (NP (N kakigoori)))
                         (VB tabe_tari)))
             (CONJP (IML (ACT past)
                         (PU ,)
                         (PP (P-ROLE ARG1)
                             (NP (N kingyo-sukui)))
                         (VB shi_tari)))
             (IML (ACT past)
                  (PU ,)
                  (PP (P-ROLE ARG1)
                      (NP (N hanabi)))
                  (VB mi_tari_shi_mashi_ta)))
        (PU .))

     Other changes brought by normalisation include restructuring content to eliminate instances of coindexed *ICH*. Such elimination can happen either by:

  1. *ICH* being made into a binding operation, and the coindexed element into a bound element; or
  2. the coindexed element being made into a binding operation, and *ICH* into a bound element; or
  3. the full relocation of the coindexed element to the *ICH* site.

     Option 1 for eliminating *ICH* occurs when the coindexed element is a binding item with role information and when there is only one *ICH* instance that is not accompanied by role information and that occurs higher in the structure than the coindexed element. To be a coindexed *ICH* without role information amounts to having the bare form (NP *ICH*-N). To be higher amounts to being either in a layer that dominates the coindexed element or to have placement to the left of the coindexed element in the same layer. Such a scenario holds for (19) above, which gives (25) following normalisation.

(25)

(IP-MAT (ACT past)
        (PP (P-ROLE *T1*)
            (NP (SORT *BETTYS*)
                (D a)
                (N cafe)))
        (PP (P-ROLE ARG0)
            (NP (ACT *INDEF*)
                (SORT *PERSON*)
                (Q Everyone)))
        (VB ate)
        (PP (P-ROLE LOC_at)
            (NP *T1*))
        (PU .))

Notably, in the change from (19) to (25),

  (NP *ICH*-1)

has become the binding operation

  (PP (P-ROLE *T1*)
      (NP (SORT *BETTYS*)
          (D a)
          (N cafe)))

and

  (PP-LOC (P-ROLE at)
          (NP;{BETTYS}-1 (D a)
                         (N cafe)))

has become the bound element

  (PP (P-ROLE LOC_at)
      (NP *T1*))

     Option 2 for eliminating *ICH* occurs when the coindexed element is a binding item that is not accompanied by role information and when *ICH* is accompanied by role information and occurs lower in the structure than the coindexed element. To be lower amounts to being either in a layer that is subordinate to the coindexed element or to have placement to the right of the coindexed element in the same layer. In such cases, there can be multiple *ICH* sites. For example, the described configuration holds for annotation of (26) in (27).

(26)
Development of and research with a Parsed Corpus of Modern Japanese

(27)

(FRAG (NP (NML (NP (N Development)
                   (PP (P-ROLE of)
                       (NP *ICH*-1)))
               (CONJP (CONJ and)
                      (NP (N research)
                          (PP (P-ROLE with)
                              (NP *ICH*-1)))))
          (NP-1 (D a)
                (IP-PPL (NP-LGS *)
                        (VVN Parsed))
                (N Corpus)
                (PP (P-ROLE of)
                    (NP (ADJ Modern)
                        (N Japanese))))))

With normalisation, (27) becomes (28).

(28)

(IP-MAT (PP (P-ROLE LINK_)
            (NP (PP (P *T1*)
                    (NP (PP (P-ROLE of)
                            (NP (ADJP (SORT *ATTRIB*)
                                      (LINK *ATTRIBUTE*)
                                      (ADJ Modern))
                                (N Japanese)))
                        (D a)
                        (IP-ADV (ACT passive)
                                (VB Parsed))
                        (N Corpus)))
                (NP-SUM (NP (PP (P-ROLE of)
                                (NP *T1*))
                            (N Development))
                        (CONJP (CONJ and)
                               (NP (PP (P-ROLE with)
                                       (NP *T1*))
                                   (N research)))))))

Notably, the instances of *ICH*-1 have become the bound elements (NP *T1*).

     Option 3 for eliminating *ICH* can be illustrated with annotation for (29) given in (30) where the coindexed item is a PP layer, which is a layer of structure with already saturated role information.

(29)
John wrote the book of which Mary proofread a chapter.

(30)

(IP-MAT (NP-SBJ (NPR John))
        (VBD wrote)
        (NP-OB1 (D;{DEF} the)
                (N book)
                (IP-REL (PP-1 (P-ROLE of)
                              (NP (WPRO which)))
                        (NP-SBJ (NPR Mary))
                        (VBD proofread)
                        (NP-OB1 (D a)
                                (N chapter)
                                (PP *ICH*-1))))
        (PU .))

With normalisation, (30) becomes (31), with full relocation of the coindexed PP to the *ICH* site.

(31)

(IP-MAT (ACT past)
        (PP (P-ROLE ARG0)
            (NP (NPR John)))
        (VB wrote)
        (PP (P-ROLE ARG1)
            (NP (ACT *DEF*)
                (D the)
                (N book)
                (CP-REL (IP-SUB (ACT past)
                                (PP (P-ROLE ARG0)
                                    (NP (NPR Mary)))
                                (VB proofread)
                                (PP (P-ROLE ?e)
                                    (NP *T*))
                                (PP (P-ROLE ARG1)
                                    (NP (PP (P-ROLE of)
                                            (NP (WPRO which)))
                                        (D a)
                                        (N chapter)))))))
        (PU .))

Example (30) also illustrates the case of a relative clause with an overt relative pronoun. A relative pronoun is captured as being a WH pronoun, with the behaviour of creating a binding from an ?e source and bringing about its integration as an of-binding for chapter. In order for the relative pronoun to function as the device for integrating the head binding of the relative clause, normalisation adds extra content (PP (P-ROLE ?e) (NP *T*)) before the relative pronouns occurrence. Containing *T*, as seen with the relative clause in section 2.1.6, this ensures the head binding is integrated as the next binding to be taken from the ?e source, and so to be the binding that the relative pronoun integrates.

2.3   Normalisation to Prolog terms

A Prolog term is either a variable (denoted by a capitalised identifier), a constant (denoted by a non-capitalised identifier), or a structure of the form f(t_1 ... t_n) where f is a symbol called a functor (denoted as a constant), and the t_i's are terms --- the term's subterms. The number of subterms for a given functor symbol is predetermined and called its arity. Two functors are equal if and only if they have the same symbol and arity. The explicit notation ‘f/n’ refers to the functor consisting of the symbol f with arity n. Letting n = 0, a constant is seen as a special case of a structure. Thus, a constant c will be designated as the functor c/0.

     Normalisation to a Prolog term creates a <normalised_expr>, where:

(32)

<normalised_expr> ::=
         <sct_structure_mapping>
      |  fresh(<fresh_list>, <normalised_expr>)
      |  local(<local_list>, <normalised_expr>)
      |  close(<q_operator>, <normalised_expr>)
      |  verb(<fresh_string>, <discourse_referent>, <relation_string>,
           <normalised_expr_list>)
      |  past(<fresh_string>, <normalised_expr>)
      |  passive(<normalised_expr>)
      |  pred(<relation_string>, <normalised_expr_list>)
      |  relation(<relation_string>, <normalised_expr_list>)
      |  npr(<discourse_referent>, <local_string>, <normalised_expr>)
      |  some(<fresh_string>, <discourse_referent>, <normalised_expr>,
           <local_string>, <normalised_expr>)
      |  quant(<q_operator>, <fresh_string>, <discourse_referent>,
           <normalised_expr>, <local_string>, <normalised_expr>)
      |  someClassic(<fresh_string>, <discourse_referent>, <normalised_expr>,
           <local_string>, <normalised_expr>)
      |  someFact(<fresh_string>, <relation_string>, <discourse_referent>,
           <normalised_expr>, <local_string>, <normalised_expr>)
      |  pro(<pick_string_list>, <sort_list>, <fresh_string>,
           <selection_string>, <discourse_referent>, <local_string>,
           <normalised_expr>)
      |  conjNpSum(<fresh_string>, <relation_string>, <discourse_referent>,
           <np_expr_list>, <local_string>, <normalised_expr>)
      |  conjNp(<relation_string>, <np_expr_list>, <local_string>,
           <normalised_expr>)
      |  conjPp(<relation_string>, <pp_expr_list>, <normalised_expr>)
      |  parenthetical(<fresh_string>, <pp_expr>, <np_expr>, <local_string>,
           <normalised_expr>)
      |  embed(<normalised_expr>)
      |  control(<normalised_expr>)
      |  control2(<normalised_expr>)
      |  connect(<relation_string>, <normalised_expr_list>)
      |  join(<relation_string>, <normalised_expr>, <normalised_expr>)
      |  scon(<relation_string>, <normalised_expr>, <normalised_expr>)
      |  scon_right(<relation_string>, <normalised_expr>, <normalised_expr>)
      |  cond(<fresh_string>, <relation_string>, <normalised_expr>,
           <normalised_expr>)
      |  cond_right(<fresh_string>, <relation_string>, <normalised_expr>,
           <normalised_expr>)
      |  question(<normalised_expr>)
      |  neg(<normalised_expr>)
      |  md(<relation_string>, <normalised_expr>)

<sct_structure_mapping> ::=
         t(<grammar_string>)
      |  at(<normalised_expr>, <role_string>)
      |  lam(<grammar_string>, <grammar_string>, <normalised_expr>)
      |  wipe(<fresh_string>, <normalised_expr>)
      |  bodyClimb(<fresh_string>, <normalised_expr>)

<np_expr> ::=
      |  npr(<discourse_referent>)
      |  some(<fresh_string>, <discourse_referent>, <normalised_expr>)
      |  quant(<q_operator>, <fresh_string>, <discourse_referent>,
           <normalised_expr>)
      |  someClassic(<fresh_string>, <discourse_referent>, <normalised_expr>)
      |  someFact(<fresh_string>, <relation_string>, <discourse_referent>,
           <normalised_expr>)
      |  pro(<pick_string_list>, <sort_list>, <fresh_string>,
           <selection_string>, <discourse_referent>)
      |  conjNpSum(<fresh_string>, <relation_string>, <discourse_referent>,
           <np_expr_list>)
      |  conjNp(<relation_string>, <np_expr_list>)
      |  parenthetical(<fresh_string>, <pp_expr>, <np_expr>)

<np_expr_list> ::=
         []
      |  <np_expr> . <np_expr_list>

<pp_expr> ::=
      |  npr(<discourse_referent>, <local_string>)
      |  some(<fresh_string>, <discourse_referent>, <normalised_expr>,
           <local_string>)
      |  quant(<q_operator>, <fresh_string>, <discourse_referent>,
           <normalised_expr>, <local_string>)
      |  someClassic(<fresh_string>, <discourse_referent>, <normalised_expr>,
           <local_string>)
      |  someFact(<fresh_string>, <relation_string>, <discourse_referent>,
           <normalised_expr>, <local_string>)
      |  pro(<pick_string_list>, <sort_list>, <fresh_string>,
           <selection_string>, <discourse_referent>, <local_string>)
      |  conjNpSum(<fresh_string>, <relation_string>, <discourse_referent>,
           <np_expr_list>, <local_string>)
      |  conjNp(<relation_string>, <np_expr_list>, <local_string>)
      |  conjPp(<relation_string>, <pp_expr_list>)
      |  parenthetical(<fresh_string>, <pp_expr>, <np_expr>, <local_string>)

<pp_expr_list> ::=
         []
      |  <pp_expr> . <pp_expr_list>

<fresh_list> ::=
         []
      |  <fresh_string> . <fresh_list>

<local_list> ::=
         []
      |  <local_string> . <local_list>

<pick_string_list> ::=
         []
      |  <local_string> . <pick_string_list>
      |  <context_string> . <pick_string_list>

<sort_list> ::=
         []
      |  <sort_string> . <sort_list>

<grammar_string> ::=
         <fresh_string>
      |  <local_string>
      |  <context_string>

<discourse_referent> ::=
         x(<sort_string>, <integer>)
      |  c(<sort_string>, <constant_string>)

     Prolog terms derived from normalised annotation are either direct structural mappings to the SCT language (t/1, at/2, lam/3, wipe/2, and bodyClimb/2; see section 2.5), or “higher level” structures to realise:

     Discourse referents can be either bound variables (x/2) or constants (c/2). A variable has an integer parameter and a string parameter. The integer identifies the variable, while the string is a specification from a sorted ontology. For example, x(1, "PERSON") is the person variable ‘1’, while x(2, "EVENT") is the event variable ‘2’. A constant has two string parameters. The first identifies the constant, while the second is sort information. Thus c("John", "PERSON") denotes the person named ‘John’.

     As an example of how to reach a Prolog term from a normalised tree, consider the normalised tree (23). This can be broken into tree fragments, as shown below on the left hand side, which can be re-written to the Prolog terms shown on the right hand side:

(33)

NP in:                                   NP out:
(NP (ACT *INDEF*)                        quant( "EVERYONE",".e",
    (Q Everyone))                               x( "ENTITY",1)
                                                ,
                                                local( .( "h",[])
                                                       ,
                                                       pred( "",[]))
                                                ,__X__,
                                                __E__)__LOCAL__

With this first step (Q Everyone) is re-written to the quant/6 structure, with "EVERYONE" as the <q_operator> (quantificational operator). This re-write also triggers creation of x("ENTITY",1) as a <discourse_referent>. The presence of (ACT *INDEF*) gives ".e" as value for the <fresh_string> parameter. In the resulting Prolog term, pred("",[]) reflects the lack of restriction material in the source NP. Note the returned structure is only partially complete, with __X__ and __E__ as place holders for a <local_string>, and for a <normalised_expr>, respectively. Note also the presence of __LOCAL__ which is used as a divider, to keep track of the assembled expression to the left, and a list of known <local_string>s to the right, the latter being empty here.

     With the next step __X__ is re-written to the <local_string> "ARG0" sourced from (P-ROLE ARG0). Note how "ARG0", as an active <local_string>, is also stored to the right of __LOCAL__:

(34)

PP in:                                   PP out:
(PP (P-ROLE ARG0)                        quant( "EVERYONE",".e",
    quant( "EVERYONE",".e",                     x( "ENTITY",1)
           x( "ENTITY",1)                       ,
           ,                                    local( .( "h",[])
           local( .( "h",[])                           ,
                  ,                                    pred( "",[]))
                  pred( "",[]))                 ,"ARG0",
           ,__X__,                              __E__)__LOCAL__"ARG0"
           __E__)__LOCAL)

     With a third step information is accumulated for the predicate rendering of (N cafe):

(35)

N in:                                    N out:
(N cafe)                                 pred( "cafe",[])

     In a fourth step, the NP for which (N cafe) provides the restrictive content is filled out by a some/5 structure as the re-writing of (D a), and includes generation of x("ENTITY",2) as a <discourse_referent>:

(36)

NP in:                                   NP out:
(NP (D a)                                some( ".e",
    pred( "cafe",[]))                          x( "ENTITY",2)
                                               ,
                                               local( .( "h",[])
                                                      ,
                                                      pred( "cafe",[]))
                                               ,__X__",
                                               __E__)__LOCAL__

     A fifth step sees the PP completed with (P-ROLE LOC_at) providing information to re-write __X__ as "LOC_at", which is also stored to the right of __LOCAL__:

(37)

PP in:                                   PP out:
(PP (P-ROLE LOC_at)                      some( ".e",
    some( ".e",                                x( "ENTITY",2)
          x( "ENTITY",2)                       ,
          ,                                    local( .( "h",[])
          local( .( "h",[])                           ,
                 ,                                    pred( "cafe",[]))
                 pred( "cafe",[]))             ,"LOC_at",
          ,__X__",                             __E__)__LOCAL__"LOC_at"
          __E__)__LOCAL__)

     In a sixth step the contribution of (ACT past) is fleshed out:

(38)

PAST in:                                 PAST out:
(ACT PAST)                               past( ".event", __E__)

     In a seventh step the main verb is rendered. This includes information gathered from the local tree concerning "LOC_at" and "ARG0" as arguments. Note also ".event" as the <fresh_string> value, and the creation of x("EVENT",3) as an event <discourse_referent>:

(39)

VB in:                                    VB out:
(VB ate)                                  verb( ".event",
                                                x( "EVENT",3)
                                                ,"ate",
                                                .( "LOC_at",
                                                   .( "ARG0",[])))

     With all parts of the clause now re-written to Prolog terms, the final step is to bring these parts together by substituting the instances of __E__ for Prolog term content. A matrix clause is then topped with local/2 to list the active <local_string>s from __LOCAL__.

(40)

IP-MAT in:                           IP-MAT out:
(IP-MAT past( ".event", __E__)       local( .( "ARG0",
        quant( "EVERYONE",".e",                .( "LOC_at",[]))
               x( "ENTITY",1)               ,
               ,                            quant( "EVERYONE",".e",
               local( .( "h",[])                   x( "ENTITY",1)
                      ,                            ,
                      pred( "",[]))                local( .( "h",[])
               ,"ARG0",                                   ,
               __E__)__LOCAL__"ARG0"                      pred( "",[]))
        verb( ".event",                            ,"ARG0",
              x( "EVENT",3)                        some( ".e",
              ,"ate",                                    x( "ENTITY",2)
              .( "LOC_at",                               ,
                 .( "ARG0",[])))                         local( .( "h",[])
        some( ".e",                                             ,
              x( "ENTITY",2)                                    pred( "cafe",[]))
              ,                                          ,"LOC_at",
              local( .( "h",[])                          past( ".event",
                     ,                                         verb( ".event",
                     pred( "cafe",[]))                               x( "EVENT",3)
              ,"LOC_at",                                             ,"ate",
              __E__)__LOCAL__"LOC_at"                                .( "LOC_at",
        (PU .))                                                   .( "ARG0",[])))))))

2.4   Strings with grammatical roles

A character string that is part of a <normalised_expr> has a grammatical role (i.e. is a <grammar_string>) when it is either:

     The significance of these roles will emerge when we transform to <sct_expr>s (see section 2.5), and still more when we undertake semantic calculations in chapter 3. Briefly:

     What is important for now is to keep these strings with there differing roles distinct. Separation is achieved by listing <fresh_string>s with fresh/2, and <local_string>s with local/2. Any character string not listed by the commanding instances of fresh/2 and local/2 might be used as a <context_string>.

     There is typically only one declaration of <fresh_string>s with fresh/2 for the <normalised_expr> of a full discourse, occuring as the topmost structure of the discourse encoding.

     In addition to the separation achieved with fresh/2 and local/2, <fresh_string>s will follow the conventions of being prefixed with:

Notable examples are: "@e" (source for definite entities), ".e" (source for indefinites entities), "?e" (source for entities under question), "@event" (source for definite events), ".event" (source for indefinite events), etc.

2.5   Intermediate language

Section 2.3 allows for the gap between normalised annotation and Prolog terms to be bridged with a re-writing step. But the Prolog terms reached are not sufficiently fine grained to feed the semantic calculation of chapter 3, and must first be transformed into terms of the SCT language, defined in this section. An <sct_expr> is an <sct_expr>, where:

(41)

<sct_expr> ::=
         <drs_structure_mapping>
      |  namely(<discourse_referent>, <fresh_string>, <sct_expr>)
      |  wipe(<fresh_string>, <sct_expr>)
      |  <sct_term>
      |  at(<sct_expr>, <role_string>)
      |  rel(<fresh_list>, <context_list>, <relation_string>, <sct_expr_list>)
      |  ifThere(<grammar_string>, <sct_expr>, <sct_expr>)
      |  lam(<grammar_string>, <grammar_string>, <sct_expr>)
      |  clean(<integer>, <local_list>, <context_string>, <sct_expr>)
      |  pick(<selection_string>, <sct_term>, <pick_string_list>,
           <sort_list>)

<drs_structure_mapping> ::=
         head(<q_operator>, <fresh_list>, <sct_expr>)
      |  body(<fresh_list>, <sct_expr>)
      |  headClimb(<discourse_referent>, <fresh_string>, <sct_expr>)
      |  bodyClimb(<fresh_string>, <sct_expr>)

<sct_term> ::= t(<grammar_string>)

<sct_expr_list> ::=
         []
      |  <sct_expr> . <sct_expr_list>

<context_list> ::=
         []
      |  <context_string> . <context_list>

     With semantic calculations, these language primitives assemble content for expressions of a target discourse representation language (<target_expr>s; see section 3.4), while possibly altering the content of an information state (see section 3.2). The following provides an informal overview of what the various primitives contribute:

     The significance of these SCT functors will become apparent when they are used in instantiations of <sct_expr>s, the first of which are introduced in section 2.6.

2.6   Basic grammar statements

This section defines Prolog statements to assist <sct_expr> construction in section 2.7.

2.6.1   Building predicates

First, consider build_args(L1, L2), where L1 is a list of either strings or <sct_expr>s, and L2 is the same list as L1, only with the strings converted into <sct_expr>s, with each string from L1 functioning as: (i) the <grammar_string> of an <sct_term> and, (ii) the <role_string> of an at/2 structure with the term embedded.

(42)

build_args([], []).
build_args([A0|As0], As) :-
  ( string(A0) ->
    As = [at(t(A0), A0)|As1]
  ;
    As = [A0|As1]
  ),
  build_args(As0, As1).

For example:

(43)

|?- build_args(["foo", at(t("bar"), "bar")], L).
L = [at(t("foo"), "foo"), at(t("bar"), "bar")]
Yes

     Now consider build_predicate/4 as a means to create predicates from SCT primitive rel/4 together with the range of potential arguments for the predicate (via build_args/2), and the selectional criteria for choosing between the produced arguments (via ifThere/2 for the semantic calculation to check the status of assigned content).

(44)

build_predicate([], L, S, rel([], [], S, Args)) :-
  build_args(L, Args).
build_predicate([H|T], L, S, ifThere(H, PredA, PredB)) :-
  build_predicate(T, [H|L], S, PredA),
  build_predicate(T, L, S, PredB).

For example, (45) illustrates ["foo", "bar"] as a candidate list for the construction of arguments for a "foobar" predicate:

(45)

|?- build_predicate(["foo", "bar"], [], "foobar", P).
P =
ifThere( "foo",
         ifThere( "bar",
                  rel( [],[],"foobar",
                       [at( t( "bar"),"bar")
                       ,
                       at( t( "foo"),"foo")
                       ])
                  ,
                  rel( [],[],"foobar",
                       [at( t( "foo"),"foo")
                       ]))
         ,
         ifThere( "bar",
                  rel( [],[],"foobar",
                       [at( t( "bar"),"bar")
                       ])
                  ,
                  rel( [],[],"foobar",[])))
Yes

The instantiation of P gives two layers of ifThere/3 structures that are tests to choose between four different potential realisations of the "foobar" predicate, each with a different valency that either includes or excludes arguments constructed from "foo" and "bar".

     The appeal of build_predicate/4 is that there need be nothing in a predicate specification per se to determine what its arguments are going to be. Instead, there is the creation of all potential argument options, and it is left to the semantic calculation to make a final selection on the basis of which arguments have assigned content.

     With such an outlook there is no need for reference to a dictionary or lexicon to retrieve valence information for predicates. On the other hand, given an external resource, there is the prospect of grammaticality effects emerging when what is predicted by the resource differs from what is available from the assignment state during the runtime of a semantic calculation.

2.6.2   Enabling subordination

Natural languages work by repeatedly (re-)using the same grammatical resources. For example, with each new clause there is, with the absence of control, the introduction of a subject. With the semantic calculation, the occurrence of a subject adds a <discourse_referent> to the difference list assigned to the <local_string> "ARG0". Because clauses can be embedded inside clauses, there needs to be a separation of the content assigned to "ARG0" for a higher clause from the content assigned to "ARG0" in the lower clause. Such separation will be accomplished with make_subord/6.

(46)

make_subord(N, D, Ls, Keep, E, clean(N, Remove, D, E)) :-
  subtract(Ls, Keep, Remove).

This creates a clean/4 structure that takes integer N, <local_list> Remove (formed from the <local_list> Ls with any elements also contained in Keep subtracted by subtract/3), the <context_string> D, and <sct_expr> E. At the runtime of a semantic calculation, this will send difference list content assigned to the strings of Remove to the difference list that is assigned to D, such that the difference lists that remain assigned to the strings of Remove will have a resulting length of N when evaluation continues with E. When N = 0, strings of Remove will be assigned empty difference lists going into E.

2.6.3   Making closures

make_closure brings about an Oper closure with scope over expression E, that applies to the <fresh_string>s from Fs. Such closure involves the combination of a head/3 placed above a body/2, with both receiving the same <fresh_string>s via the Fs parameter.

(47)

make_closure(Oper, Fs, E, head(Oper, Fs, body(Fs, E))).

     select_closures(Cs, A, R0, R) is defined to pick out with the R0 and R difference the <fresh_string>s that are applicable with a given closure (the Fs content for (47)), based on those candidates from list A that share a character as prefix with the characters listed in Cs.

(48)

select_closures([], _A, R, R).
select_closures([C|Cs], A, R0, R) :-
  char_filter(C, A, R0, R1),
  select_closures(Cs, A, R1, R).

char_filter(_C, [], R, R).
char_filter(C, [A0|As0], R, As) :-
  string_chars(A0, [H|_]),
  ( H == C ->
    As = [A0|As1]
  ;
    As = As1
  ),
  char_filter(C, As0, R, As1).

     select_most_closures/3 has potential to create a fuller range of closure than only select_closures/4:

(49)

select_most_closures(S, Fresh, Selected) :-
  string_chars(S, [H|_]),
  ( H == '.' ->
    select_closures(['.'], Fresh, [], Selected)
  ; H == '@' ->
    select_closures(['@', '.'], Fresh, [], Selected)
  ; H == '?' ->
    select_closures(['?'], Fresh, [], Selected)
  ;
    Selected = []
  ).

Notably, "@" triggers selection of all strings from Fresh with either "@" or "." as first character.

2.7   Transformations

This section provides the transformation for reaching SCT structures from the Prolog terms of section 2.3 derived following tree normalisation. Transformation takes place against an environment that holds information about the available <grammar_string>s. The simplest transformations are direct mappings onto SCT structures, that make no use of the environment:

(50)

transform(_, t(X), t(X)).

transform(Env, at(Norm, S), at(E, S)) :-
  transform(Env, Norm, E).

transform(Env, lam(V, X, Norm), lam(V, X, E)) :-
  transform(Env, Norm, E).

transform(Env, wipe(X, Norm), wipe(X, E)) :-
  transform(Env, Norm, E).

transform(Env, bodyClimb(V, Norm), bodyClimb(V, E)) :-
  transform(Env, Norm, E).

In the coming subsections, we work through the other structures of section 2.3.

2.7.1   Settings for ‘fresh’ and ‘local’ parameters

As mentioned already, transformation takes place against an environment that holds information about the available <grammar_string>s. This has the form env(Fs, Ds, D, Ls), with D as the (unchangeable) <context_string>. The other values are (re-)set by fresh/2 and local/2 structures. Specifically, fresh/2 changes Fs (<fresh_list>) and Ds (<context_list>), with Ds a list of D instances with the length of the new Fs:

(51)



transform(env(_, _, D, Ls), fresh(Fs, Norm), E) :-
  (
    foreach(_, Fs),
    foreach(C, Ds),
    param(D)
  do
    C = D
  ),
  transform(env(Fs, Ds, D, Ls), Norm, E).

local/2 changes the Ls (<local_list>) parameter:

(52)



transform(env(Fs, Ds, D, _), local(Ls, Norm), E) :-
  transform(env(Fs, Ds, D, Ls), Norm, E).

2.7.2   Closure

Closure makes use of fresh_strings via the Fs parameter of the env/4 environment, with make_closure/4 (see section 2.6.3) to assemble <sct_expr> content.

(53)

transform(env(Fs, Ds, D, Ls), close(Oper, Norm), E) :-
  transform(env(Fs, Ds, D, Ls), Norm, E0),
  make_closure(Oper, Fs, E0, E).

2.7.3   Verbs

Realised with verb/4, a verb transforms to a predicate with the distinction of carrying minimally a bound Event term with "EVENT" argument role, that, moreover, has its binding assured by namely introducing (<discourse_referent>) DRef. Understanding of the function of namely will emerge as more of the system of semantic calculation is introduced (notably, see sections 3.1 and 3.3). Here it is enough to know that its presence ensures that DRef will head the difference list assigned to Event at the instance during the semantic calculation when the verb is reached. Furthermore, if Args0 --- the list of required arguments for the verb --- contains an argument that is an embedding (i.e. a non-string argument), then DRef will shift (via lam/3) to D (<context_string>) when the embedding is reached. Aside from the required arguments of Args0, build_predicate/4 (see section 2.6.1) assembles the range of potential additional arguments based on Ls (the local_strings of the environment) with any Args0 overlap subtracted.

(54)

transform(env(Fs, Ds, D, Ls), verb(Event, DRef, S, Args0), namely(DRef, Event, P)) :-
  (
    foreach(A0, Args0),
    foreach(A, Args),
    param(Fs, Ds, D, Ls, Event)
  do
    ( string(A0) ->
      A = A0
    ;
      transform(env(Fs, Ds, D, Ls), A0, E),
      A = lam(Event, D, E)
    )
  ),
  subtract(Ls, Args, Usable),
  build_predicate(Usable, [at(t(Event), "EVENT")|Args], S, P).

2.7.4   Past tense

Past tense is retained with past/2. With transformation, this constructs a predicate condition to state that the head <discourse_referent> of the difference list assigned Event is "past". The integration with bodyClimb/2 ensures this predicate condition has placement in a final semantic representation at the location where the Event binding is created.

(55)

transform(Env,
          past(Event, Norm),
          rel( [],[],"",[E,
               bodyClimb( Event,
                          rel( [],[],"past",
                               [at( t( Event),"h")
                               ]))
               ])
         ) :-
  transform(Env, Norm, E).

2.7.5   Passivisation

Information that a clause is passive is retained with passive/1. With transformation, this constructs ifThere/3 checks of the assignment, and adjusts how arguments are bound. The first ifThere/3 checks for "ARG0" (subject) binding presence. If this is not found (as it should be), then instructions are made to create a default "passive" binding with the dummy constant c("_","_") as the assigned <discourse_referent>. The next check is for "ARG1" presence. If there is an "ARG1" binding, then instructions are made to shift the "ARG0"/"passive" binding to "ARG2" and any "LGS" (logical subject) to "ARG0", otherwise there are instructions to shift "ARG0"/"passive" to "ARG1" and any "LGS" to "ARG0".

(56)

transform(Env,
          passive(Norm),
          ifThere( "ARG0",
                   ifThere( "ARG1",
                            lam( "ARG0","ARG2",
                                 clean( 0,["LGS"],"ARG0",E))
                            ,
                            lam( "ARG0","ARG1",
                                 clean( 0,["LGS"],"ARG0",E)))
                   ,
                   head( "",["passive"],
                         namely( c( "_","")
                                 ,"passive",
                                 ifThere( "ARG1",
                                          lam( "passive","ARG2",
                                               clean( 0,["LGS"],"ARG0",E))
                                          ,
                                          lam( "passive","ARG1",
                                               clean( 0,["LGS"],"ARG0",E))))))
          ) :-
  transform(Env, Norm, E).

2.7.6   Other predicates

(57)

transform(env(Fs, Ds, D, Ls), pred(S, Args0), P) :-
  (
    foreach(A0, Args0),
    foreach(A, Args1),
    param(Fs, Ds, D, Ls)
  do
    ( string(A0) ->
      A = A0
    ;
      transform(env(Fs, Ds, D, Ls), A0, A)
    )
  ),
  Args = ["h"|Args1],
  subtract(Ls, Args, Usable),
  build_predicate(Usable, Args, S, P).

(58)

transform(Env, relation(S, Norms), rel([], [], S, Es)) :-
  (
    foreach(Norm, Norms),
    foreach(E, Es),
    param(Env)
  do
    transform(Env, Norm, E)
  ).

2.7.7   Argument forming structures

This subsection discusses the argument forming structures: npr/3, some/5, quant/6, someClassic/5, someFact/6, pro/7, arg/3, conjNpSum/6, conjNp/4, conjPp/3, and parenthetical/5.

2.7.7.1   Proper names

Constructed with npr/3, a proper name has the namely/3 construct to introduce a <discourse_referent> for the <fresh_string> binding "@e", which shifts to become a <local_string> binding X. Having the <fresh_string>, "@e", prefixed with the ‘@’ character creates a widest scoped fresh "@e" binding that will remain accessible as a discourse binding (via assignment to the D environment parameter) following any coordination.

(59)

transform(env(Fs, Ds, D, Ls), npr(DRef, X, Norm), namely(DRef, "@e", lam("@e", X, E0))) :-
  transform(env(Fs, Ds, D, Ls), Norm, E0).

As an example, normalised annotation changes as follows:

(60)

Normalised tree fragment:             <normalised_expr>:
(NP (SORT *PERSON*)                   npr( c( "PERSON,"John")"
    (NPR John))                            ,__X__,
                                           __E__))
<sct_expr>:
namely( c( "PERSON","John")
        ,"@e",
        lam( "@e"
             ,__X__,
             __E__)))

2.7.7.2   Noun phrases with restrictions

A basic noun phrase is realised with some(V, DRef, NormR, X, NormNS). After transformation, there is namely/3 to introduce DRef (a <discourse_referent>) for a V (<fresh_string>) binding, which shifts to an X (<local_string>) binding for the nuclear scope content from NormNS (i.e. the rest of the containing clause/phrase), together with a further shift to "h" (a <local_string>) for the restriction material of NormR. This latter shift to "h" is accompanied by removal to the discourse context (D) (via make_subord/6 of section 2.6.2) of any local binding from the containing clause/phrase that is not "h". Also, to ensure the restriction material accompanies the quantification introduction of DRef, bodyClimb/2 surrounds the content from NormR and shares the same <fresh_string> (V) by which the new argument binding is introduced.

(61)

transform(env(Fs, Ds, D, Ls),
          some(V, DRef, NormR, X, NormNS),
          namely( DRef,V,
                  lam( V,X,
                       rel( Fs,Ds,"",
                            [bodyClimb( V,
                                        lam( X,"h",ER))
                            ,ENS])))
         ) :-
  transform(env(Fs, Ds, D, Ls), NormR, ER0),
  transform(env(Fs, Ds, D, Ls), NormNS, ENS),
  make_subord(0, D, Ls, ["h"], clean(1, ["h"], D, ER0), ER).

As an example, the normalised Prolog term from (37) changes as follows:

(62)

<normalised_expr>:
some( ".e",
      x( "ENTITY",2)
      ,
      local( .( "h",[])
             ,
             pred( "cafe",[]))
      ,"LOC_at",
      __E__)

<sct_expr>:
namely( x( "ENTITY",2)
        ,".e",
        lam( ".e","LOC_at",
             rel( .( ".e",
                     .( ".event",[]))
                  ,
                  .( "*",
                     .( "*",[]))
                  ,"",
                  .( bodyClimb( ".e",
                                lam( "LOC_at","h",
                                     clean( 0,
                                            .( "ARG0",
                                               .( "LOC_at",[]))
                                            ,"*",
                                            clean( 1,
                                                   .( "h",[])
                                                   ,"*",
                                                   rel( [],[],"cafe",
                                                        .( at( t( "h")
                                                               ,"h")
                                                           ,[]))))))
                     ,
                     __E__))))

Note how the shift to "h" provides an environment suitable for nouns to occupy when constructed with pred/2 of section 2.7.6.

2.7.7.3   Noun phrases with quantification

A quantified noun phrase arises when namely/3 --- the introducer of fresh bindings --- is bundled with quantificational closure. Thus, quant/6 is like some/5, with the addition of taking Oper to specify the operation of quantification via make_closure of section 2.6.3. What exactly is quantified is determined with select_most_closures/3 of section 2.6.3, on the basis of the <fresh_string> V. As with some/5, the restriction is insulated from the containing clause by shifting any open local binding with make_subord/6 to the discourse context D with the exception of the binding introduced by the noun phrase, which shifts to "h" to be available for the restriction content. Also, existential quantification ("exists") is introduced to the nuclear scope with make_closure.

(63)

transform(env(Fs, Ds, D, Ls), quant(Oper, V, DRef, NormR, X, NormNS), E) :-
  select_most_closures(V, Fs, C2),
  union(C2, [V], C1),
  transform(env(Fs, Ds, D, Ls), NormR, ER0),
  transform(env(Fs, Ds, D, Ls), NormNS, ENS0),
  make_subord(0, D, Ls, ["h"], clean(1, ["h"], D, ER0), ER),
  make_closure("exists", C2, ENS0, ENS),
  make_closure(Oper, C1, namely(DRef, V, lam(V, X, rel(Fs, Ds, "", [bodyClimb(V, lam(X, "h", ER)), ENS]))), E).

2.7.7.4   Classic arguments

someClassic/5 offers a variant of some/5 with no namely/3. Instead, SCT primitive headClimb/3 is used to introduce DRef (a <discourse_referent>). While this DRef receives closure (and thereby its semantic scope) from the commanding closure of V (a <fresh_string>), it will not exhibit dynamic scope. That is, its binding scope will be over the content of the restriction (NormR) and the nuclear scope (NormNS), but not beyond.

(64)

transform(env(Fs, Ds, D, Ls),
          someClassic(V, DRef, NormR, X, NormNS),
          headClimb( DRef,V,
                     lam( V,X,
                          rel( Fs,Ds,"",
                               [bodyClimb( V,
                                           lam( X,"h",ER))
                               ,ENS])))
         ) :-
  transform(env(Fs, Ds, D, Ls), NormR, ER0),
  transform(env(Fs, Ds, D, Ls), NormNS, ENS),
  make_subord(0, D, Ls, ["h"], clean(1, ["h"], D, ER0), ER).

As with some/5, open local bindings other than "h" shift to the discourse context D via make_subord/6 before content from the restriction NormR is reached. Also, the restriction content is surrounded by bodyClimb/2 with V for placement in the semantic representation resulting from semantic calculation.

2.7.7.5   Propositional arguments

someFact/6 offers a further variant of some/5, differing in its treatment of the restriction, NormR, which forms an embedding (with "THT" role) to a predicate with <relation_string> S. The binding of the noun phrase, X, binds a term argument of the S predicate with "h" role. Before the NormNS content occurs the X binding shifts to a "" (empty string) binding, where it is essentially removed from further consideration. In further contrast to the restrictions of some/5, quant/6, and someClassic/5, there are no alterations to the local bindings NormNS inherits from the containing clause/phrase.

. IX someFact definition

(65)

transform(env(Fs, Ds, D, Ls),
          someFact(V, S, DRef, NormR, X, NormNS),
          headClimb( DRef,V,
                     lam( V,X,
                          rel( Fs,Ds,"",
                               [bodyClimb( V,
                                           rel( [],[],S,
                                                [at( t( X),"h")
                                                ,
                                                at( lam( X,"",ER),"THT")
                                                ]))
                               ,ENS])))
         ) :-
  transform(env(Fs, Ds, D, Ls), NormR, ER),
  transform(env(Fs, Ds, D, Ls), NormNS, ENS).

2.7.7.6   Pronouns

Pronoun contribution is realised with pro/7. Like someClassic/5, this has headClimb/3 to introduce a fresh <discourse_referent> DRef for an X binding that will have syntactic scope over the content of Norm (the rest of the containing clause), yet scope semantically with the commanding V closure. A pronoun is resolved by receiving as its S antecedent a discourse referent that shares sort information with the <sort_list> Sorts. Candidates for antecedents are gathered with the SCT primitive pick/4 from the sequences assigned to the <context_string> D or the <local_string>s of Ls (minus X, the binding from the noun phrase itself) determined by Source.

(66)

transform(env(Fs, Ds, D, Ls),
          pro(Source, Sorts, V, S, DRef, X, Norm),
          headClimb( DRef,V,
                     lam( V,X,
                          rel( [],[],"",
                               [bodyClimb( V,
                                           pick( S,
                                                 t( X)
                                                 ,SourcesOut,Sorts))
                               ,E0])))
         ) :-
  transform(env(Fs, Ds, D, Ls), Norm, E0),
  ( Source == 'd' ->
    SourcesOut = [D]
  ; Source == 'ls' ->
    subtract(Ls, [X], SourcesOut)
  ;
    subtract(Ls, [X], SourcesOut1),
    SourcesOut = [D|SourcesOut1]
  ).

As an example, normalised annotation changes as follows:

(67)

Normalised tree fragment:       <normalised_expr>:
(NP (SORT *PERSON*)             (NP pro( ["*"],["PERSON"],".e","__EQUALS__He",
    (PRO He))                            x( "PERSON",1)
                                         ,__X__
                                         ,__E__))
<sct_expr>:
(NP headClimb( x( "PERSON",1)
               ,".e",
               lam( ".e",__X__,
                    rel( [],[],"",
                         [bodyClimb( ".e",
                                     pick( "__EQUALS__He",
                                           t( __X__)
                                           ,["*"],["PERSON"]))
                         ,__E__]))))

2.7.7.7   Noun phrase conjunction

(68)

transform(env(Fs, Ds, D, Ls),
          conjNpSum(V, S, DRef, NPsList, X, NormNS),
          namely( DRef,V,
                  lam( V,X,
                       rel( Fs,Ds,"",
                            [bodyClimb( V,
                                        lam( X,"h",ER))
                            ,ENS])))
         ) :-
  transform(env(Fs, Ds, D, Ls), NormNS, ENS),
  (
    foreach(NP, NPsList),
    foreach(ER0, ERs),
    param(Fs, Ds, D, Ls)
  do
    NP =.. NPList,
    append(NPList, ["__IN__", relation("__IN__", [t("__IN__"), t("h")])], NormRList),
    NormR =.. NormRList,
    transform(env(Fs, Ds, D, Ls), NormR, ER0)
  ),
  make_subord(0, D, Ls, ["h"], clean(1, ["h"], D, rel(Fs, Ds, S, ERs)), ER).

(69)

transform(env(Fs, Ds, D, Ls), conjNp(S, NPsList, X, NormNS), rel(Fs, Ds, S, Es)) :-
  (
    foreach(NP, NPsList),
    foreach(E, Es),
    param(Fs, Ds, D, Ls, X, NormNS)
  do
    NP =.. NPList,
    append(NPList, [X, NormNS], NormList),
    Norm =.. NormList,
    transform(env(Fs, Ds, D, Ls), Norm, E)
  ).

2.7.7.8   Preposition phrase conjunction

(70)

transform(env(Fs, Ds, D, Ls), conjPp(S, PPsList, NormNS), rel(Fs, Ds, S, Es)) :-
  (
    foreach(PP, PPsList),
    foreach(E, Es),
    param(Fs, Ds, D, Ls, NormNS)
  do
    PP =.. PPList,
    append(PPList, [NormNS], NormList),
    Norm =.. NormList,
    transform(env(Fs, Ds, D, Ls), Norm, E)
  ).

2.7.7.9   Parentheticals

(71)

transform(Env, parenthetical(V, PP, NP, X, NormNS), E) :-
  PP =.. PPList,
  last(PX, PPList),
  append(PPList, [relation(PX, [t(PX), t(X)])], ParentheticalList),
  Parenthetical =.. ParentheticalList,
  NP =.. NPList,
  append(NPList, [X, connect("", [bodyClimb(V, Parenthetical), NormNS])], NormList),
  Norm =.. NormList,
  transform(Env, Norm, E).

2.7.8   Embedding

embed/1 protects an embedding from local (Ls) bindings that would otherwise be inherited from the outside environment.

(72)

transform(env(Fs, Ds, D, Ls), embed(Norm), E) :-
  transform(env(Fs, Ds, D, Ls), Norm, E0),
  make_subord(0, D, Ls, [], E0, E).

2.7.9   Control

Having embed/1 removes all inherited local (Ls) bindings. But binding inheritance may be desirable. In particular, as obligatory dependencies, control dependencies are best captured through the preservation of a local binding of the embedding predicate into the embedding. Such preservation might include a shift to a different local binding name, as accomplished with control/1.

(73)

transform(env(Fs, Ds, D, Ls), control(Norm), E) :-
  transform(env(Fs, Ds, D, Ls), Norm, E0),
  intersection(["DARG0", "ARG00", "h", "DARG1", "ARG1", "LGS", "ARG2"], Ls, Candidates),
  make_subord(0, D, Ls,  ["ARG0"|Candidates], clean(1, ["ARG0"], D, E0), E2),
  make_subord(0, "ARG0", Candidates, [], E2, E).

The transformation of control/1 leads to three steps. First, all sequence values assigned to "h" (head binding internal to a noun phrase restriction), then "ARG1", then "LGS" (binding for a logical subject), and then "ARG2" shift to the "ARG0" binding. Second, there is removal (to D) with make_subord of any sequence values assigned to names of the Ls parameter except "ARG0". Third, if "ARG0" is non-empty there is removal to D of all assigned values except the frontmost value. This has the effect that, with control/1 there is one binding that can be preserved from the embedding clause into the embedding, with the ordering of preference in (74), with "ARG2" most preferred:

(74)

"ARG2" > "LGS" > "ARG1" > "DARG1" > "h" > "DARG0" > "ARG0"

     In deviation to control/1, we will also establish control relations with control2/1. This misses out the first step of shifting sequence values to the "ARG0" binding. With this change, it can only be the "ARG0" binding that is maintained into the embedding.

(75)

transform(env(Fs, Ds, D, Ls), control2(Norm), E) :-
  transform(env(Fs, Ds, D, Ls), Norm, E0),
  make_subord(0, D, Ls, ["ARG0"], clean(1, ["ARG0"], D, E0), E).

2.7.10   Coordination

It is the purpose of the current section to consider how arguments and adjuncts can be ‘inherited’ when there is coordination. This relation is called ‘Across the Board’ extraction (ATB).

     When there is annotation of coordinate structure, with either an explicit CONJP configuration (see section 2.1.2.1), or -CONJ specification with clause linkage (see section 2.1.4), the <sct_expr> resulting from conversion will contain the grammar building combinator connect/2 to integrate the conjuncts under a single Rel construct, with the appropriate relation name supplied through the S parameter.

     What is most notable about a relation constructed with connect is that it is made sensitive to the Fs parameter, which is used to list the available fresh binding names, and so trigger management (via calls during evaluation leading to allocate; see section 3.2.5) of the accessible fresh discourse referents for the conjuncts given with the Es list parameter.

(76)

transform(env(Fs, Ds, D, Ls), connect(S, Norms), rel(Fs, Ds, S, Es)) :-
  (
    foreach(Norm, Norms),
    foreach(E, Es),
    param(Fs, Ds, D, Ls)
  do
    transform(env(Fs, Ds, D, Ls), Norm, E)
  ).

2.7.11   Further ways to connect expressions

In contrast to the “dynamic” behaviour of connect, join offers a static variant to bring together expressions EA and EB under an S relation.

(77)

transform(Env, join(S, NormA, NormB), rel([], [], S, [EA, EB])) :-
  transform(Env, NormA, EA),
  transform(Env, NormB, EB).

Bringing together expressions EA and EB under an S relation with the “dynamic” behaviour of connect is achieved with scon and scon_right. These differ in the ordering behaviour of and so dynamics between EA and EB:

. IX scon definition

(78)

transform(env(Fs, Ds, D, Ls), scon(S, NormA, NormB), rel(Fs, Ds, S, [EA, EB])) :-
  transform(env(Fs, Ds, D, Ls), NormA, EA),
  transform(env(Fs, Ds, D, Ls), NormB, EB).

(79)

transform(env(Fs, Ds, D, Ls), scon_right(S0, NormA, NormB), rel(Fs, Ds, S, [EB, EA])) :-
  concat_strings(S0, "__RIGHT__", S),
  transform(env(Fs, Ds, D, Ls), NormA, EA),
  transform(env(Fs, Ds, D, Ls), NormB, EB).

cond and cond_right are variants of scon and scon_right that incorporate quantification to support donkey conditionals.

(80)

transform(env(Fs, Ds, D, Ls), cond(V, S, NormA, NormB), E) :-
  select_most_closures(V, Fs, C1),
  transform(env(Fs, Ds, D, Ls), NormA, EA),
  transform(env(Fs, Ds, D, Ls), NormB, EB0),
  make_closure("exists", C1, EB0, EB),
  make_closure("forall", C1, rel(Fs, Ds, S, [EA, EB]), E).

(81)

transform(env(Fs, Ds, D, Ls), cond_right(V, S0, NormA, NormB), E) :-
  concat_strings(S0, "__RIGHT__", S),
  select_most_closures(V, Fs, C1),
  transform(env(Fs, Ds, D, Ls), NormA, EA),
  transform(env(Fs, Ds, D, Ls), NormB, EB0),
  make_closure("exists", C1, EB0, EB),
  make_closure("forall", C1, rel(Fs, Ds, S, [EB, EA]), E).

2.7.12   Clause typing

(82)

transform(env(Fs, Ds, D, Ls), question(Norm), head("exists", C1, head("question", C2, body(C3, E)))) :-
  transform(env(Fs, Ds, D, Ls), Norm, E),
  select_closures(['.'], Fs, [], C1),
  select_closures(['?'], Fs, [], C2),
  select_closures(['?', '.'], Fs, [], C3).

2.7.13   Propositional operations

(83)

transform(env(Fs, Ds, D, Ls), neg(Norm), rel([], [], "neg", [E])) :-
  transform(env(Fs, Ds, D, Ls), Norm, E0),
  select_closures(['.'], Fs, [], C1),
  make_closure("exists", C1, E0, E).

(84)

transform(Env, md(S, Norm), rel([], [], S, [E])) :-
  transform(Env, Norm, E).

2.8   Orientation

In the next chapter we move on to a discussion of the subsequent interpretation of <sct_expr>s as reached by the transformations of normalised annotation in this chapter. But before doing so, one final observation is in order. The process of reaching an <sct_expr> can in principle be carried out for any language in any annotation format, provided that the format includes enough information about part of speech, constituency, argumenthood, modification, and anaphoric relations to discharge the requirements of lexical elements and reflect the roles of functional elements.

     With the sketched setup comes an emergence of a notion of ‘grammar’ as a guidance for ensuring bindings are accessible when they need to be and inaccessible when they should not be available. It then becomes possible for the grammatical system to determine how a word or construction in a certain environment will behave. But also a word or construction might have its properties specified so as to place very clear demands on the state of the environment in which it occurs. Grammaticality effects arise with the possibility of a clash between: (i) what is given by the assignment state, and (ii) what needs to be present as well as absent for the expression under evaluation.


Chapter 3: Semantic calculation

This chapter sets out how <sct_expr>s of the previous chapter can be used as input for a calculation that returns expressions of a target discourse representation language. Target language expressions (<target_expr>s) include quantificational closures, discourse referents, and relations (both as predicate conditions and connectives), as well as markers to carry information on where discourse referents and conditions are interpreted.

     The chapter is organised as follows. Section 3.1 presents a procedure for collecting the <discourse_referent>s of an <sct_expr>. Section 3.2 introduces a storage mechanism for holding <discourse_referent>s. Section 3.3 presents the calculation from <sct_expr>s to the target language. Finally, section 3.4 details the target language.

3.1   Collecting <discourse_referent>s

A key contribution of head/3, namely/3, and wipe/2, is their use in determining the distributions of <discourse_referent>s. The effects of this contribution are made with discourse_refs(X, E, Value) of (1). This is true when X is a <fresh_name>, E is an <sct_expr>, and Value is a difference list with the <discourse_referent>s from E.

(1)

discourse_refs(X, head(_, Xs, E), Vs0-Vs) :-
  ( memberchk(X, Xs) ->
    Vs0 = Vs
  ;
    discourse_refs(X, E, Vs0-Vs)
  ).
discourse_refs(X, body(_, E), Value) :-
  discourse_refs(X, E, Value).
discourse_refs(X, headClimb(_, _, E), Value) :-
  discourse_refs(X, E, Value).
discourse_refs(X, bodyClimb(_, E), Value) :-
  discourse_refs(X, E, Value).
discourse_refs(X, namely(DRef, Y, E), Vs0-Vs) :-
  ( X == Y ->
    discourse_refs(X, E, Vs1-Vs),
    Vs0 = [DRef|Vs1]
  ;
    discourse_refs(X, E, Vs0-Vs)
  ).
discourse_refs(X, wipe(Y, E), Vs0-Vs) :-
  ( X == Y ->
    discourse_refs(X, E, [_|Vs1]-Vs),
    Vs0 = Vs1
  ;
    discourse_refs(X, E, Vs0-Vs)
  ).
discourse_refs(_, t(_), Vs-Vs).
discourse_refs(X, at(E, _), Value) :-
  discourse_refs(X, E, Value).
discourse_refs(X, rel(_, _, _, Es), Vs0-Vs) :-
  (
    foreach(E, Es),
    fromto(Vs, In, Out, Vs0),
    param(X)
  do
    discourse_refs(X, E, Out-In)
  ).
discourse_refs(X, ifThere(_, E1, E2), Value) :-
  discourse_refs(X, E1, Value),
  discourse_refs(X, E2, Value).
discourse_refs(X, lam(_, _, E), Value) :-
  discourse_refs(X, E, Value).
discourse_refs(X, clean(_, _, _, E), Value) :-
  discourse_refs(X, E, Value).
discourse_refs(_, pick(_, _, _, _), Vs-Vs).

The definition of discourse_refs/3 has patterns (including wildcards ‘_’) to match the functors that make up the <sct_expr> language. Most functors contribute only the collections from the expressions over which they scope. For rel/4, this includes bringing together collections for its list of <sct_expr>s expressions (specifically, via the ECLiPSe iteration constructor do).

     The real action with discourse_refs/3 happens when either namely/3, wipe/2, or head/3 is reached. With namely/3 if there is a match of <fresh_string>s then the <discourse_referent> carried by namely/3 is entered into the overall difference list, else collection continues with no addition. With wipe/2 there is collection for the embedded <sct_expr>, E, such that if there is a match of <fresh_string>s then the tail of the collection is returned, otherwise all of the collection is returned. This has the effect of skipping the <discourse_referent> from the next namely/3 when the same <fresh_string> is shared by head/3 and namely/3. Finally, with head/3 if the <fresh_string> of the collection happens to be a member of the list that instantiates the Xs parameter of head/3 then the empty list is returned as the collection result (potentially hiding <discourse_referent>s), else the collection for the embedded <sct_expr> is returned.

     As an example of executing discourse_refs/3, consider (2):

(2)

|?- discourse_refs("foo", namely(x("BAR", 1), "foo", namely(x("BAR", 2), "foo", t("foo"))), Value).
Value = [x("BAR", 1), x("BAR", 2)|L] - L
Yes

That is, a difference list is returned containing the <discourse_referent>s carried by the namely/3 instances.

     When head/3 and namely/3 share the same <fresh_string>, head/3 serves to hide the presence of namely/3, as the return of the empty difference list in (3) shows.

(3)

|?- discourse_refs("foo", head("exists", ["foo"], namely(x("BAR", 1), "foo", namely(x("BAR", 2), "foo", t("foo")))), Value).
Value = L - L
Yes

Also taking a <fresh_string>, wipe/2 differs from head/3 by hiding only what is the next namely/3 instance with the same <fresh_string>, as (4) demonstrates:

(4)

discourse_refs("foo", wipe("foo", namely(x("BAR", 1), "foo", namely(x("BAR", 2), "foo", t("foo")))), Value).
Value = [x("BAR", 2)|L] - L
Yes

3.2   Storing <discourse_referent>s

This section introduces a storage mechanism capable of keeping track of the status of <discourse_referent>s. This consists of an assignment that assigns a (possibly empty) difference list of <discourse_referent>s to each <grammar_string> (see section 2.4).

     First, val(Assn, X, Value) succeeds when Value is the (possibly empty) difference list assigned by Assn to X.

(5)

val(Assn, X, Value) :-
  ( memberchk(X @> Value0, Assn) ->
    Value = Value0
  ;
    Value = Vs-Vs                 % otherwise return the empty difference list
  ).

By contrast, contentful_val(Assn, X, Value) succeeds only if Value is a non-empty difference list assigned by Assn to X.

(6)

contentful_val(Assn, X, Vs0-Vs) :-
  memberchk(X @> Vs0-Vs, Assn),
  Vs0 \== Vs.                     % assigned difference list must be non-empty

     Note that with the definition of val/3 in (5), Assn as the empty list ([]) is sufficient for stating the empty assignment, with all X instantiations assigned the empty difference list.

     Now we have the ability to access assigned content, we next introduce methods, push/4, pop/3, shift/4, shift_last/4, allocate/6, and dispose/5, to govern the release and subsequent accessibility of assigned content.

3.2.1   push/4

From the ECLiPSe library:

Defined in (7), push/4 succeed when Assn is a variant of assignment Assn0 differing only in that there is a new difference list assigned to X that is the concatenation (New-Vs) of the content of difference list New-Old and the difference list (Old-Vs) assigned to X by Assn0.

(7)

push(New-Old, X, Assn0, Assn) :-
  val(Assn0, X, Old-Vs),
  update(1, X @> New-Vs, Assn0, Assn).

For example:

(8)

|?- push([x(2,"BAR")|Old]-Old, "foo", ["foo" @> [x(1,"BAR")|L]-L], P).
Old = [x(1, "BAR")|L]
L = L
P = ["foo" @> [x(2, "BAR"), x(1, "BAR")|L] - L]
Yes

3.2.2   pop/3

Defined in (9), pop/3 succeeds when Assn is the same as Assn0 except with the first difference list element assigned to X removed.

(9)

pop(X, Assn0, Assn) :-
  contentful_val(Assn0, X, [_|VRs]-Vs),
  update(1, X @> VRs-Vs, Assn0, Assn).

For example:

(10)

|?- pop("foo", ["foo" @> [x(2, "BAR"), x(1, "BAR")|L]-L], P).
L = L
P = ["foo" @> [x(1, "BAR")|L] - L]
Yes

3.2.3   shift/4

Defined in (11), shift/4 succeeds when Assn is the same as Assn0 except with the first difference list element assigned to X removed and made the first element of the difference list assigned to Y.

(11)

shift(X, Y, Assn0, Assn) :-
  contentful_val(Assn0, X, [VXH|VXRs]-VXs),
  update(1, X @> VXRs-VXs, Assn0, Assn1),
  val(Assn0, Y, VYs0-VYs),
  update(1, Y @> [VXH|VYs0]-VYs, Assn1, Assn).

For example:

(12)

|?- shift("foo", "baz", ["foo" @> [x(2, "BAR"), x(1, "BAR")|L]-L], P).
L = L
P = ["baz" @> [x(2, "BAR")|_233] - _233, "foo" @> [x(1, "BAR")|L] - L]
Yes

3.2.4   shift_last/4

Defined in (13), shift_last/4 succeeds when Assn is the same as Assn0 except with the last difference list element, VXL (found via last_il/3), assigned to X removed (to leave VXRs-VXs as the assigned value) and made the first element of the difference list assigned to Y.

(13)

shift_last(X, Y, Assn0, Assn) :-
  contentful_val(Assn0, X, VXs0-VXs),
  last_il(VXs0, VXRs, VXL),
  update(1, X @> VXRs-VXs, Assn0, Assn1),
  val(Assn0, Y, VYs0-VYs),
  update(1, Y @> [VXL|VYs0]-VYs, Assn1, Assn).

For example:

(14)

|?- shift_last("foo", "baz", ["foo" @> [x(2, "BAR"), x(1, "BAR")|L]-L], P).
L = L
P = ["baz" @> [x(1, "BAR")|_231] - _231, "foo" @> [x(2, "BAR")|L] - L]
Yes

3.2.5   allocate/6 with expression integrity

The required manipulation for moving through the expressions of a discourse from left to right will be automated by allocate/6. A string X is a <fresh_string> when namely(X, _, _) occurs within an <sct_expr>. A <fresh_string> serves as a source of <discourse_referent>s that have not been previously accessed. Taking discourse to be a collection of ordered <sct_expr>s (Es), and supposing X is a <fresh_string> in Es, then, at the moment of interpreting the entire discourse Es, the assignment state will be assigning a difference list to X that contains all <discourse_referent>s required for all the separate expressions of Es. We can think of such an assigned difference list as being formed so that <discourse_referent>s needing to appear for the first expression of Es (that is, the start of the discourse) will appear last in the assigned difference list. Working through the remaining expressions of Es then amounts to opening up more of the difference list content assigned to X in end-to-front direction, until all <discourse_referent>s are revealed with the last expression of Es, so that, with completion of the discourse, all <discourse_referent>s assigned X will have been accessed. One more thing that allocate/6 does is move the <discourse_referent>s that were accessed by prior expressions to a different <grammar_string> serving as a <context_string>. The different uses of <grammar_string>s are set out in section 2.4. Bearing these matters in mind will help in understanding how allocate/6 is defined.

     First, consider split(N, List, Past, Future) of (15). This succeeds when Past is the first N-1 elements of List and Future is the elements of List from N+1 to the last element.

(15)

split(1, [_|T], [], T).
split(N, [H|T], [H|Past], Future) :-
  M is N - 1,
  split(M, T, Past, Future).

For example:

(16)

|?- split(3, [a, b, c, d, e], Past, Future).
Past = [a, b]
Future = [d, e]
Yes

     Now consider allocate(N, Xs, Ys, Es, Assn0, Assn), as defined in (17). With Xs and Ys empty, Assn and Assn0 are the same assignment. Otherwise there is recursion to work through the list content of Xs and Ys. Each cycle of recursion succeeds when, relative to integer N and list Es of <sct_expr>s, assignment Assn differs from Assn0 in regards to the content assigned to the head X of Xs and the head Y of Ys. More specifically, N is used to split Es into a list of future expressions (Future) and past expressions (Past), from which lists of <discourse_referent>s for X are extracted (via discourse_refs/3) for the future (Future_DRefs) and past (Past_DRefs) relative to N. The Future_DRefs are then removed (via pop/3) from the assignment to X, while the Past_DRefs are relocated (via shift_last/4) to Y.

(17)

allocate(_, [], [], _, Assn, Assn).
allocate(N, [X|FNs], [Y|CNs], Es, Assn0, Assn) :-
  split(N, Es, Past, Future),
  (                             % the future
    foreach(E, Future),
    fromto([], In, Out, Future_DRefs),
    param(X)
  do
    discourse_refs(X, E, Out-In)
  ),
  (                             % the past
    foreach(E, Past),
    fromto([], In, Out, Past_DRefs),
    param(X)
  do
    discourse_refs(X, E, Out-In)
  ),
  (                             % remove the future
    foreach(_, Future_DRefs),
    fromto(Assn0, In, Out, Assn1),
    param(X)
  do
    pop(X, In, Out)
  ),
  (                             % contextualise the past
    foreach(_, Past_DRefs),
    fromto(Assn1, In, Out, Assn2),
    param(X, Y)
  do
    shift_last(X, Y, In, Out)
  ),
  allocate(N, FNs, CNs, Es, Assn2, Assn).

     To see consequences of allocate/6, consider (18)--(20).

(18)

|?- allocate(1, ["foo"], ["baz"], [t("baz"), namely(x(2,"BAR"), "foo", t("foo")), t("baz")], ["baz" @> [x(1,"BAR")|L1]-L1, "foo" @> [x(2, "BAR")|L2]-L2], P).
L1 = L1
L2 = L2
P = ["baz" @> [x(1, "BAR")|L1] - L1, "foo" @> L2 - L2]
Yes

(19)

|?- allocate(2, ["foo"], ["baz"], [t("baz"), namely(x(2,"BAR"), "foo", t("foo")), t("baz")], ["baz" @> [x(1,"BAR")|L1]-L1, "foo" @> [x(2, "BAR")|L2]-L2], P).
L1 = L1
L2 = L2
P = ["baz" @> [x(1, "BAR")|L1] - L1, "foo" @> [x(2, "BAR")|L2] - L2]
Yes

(20)

|?- allocate(3, ["foo"], ["baz"], [t("baz"), namely(x(2,"BAR"), "foo", t("foo")), t("baz")], ["baz" @> [x(1,"BAR")|L1]-L1, "foo" @> [x(2, "BAR")|L2]-L2], P).
L1 = L1
L2 = L2
P = ["baz" @> [x(2, "BAR"), x(1, "BAR")|L1] - L1, "foo" @> L2 - L2]
Yes

This reveals how what is assigned as difference list content can be discarded altogther, as is the case for x(2, "BAR") when N is 1 in (18). And if assigned content remains, then it is either: (i) present to support occurrences of namely/3, as is the case with x(2, "BAR") remaining assigned to "foo" when N is 2 in (19), or (ii) serving as content that will have been relocated as seen when N is 3 in (20) with x(2, "BAR") assigned as part of a difference list for "baz" while the difference list for "foo" is empty.

     When allocate/6 is called it ensures the appropriate assignment of <discourse_referent>s to <grammar_string>s in an expression. The calculation is global over the discourse in question, amounting to a check on the operation of the calculation and on the well-formedness of the discourse data, simultaneously.

3.2.6   dispose/5

Defined in (21) with iterations of shift_last/4, dispose/5 relocates <discourse_referent>s contained in the difference lists assigned to the <grammar_string>s of Xs to become <discourse_referent>s of the difference list assigned to the Y <grammar_string> when the source difference lists have a length longer than N.

(21)

dispose(_, [], _, Assn, Assn).
dispose(N, [X|T], Y, Assn0, Assn) :-
  val(Assn0, X, Vs0-_),
  length_il(Vs0, M),
  (
    for(_, 1, M - N),
    fromto(Assn0, In, Out, Assn1),
    param(X, Y)
  do
    shift_last(X, Y, In, Out)
  ),
  dispose(N, T, Y, Assn1, Assn).

For example:

(22)

|?- dispose(0, ["foo"], "baz", ["foo" @> [x(2, "BAR"), x(1, "BAR")|L]-L], P).
L = L
P = ["baz" @> [x(2, "BAR"), x(1, "BAR")|_247] - _247, "foo" @> L - L]
Yes

With N = 0, all <discourse_referent>s of the difference list assigned to "foo" are relocated to "baz".

     Like allocate/6, dispose/5 will be utilised to move <discourse_referent>s from one <grammar_string> to a different <grammar_string> serving as a discourse context. A key difference is that while with allocate/6 such moves will occur as we proceed through discourse (that is, through ‘coordinate structure’ / linked units (e.g., clauses) of equal status), with dispose/5 the moves are to be triggered as we enter ‘subordinate structure’ (e.g., clauses which are grammatically subordinate because they are part of another clause).

3.3   From <sct_expr>s to <target_expr>s

This section brings together everything seen thus far with calculate/3 which transforms <sct_expr>s into expressions of a target discourse representation language. Defined in (23), calculate(Assn, E, Target) has Assn for an assignment function, E to take the input <sct_expr>, while Target is the output target expression. Assn assigns difference lists of <discourse_referent>s to the <grammar_string>s contained in E.

     calculate/3 contains calls to the assignment actions of section 3.2: push/4 (7), pop/3 (11), allocate/6 (17), and dispose/5 (21). When encountering occurrences of head/3, calculate/3 calls the operation of discourse_refs/3 (1). This gathers the <discourse_referent>s made available by namely/3 for inclusion into the assignment. Thereafter the assigned content is distributed to parts of the input <sct_expr> with recursive calls of calculate/3. Such recursive calls of calculate/3 may be invoked by a match of rel/4 that through applications of allocate/6 can reposition or remove assigned content based on collections from namely/3. Note how discourse_refs/3 performs two functions: Firstly, with head/3, it collects the <discourse_referent>s of namely/3 instances for inclusion into the assignment, and secondly, with rel/4, it is used in calls of allocate/6 to ensure that already collected <discourse_referent>s that are parts of assigned difference lists are correctly accessible from the inherited assignment state.

(23)

calculate(Assn0, head(Oper, Xs, E), head(Oper, Xs, Bds, Target)) :-
  (
    foreach(X, Xs),
    fromto(Assn0, AssnIn, AssnOut, Assn),     % make assignment changes
    fromto([], BdsIn, BdsOut, Bds),           % collect binding information
    param(E)
  do
    discourse_refs(X, E, DRefs-Vs),
    push(DRefs-Vs, X, AssnIn, AssnOut),
    binding_filter(DRefs, BdsIn, BdsOut)
  ),
  calculate(Assn, E, Target).
calculate(Assn, body(Xs, E), body(Xs, Target)) :-
  calculate(Assn, E, Target).
calculate(Assn0, headClimb(DRef, X, E), headClimb(DRef, X, Target)) :-
  push([DRef|R]-R, X, Assn0, Assn),
  calculate(Assn, E, Target).
calculate(Assn, bodyClimb(X, E), bodyClimb(X, Target)) :-
  calculate(Assn, E, Target).
calculate(Assn, namely(_, _, E), Target) :-
  calculate(Assn, E, Target).
calculate(Assn, wipe(_, E), Target) :-
  calculate(Assn, E, Target).
calculate(Assn, t(X), DRef) :-
  memberchk(X @> [DRef|_]-_, Assn).
calculate(Assn, at(E, S), at(Target, S)) :-
  calculate(Assn, E, Target).
calculate(Assn0, rel(Xs, Ys, S, Es), rel(S, Ts)) :-
  (
    foreach(E, Es),
    foreach(Target, Ts),
    count(I, 1, _),
    param(Assn0, Xs, Ys, Es)
  do
    allocate(I, Xs, Ys, Es, Assn0, Assn),
    calculate(Assn, E, Target)
  ).
calculate(Assn, ifThere(X, E1, E2), Target) :-
  ( contentful_val(Assn, X, _) ->
    calculate(Assn, E1, Target)
  ;
    calculate(Assn, E2, Target)
  ).
calculate(Assn0, lam(X, Y, E), Target) :-
  shift(X, Y, Assn0, Assn),
  calculate(Assn, E, Target).
calculate(Assn0, clean(N, Xs, Y, E), Target) :-
  dispose(N, Xs, Y, Assn0, Assn),
  calculate(Assn, E, Target).
calculate(Assn, pick(S, E, Sources, Sorts), rel(S, [DRef|Resolved])) :-
  calculate(Assn, E, DRef),
  (
    foreach(X, Sources),
    fromto([], In, Out, Accessible),
    param(Assn)
  do
    val(Assn, X, Vs-_),
    append_il(Vs, In, Out)
  ),
  antecedents(Sorts, Accessible, [], Resolved).

     The following details the consequences of all the functors with regards to direct changes made to the assignment, as well as the contribution made for the overall target expression returned:

     Pronouns can offer information to limit possible antecedents. For example, they should take a group <discourse_referent> as antecedent, while him should link to a male person <discourse_referent>. Defined in (24) and calling sort_filter/4 of (25), antecedents(Sorts, Accessible, Resolved0, Resolved) accumulates potential antecedents with Resolved0 and Resolved that have Sort information from list Accessible.

(24)

antecedents([], _, R, R).
antecedents([S|Ss], A, R0, R) :-
  sort_filter(S, A, R0, R1),
  antecedents(Ss, A, R1, R).

(25)

sort_filter(_S, [], R, R).
sort_filter(S, [A0|As0], R, As) :-
  ( A0 = x(S, _) ->
    As = [A0|As1]
  ; A0 = c(S, _) ->
    As = [A0|As1]
  ;
    As = As1
  ),
  sort_filter(S, As0, R, As1).

3.4   The target discourse representation language

The target language reached by the calculation of section 3.3 includes <discourse_referent>s as terminal elements. For complex expressions, there are structures to distinguish relations (rel/2), markers of argument roles (at/2), and quantification (quant/3). The inclusion of <extended_target_expr>s gives structures to manipulate where discourse referents and their conditions are interpreted (head/4, body/2, headClimb/3, and bodyClimb/2).

     A target language expression is a <target_expr>, where:

<target_expr> ::=
         <discourse_referent>
      |  rel(<relation_string>, <target_expr_list>)
      |  at(<target_expr>, <role_string>)
      |  quant(<q_operator>, <bound_list>, <target_expr>)
      |  <extended_target_expr>

<target_expr_list> ::=
         []
      |  <target_expr> . <target_expr_list>

<bound_list> ::=
         []
      |  x(<sort_string>, <integer>) . <bound_list>

<extended_target_expr> ::=
         head(<q_operator>, <fresh_list>, <bound_list>, <target_expr>)
      |  body(<fresh_list>, <target_expr>)
      |  headClimb(<discourse_referent>, <fresh_string>, <target_expr>)
      |  bodyClimb(<fresh_string>, <target_expr>)

<fresh_list> ::=
         []
      |  <fresh_string> . <fresh_list>

     Relations (rel/2) comprise predications, adverbial modifications, as well as higher order connectives, such as negation and conjunction. The string parameter of rel/2 identifies the predicate, modifier, connective, etc. in question, while the second parameter is either a list of the arguments built on at/2 functors (of a predicate or modifier), or a list of <target_expr>s (of a connective).

     Argument role markers (at/2) have a <target_expr> parameter (typically built on <discourse_referent>s) and a string parameter which specifies the argument role relative to the containing relation.

     Functor quant/3 creates quantificational closure, with parameters for a quantificational operation ("∃", "EVERY", etc.), a list of x/2 <discourse_referent>s bound by the operation, and the <target_expr> scoped over.

     The remaining functors carry information about the placement of expression material: head/4 has a string parameter to specify quantification ("∃", "EVERY", etc.), a string list parameter to specify indexing with the potential for collecting <discourse_referent>s appearing inside coindexed headClimb/3, a lang list parameter for <discourse_referent>s that the quantification serves to bind, and a parameter for a <target_expr>, which is typically filled by a body/2 expression. In other words, head/4 brings about a quantificational closure that is indexed to collect x/2 <discourse_referent>s. Like head/4, the functor body/2 has a string parameter to specify the kind of quantification to which the body/2 is linked ("∃", "EVERY", etc.), and a string list parameter to specify indexing with the potential for collecting conditions appearing inside coindexed bodyClimb/2, as well as a parameter for a <target_expr>, which is typically filled by a rel/2 expression that is a collection point for coindexed headClimb/3 content. Finally, indexed headClimb/3 and bodyClimb/2 mark x/2 <discourse_referent>s and conditions, respectively, that await integration into the containing expression at higher coindexed instances of head/4 and body/2. In this regard, head/4 acts like the top box of a Discourse Representation Structure (DRS), while body/2 acts as the bottom box.

     For a demonstration, consider (26), seen annotated as (16) in section 2.1.5, as well as below as (27) with added sort information.

(26)
Everyone ate at the cafe.

(27)

(IP-MAT (NP-SBJ;{PERSON} (QN Everyone))
        (VBD ate)
        (PP-LOC (P-ROLE at)
                (NP;{BETTYS} (D;{DEF} the)
                             (N cafe)))
        (PU .))

With tree normalisation, (27) becomes (28).

(28)

(IP-MAT (ACT past)
        (PP (P-ROLE ARG0)
            (NP (ACT *INDEF*)
                (SORT *PERSON*)
                (Q Everyone)))
        (VB ate)
        (PP (P-ROLE LOC_at)
            (NP (ACT *DEF*)
                (SORT *BETTYS*)
                (D the)
                (N cafe)))
        (PU .))

With conversion to a <normalised_expr>, (28) becomes (29).

(29)

local( .( "ARG0",
          .( "LOC_at",[]))
       ,
       quant( "EVERYONE",".e",
              x( "PERSON",1)
              ,
              local( .( "h",[])
                     ,
                     pred( "",[]))
              ,"ARG0",
              some( "@e",
                    x( "BETTYS",2)
                    ,
                    local( .( "h",[])
                           ,
                           pred( "cafe",[]))
                    ,"LOC_at",
                    past( ".event",
                          verb( ".event",
                                x( "EVENT",3)
                                ,"ate",
                                .( "LOC_at",
                                   .( "ARG0",[])))))))

With transformation to an <sct_expr>, (29) becomes (30).

(30)

head( "exists",
      .( "@e",
         .( ".event",[]))
      ,
      body( .( "@e",
               .( ".event",[]))
            ,
            head( "EVERYONE",
                  .( ".event",
                     .( ".e",[]))
                  ,
                  body( .( ".event",
                           .( ".e",[]))
                        ,
                        namely( x( "PERSON",1)
                                ,".e",
                                lam( ".e","ARG0",
                                     rel( .( "@e",
                                             .( ".event",[]))
                                          ,
                                          .( "*",
                                             .( "*",[]))
                                          ,"",
                                          .( bodyClimb( ".e",
                                                        lam( "ARG0","h",
                                                             clean( 0,
                                                                    .( "ARG0",
                                                                       .( "LOC_at",[]))
                                                                    ,"*",
                                                                    clean( 1,
                                                                           .( "h",[])
                                                                           ,"*",
                                                                           rel( [],[],"",
                                                                                .( at( t( "h")
                                                                                       ,"h")
                                                                                   ,[]))))))
                                             ,
                                             .( head( "exists",
                                                      .( ".event",[])
                                                      ,
                                                      body( .( ".event",[])
                                                            ,
                                                            namely( x( "BETTYS",2)
                                                                    ,"@e",
                                                                    lam( "@e","LOC_at",
                                                                         rel( .( "@e",
                                                                                 .( ".event",[]))
                                                                              ,
                                                                              .( "*",
                                                                                 .( "*",[]))
                                                                              ,"",
                                                                              .( bodyClimb( "@e",
                                                                                            lam( "LOC_at","h",
                                                                                                 clean( 0,
                                                                                                        .( "ARG0",
                                                                                                           .( "LOC_at",[]))
                                                                                                        ,"*",
                                                                                                        clean( 1,
                                                                                                               .( "h",[])
                                                                                                               ,"*",
                                                                                                               rel( [],[],"cafe",
                                                                                                                    .( at( t( "h")
                                                                                                                           ,"h")
                                                                                                                       ,[]))))))
                                                                                 ,
                                                                                 .( rel( [],[],"",
                                                                                         .( namely( x( "EVENT",3)
                                                                                                    ,".event",
                                                                                                    rel( [],[],"ate",
                                                                                                         .( at( t( ".event")
                                                                                                                ,"EVENT")
                                                                                                            ,
                                                                                                            .( at( t( "LOC_at")
                                                                                                                   ,"LOC_at")
                                                                                                               ,
                                                                                                               .( at( t( "ARG0")
                                                                                                                      ,"ARG0")
                                                                                                                  ,[])))))
                                                                                            ,
                                                                                            .( bodyClimb( ".event",
                                                                                                          rel( [],[],"past",
                                                                                                               .( at( t( ".event")
                                                                                                                      ,"h")
                                                                                                                  ,[])))
                                                                                               ,[])))
                                                                                    ,[])))))))
                                                ,[])))))))))

With calculation of a <target_expr>, (30) becomes (31).

(31)

head( "exists",
      .( "@e",
         .( ".event",[]))
      ,
      .( x( "BETTYS",2)
         ,[])
      ,
      body( .( "@e",
               .( ".event",[]))
            ,
            head( "EVERYONE",
                  .( ".event",
                     .( ".e",[]))
                  ,
                  .( x( "PERSON",1)
                     ,[])
                  ,
                  body( .( ".event",
                           .( ".e",[]))
                        ,
                        rel( "",
                             .( bodyClimb( ".e",
                                           rel( "",
                                                .( at( x( "PERSON",1)
                                                       ,"h")
                                                   ,[])))
                                ,
                                .( head( "exists",
                                         .( ".event",[])
                                         ,
                                         .( x( "EVENT",3)
                                            ,[])
                                         ,
                                         body( .( ".event",[])
                                               ,
                                               rel( "",
                                                    .( bodyClimb( "@e",
                                                                  rel( "cafe",
                                                                       .( at( x( "BETTYS",2)
                                                                              ,"h")
                                                                          ,[])))
                                                       ,
                                                       .( rel( "",
                                                               .( rel( "ate",
                                                                       .( at( x( "EVENT",3)
                                                                              ,"EVENT")
                                                                          ,
                                                                          .( at( x( "BETTYS",2)
                                                                                 ,"LOC_at")
                                                                             ,
                                                                             .( at( x( "PERSON",1)
                                                                                    ,"ARG0")
                                                                                ,[]))))
                                                                  ,
                                                                  .( bodyClimb( ".event",
                                                                                rel( "past",
                                                                                     .( at( x( "EVENT",3)
                                                                                            ,"h")
                                                                                        ,[])))
                                                                     ,[])))
                                                          ,[])))))
                                   ,[])))))))

The role for any <discourse_referent> introduced by a noun phrase with respect to the content of the restriction of the introducing noun phrase is "h", which is basically a role instruction to identify the <discourse_referent> as contributing the noun phrase head.

     When the contents of headClimb/3 and bodyClimb/2 are integrated with the next commanding head/4 and body/2 occurrences that share a corresponding index, their content makes the appropriate contribution to the levels of quantificational closure that the head/4 and body/2 occurrences realise, either by enlarging the range of <discourse_referent>s quantified (as in the case of relocated headClimb/3 content), or having correct placement for restriction material (as in the case of relocated bodyClimb/2 content). With headClimb/3 and bodyClimb/2 eliminated after the relocation of their content, the resulting expression is the equivalent of a DRS encoding, with head/4 to capture quantification, and body/2 to capture conditions. Presented in the more familiar box notation, the output of (31) so revised would be (32):

(32)

Or the output of (31) revised as a predicate logic formula is (33):

(33)

exists BETTYS[2].(cafe(BETTYS[2])
  and EVERYONE PERSON[1].exists EVENT[3].(past(EVENT[3])
        and ate(EVENT[3],PERSON[1]) & loc_at(EVENT[3]) = BETTYS[2]))

Note how in the <target_expr> (31), there is a condition rel( "cafe", .( at( x( "BETTYS",2) ,"h"),[])) inside a bodyClimb/2 indexed with "@e". This same "@e" index occurs with the highest head/4 which brings about the discourse level closure, but does not appear with any other intervening head/4. As a consequence, given elimination of the placement instructions of headClimb/3 and bodyClimb/2, the restrictive content cafe(BETTYS[2]) is situated outside the scope of EVERYONE, as seen in the resulting DRS/predicate logic formula. In this way, the target language manages the quantification and restriction of <discourse_referent>s while taking into account the specific contexts into which they are introduced.


References

Kamp, Hans and Uwe Reyle. 1993. From Discourse to Logic: Introduction to Model-theoretic Semantics of Natural Language, Formal Logic and Discourse Representation Theory. Dordrecht: Kluwer.

Sampson, Geoffrey R. 1995. English for the Computer: The SUSANNE Corpus and Analytic Scheme. Oxford: Clarendon Press (Oxford University Press).

Santorini, Beatrice. 2016. Annotation manual for the Penn Historical Corpora and the PCEEC (Release 2). Tech. rep., Department of Computer and Information Science, University of Pennsylvania, Philadelphia. (http://www.ling.upenn.edu/histcorpora/annotation).