From b425d960dc130b963e7afc6c4132030e29bb69d1 Mon Sep 17 00:00:00 2001
From: aarne
Date: Fri, 6 Jul 2007 15:37:32 +0000
Subject: [PATCH] new tutorial almost finished
---
doc/intro-resource.txt | 2 +
doc/tutorial/gf-tutorial2_8.txt | 1259 +++++++++++++++++--------
doc/tutorial/resource-food/FoodEng.gf | 9 +
doc/tutorial/resource-food/FoodFre.gf | 6 +-
doc/tutorial/smarthouse/Smart.gf | 17 +
doc/tutorial/smarthouse/SmartEng.gf | 19 +
lib/resource-1.0/abstract/Cat.gf | 20 +-
lib/resource-1.0/doc/synopsis.html | 10 +
8 files changed, 936 insertions(+), 406 deletions(-)
create mode 100644 doc/tutorial/resource-food/FoodEng.gf
create mode 100644 doc/tutorial/smarthouse/Smart.gf
create mode 100644 doc/tutorial/smarthouse/SmartEng.gf
diff --git a/doc/intro-resource.txt b/doc/intro-resource.txt
index 25dcebde7..c4c292fca 100644
--- a/doc/intro-resource.txt
+++ b/doc/intro-resource.txt
@@ -1,3 +1,5 @@
+
+
==Coverage==
The GF Resource Grammar Library contains grammar rules for
diff --git a/doc/tutorial/gf-tutorial2_8.txt b/doc/tutorial/gf-tutorial2_8.txt
index 090d0bd9d..9820a7354 100644
--- a/doc/tutorial/gf-tutorial2_8.txt
+++ b/doc/tutorial/gf-tutorial2_8.txt
@@ -2090,26 +2090,592 @@ FIXME: The linearization type is ``{s : Str}`` for all these categories.
%--!
+
=Using the resource grammar library=
-%!include: ../intro-resource.txt
+In this chapter, we will take a look at the GF resource grammar library.
+We will use the library to implement a slightly extended ``Food`` grammar
+and port it to some new languages.
-%--!
-=Overview of the resource grammar library=
+==The coverage of the library==
-%!include: ../overview-resource.txt
+The GF Resource Grammar Library contains grammar rules for
+10 languages (in addition, 2 languages are available as incomplete
+implementations, and a few more are under construction). Its purpose
+is to make these rules available for application programmers,
+who can thereby concentrate on the semantic and stylistic
+aspects of their grammars, without having to think about
+grammaticality. The targeted level of application grammarians
+is that of a skilled programmer with
+a practical knowledge of the target languages, but without
+theoretical knowledge about their grammars.
+Such a combination of
+skills is typical of programmers who, for instance, want to localize
+software to new languages.
+
+The current resource languages are
+- ``Ara``bic (incomplete)
+- ``Cat``alan (incomplete)
+- ``Dan``ish
+- ``Eng``lish
+- ``Fin``nish
+- ``Fre``nch
+- ``Ger``man
+- ``Ita``lian
+- ``Nor``wegian
+- ``Rus``sian
+- ``Spa``nish
+- ``Swe``dish
+
+
+The first three letters (``Eng`` etc) are used in grammar module names.
+The incomplete Arabic and Catalan implementations are
+enough to be used in many applications; they both contain, amoung other
+things, complete inflectional morphology.
+
+
+==The resource API==
+
+The resource library API is devided into language-specific
+and language-independent parts. To put it roughly,
+- the syntax API is language-independent, i.e. has the same types and functions for all
+ languages.
+ Its name is ``Syntax``//L// for each language //L//
+- the morphology API is language-specific, i.e. has partly different types and functions
+ for different languages.
+ Its name is ``Paradigms``//L// for each language //L//
+
+
+A full documentation of the API is available on-line in the
+[resource synopsis ../../lib/resource-1.0/synopsis.html]. For our
+examples, we will only need a fragment of the full API.
+
+In the first examples,
+we will make use of the following categories, from the module ``Syntax``.
+
+|| Category | Explanation | Example ||
+| ``Utt`` | sentence, question, word... | "be quiet" |
+| ``Adv`` | verb-phrase-modifying adverb, | "in the house" |
+| ``AdA`` | adjective-modifying adverb, | "very" |
+| ``S`` | declarative sentence | "she lived here" |
+| ``Cl`` | declarative clause, with all tenses | "she looks at this" |
+| ``AP`` | adjectival phrase | "very warm" |
+| ``CN`` | common noun (without determiner) | "red house" |
+| ``NP`` | noun phrase (subject or object) | "the red house" |
+| ``Det`` | determiner phrase | "those seven" |
+| ``Predet`` | predeterminer | "only" |
+| ``Quant`` | quantifier with both sg and pl | "this/these" |
+| ``Prep`` | preposition, or just case | "in" |
+| ``A`` | one-place adjective | "warm" |
+| ``N`` | common noun | "house" |
+
+
+We will need the following syntax rules from ``Syntax``.
+
+|| Function | Type | Example ||
+| ``mkUtt`` | ``S -> Utt`` | //John walked// |
+| ``mkUtt`` | ``Cl -> Utt`` | //John walks// |
+| ``mkCl`` | ``NP -> AP -> Cl`` | //John is very old// |
+| ``mkNP`` | ``Det -> CN -> NP`` | //the first old man// |
+| ``mkNP`` | ``Predet -> NP -> NP`` | //only John// |
+| ``mkDet`` | ``Quant -> Det`` | //this// |
+| ``mkCN`` | ``N -> CN`` | //house// |
+| ``mkCN`` | ``AP -> CN -> CN`` | //very big blue house// |
+| ``mkAP`` | ``A -> AP`` | //old// |
+| ``mkAP`` | ``AdA -> AP -> AP`` | //very very old// |
+
+We will also need the following structural words from ``Syntax``.
+
+|| Function | Type | Example ||
+| ``all_Predet`` | ``Predet`` | //all// |
+| ``defPlDet`` | ``Det`` | //the (houses)// |
+| ``this_Quant`` | ``Quant`` | //this// |
+| ``very_AdA`` | ``AdA`` | //very// |
+
+
+For French, we will use the following part of ``ParadigmsFre``.
+
+|| Function | Type | Example ||
+| ``Gender`` | ``Type`` | - |
+| ``masculine`` | ``Gender`` | - |
+| ``feminine`` | ``Gender`` | - |
+| ``mkN`` | ``(cheval : Str) -> N`` | - |
+| ``mkN`` | ``(foie : Str) -> Gender -> N`` | - |
+| ``mkA`` | ``(cher : Str) -> A`` | - |
+| ``mkA`` | ``(sec,seche : Str) -> A`` | - |
+
+
+For German, we will use the following part of ``ParadigmsGer``.
+
+|| Function | Type | Example ||
+| ``Gender`` | ``Type`` | - |
+| ``masculine`` | ``Gender`` | - |
+| ``feminine`` | ``Gender`` | - |
+| ``neuter`` | ``Gender`` | - |
+| ``mkN`` | ``(Stufe : Str) -> N`` | - |
+| ``mkN`` | ``(Bild,Bilder : Str) -> Gender -> N`` | - |
+| ``mkA`` | ``Str -> A`` | - |
+| ``mkA`` | ``(gut,besser,beste : Str) -> A`` | //gut,besser,beste// |
+
+
+**Exercise**. Try out the morphological paradigms in different languages. Do
+in this way:
+```
+ > i -path=alltenses:prelude -retain alltenses/ParadigmsGer.gfr
+ > cc mkN "Farbe"
+ > cc mkA "gut" "besser" "beste"
+```
+
+
+==Example: French==
+
+We start with an abstract syntax that is like ``Food`` before, but
+has a plural determiner (//all wines//) and some new nouns that will
+need different genders in most languages.
+```
+ abstract Food = {
+ cat
+ S ; Item ; Kind ; Quality ;
+ fun
+ Is : Item -> Quality -> S ;
+ This, All : Kind -> Item ;
+ QKind : Quality -> Kind -> Kind ;
+ Wine, Cheese, Fish, Beer, Pizza : Kind ;
+ Very : Quality -> Quality ;
+ Fresh, Warm, Italian, Expensive, Delicious, Boring : Quality ;
+ }
+```
+The French implementation opens ``SyntaxFre`` and ``ParadigmsFre``
+to get access to the resource libraries needed. In order to find
+the libraries, a ``path`` directive is prepended; it is interpreted
+relative to the environment variable ``GF_LIB_PATH``.
+```
+ --# -path=.:present:prelude
+
+ concrete FoodFre of Food = open SyntaxFre,ParadigmsFre in {
+ lincat
+ S = Utt ;
+ Item = NP ;
+ Kind = CN ;
+ Quality = AP ;
+ lin
+ Is item quality = mkUtt (mkCl item quality) ;
+ This kind = mkNP (mkDet this_Quant) kind ;
+ All kind = mkNP all_Predet (mkNP defPlDet kind) ;
+ QKind quality kind = mkCN quality kind ;
+ Wine = mkCN (mkN "vin") ;
+ Beer = mkCN (mkN "bière") ;
+ Pizza = mkCN (mkN "pizza" feminine) ;
+ Cheese = mkCN (mkN "fromage" masculine) ;
+ Fish = mkCN (mkN "poisson") ;
+ Very quality = mkAP very_AdA quality ;
+ Fresh = mkAP (mkA "frais" "fraîche") ;
+ Warm = mkAP (mkA "chaud") ;
+ Italian = mkAP (mkA "italien") ;
+ Expensive = mkAP (mkA "cher") ;
+ Delicious = mkAP (mkA "délicieux") ;
+ Boring = mkAP (mkA "ennuyeux") ;
+ }
+```
+The ``lincat`` definitions in ``FoodFre`` assign **resource categories**
+to **application categories**. In a sense, the application categories
+are **semantic**, as they correspond to concepts in the grammar application,
+whereas the resource categories are **syntactic**: they give the linguistic
+means to express concepts in any application.
+
+The ``lin`` definitions likewise assign resource functions to application
+functions. Under the hood, there is a lot of matching with parameters to
+take care of word order, inflection, and agreement. But the user of the
+library sees nothing of this: the only parameters you need to give are
+the genders of some nouns, which cannot be correctly inferred from the word.
+
+In French, for example, the one-argument ``mkN`` assignes the noun the feminine
+gender if and only if it ends with an //e//. Therefore the words //fromage// and
+//pizza// are given genders. One can of course always give genders manually, to
+be on the safe side.
+
+As for inflection, the one-argument adjective pattern ``mkA`` takes care of
+completely regular adjective such as //chaud-chaude//, but also of special
+cases such as //italien-italien//, //cher-chère//, and //délicieux-délicieuse//.
+But it cannot form //frais-fraîche// properly. Once again, you can give more
+forms to be on the safe side. You can also test the paradigms in the GF
+program.
+
+**Exercise**. Compile the grammar ``FoodFre`` and generate and parse some sentences.
+
+**Exercise**. Write a concrete syntax of ``Food`` for English or some other language
+included in the resource library. You can also compare the output with the hand-written
+grammars presented earlier in this tutorial.
+
+
+
+==Functor implementation of multilingual grammars==
+
+If you did the exercise of writing a concrete syntax of ``Food`` for some other
+language, you probably noticed that much of the code looks exactly the same
+as for French. The immediate reason for this is that the ``Syntax`` API is the
+same for all languages; the deeper reason is that all languages (at least those
+in the resource package) have the same syntactic structures and tend to use them
+in similar ways. Thus it is only the lexical parts of a concrete syntax that
+you need to write anew for a new language. In brief,
+- first copy the concrete syntax for one language
+- then change the words (the strings and perhaps some paradigms)
+
+
+But programming by copy-and-paste is not worthy of a functional programmer.
+Can we write a function that takes care of the shared parts of grammar modules?
+Yes, we can. It is not a function in the ``fun`` or ``oper`` sense, but
+a function operating on modules, called a **functor**. This construct
+is familiar from the functional languages ML and OCaml, but it does not
+exist in Haskell. It also bears some resemblance to templates in C++.
+Functors are also known as **parametrized modules**.
+
+In GF, a functor is a module that ``open``s one or more **interfaces**.
+An ``interface`` is a module similar to a ``resource``, but it only
+contains the types of ``oper``s, not their definitions. You can think
+of an interface as a kind of a record type. Thus a functor is a kind
+of a function taking records as arguments and producins a module
+as value.
+
+Let us look at a functor implementation of the ``Food`` grammar.
+Consider its module header first:
+```
+ incomplete concrete FoodI of Food = open Syntax, LexFood in
+```
+In the functor-function analogy, ``FoodI`` would be presented as a function
+with the following type signature:
+```
+ FoodI : instance of Syntax -> instance of LexFood -> concrete of Food
+```
+It takes as arguments two interfaces:
+- ``Syntax``, the resource grammar interface
+- ``LexFood``, the domain-specific lexicon interface
+
+
+Functors opening ``Syntax`` and a domain lexicon interface are in fact
+so typical in GF applications, that this structure could be called a **design patter**
+for GF grammars. The idea in this pattern is, again, that
+the languages use the same syntactic structures but different words.
+
+Before going to the details of the module bodies, let us look at how functors
+are concretely used. An interface has a header such as
+```
+ interface LexFood = open Syntax in
+```
+To give an ``instance`` of it means that all ``oper``s are given definitione (of
+appropriate types). For example,
+```
+ instance LexFoodGer of LexFood = open SyntaxGer, ParadigmsGer in
+```
+Notice that when an interface opens an interface, such as ``Syntax``, then its instance
+opens an instance of it. But the instance may also open some resources - typically,
+a domain lexicon instance opens a ``Paradigms`` module.
+
+In the function-functor analogy, we now have
+```
+ SyntaxGer : instance of Syntax
+ LexFoodGer : instance of LexFood
+```
+Thus we can complete the German implementation by "applying" the functor:
+```
+ FoodI SyntaxGer LexFoodGer : concrete of Food
+```
+The GF syntax for doing so is
+```
+ concrete FoodGer of Food = FoodI with
+ (Syntax = SyntaxGer),
+ (LexFood = LexFoodGer) ;
+```
+Notice that this is the //complete// module, not just a header of it.
+The module body is received from ``FoodI``, by instantiating the
+interface constants with their definitions given in the German
+instances.
+
+A module of this form, characterized by the keyword ``with``, is
+called a **functor instantiation**.
+
+Here is the complete code for the functor ``FoodI``:
+```
+ incomplete concrete FoodI of Food = open Syntax, LexFood in {
+ lincat
+ S = Utt ;
+ Item = NP ;
+ Kind = CN ;
+ Quality = AP ;
+ lin
+ Is item quality = mkUtt (mkCl item quality) ;
+ This kind = mkNP (mkDet this_Quant) kind ;
+ All kind = mkNP all_Predet (mkNP defPlDet kind) ;
+ QKind quality kind = mkCN quality kind ;
+ Wine = mkCN wine_N ;
+ Beer = mkCN beer_N ;
+ Pizza = mkCN pizza_N ;
+ Cheese = mkCN cheese_N ;
+ Fish = mkCN fish_N ;
+ Very quality = mkAP very_AdA quality ;
+ Fresh = mkAP fresh_A ;
+ Warm = mkAP warm_A ;
+ Italian = mkAP italian_A ;
+ Expensive = mkAP expensive_A ;
+ Delicious = mkAP delicious_A ;
+ Boring = mkAP boring_A ;
+}
+```
+
+
+==Interfaces and instances==
+
+Let us now define the ``LexFood`` interface:
+```
+ interface LexFood = open Syntax in {
+ oper
+ wine_N : N ;
+ beer_N : N ;
+ pizza_N : N ;
+ cheese_N : N ;
+ fish_N : N ;
+ fresh_A : A ;
+ warm_A : A ;
+ italian_A : A ;
+ expensive_A : A ;
+ delicious_A : A ;
+ boring_A : A ;
+}
+```
+In this interface, only lexical items are declared. In general, an
+interface can declare any functions and also types. The ``Syntax``
+interface does this.
+
+Here is the German instance of the interface:
+```
+ instance LexFoodGer of LexFood = open SyntaxGer, ParadigmsGer in {
+ oper
+ wine_N = mkN "Wein" ;
+ beer_N = mkN "Bier" "Biere" neuter ;
+ pizza_N = mkN "Pizza" "Pizzen" feminine ;
+ cheese_N = mkN "Käse" "Käsen" masculine ;
+ fish_N = mkN "Fisch" ;
+ fresh_A = mkA "frisch" ;
+ warm_A = mkA "warm" "wärmer" "wärmste" ;
+ italian_A = mkA "italienisch" ;
+ expensive_A = mkA "teuer" ;
+ delicious_A = mkA "köstlich" ;
+ boring_A = mkA "langweilig" ;
+}
+```
+Just to complete the picture, we repeat the German functor instantiation
+for ``FoodI``, this time with a path directive that makes it compilable.
+```
+ --# -path=.:present:prelude
+
+ concrete FoodGer of Food = FoodI with
+ (Syntax = SyntaxGer),
+ (LexFood = LexFoodGer) ;
+```
+
+
+**Exercise**. Compile and test ``FoodGer``.
+
+**Exercise**. Refactor ``FoodFre`` as a functor instantiation.
+
+
+
+==Adding languages to a functor implementation==
+
+Once we have an application grammar defined by using a functor,
+adding a new language is simple. Just two modules need to be written:
+- a domain lexicon instance
+- a functor instantiation
+
+
+The functor instantiation is completely mechanical to write.
+Here is one for Finnish:
+```
+--# -path=.:present:prelude
+
+concrete FoodFin of Food = FoodI with
+ (Syntax = SyntaxFin),
+ (LexFood = LexFoodFin) ;
+```
+The domain lexicon instance requires some knowledge of the words of the
+language: what words are used for which concepts, how the words are
+inflected, plus features such as genders. Here is a lexicon instance for
+Finnish:
+```
+ instance LexFoodFin of LexFood = open SyntaxFin, ParadigmsFin in {
+ oper
+ wine_N = mkN "viini" ;
+ beer_N = mkN "olut" ;
+ pizza_N = mkN "pizza" ;
+ cheese_N = mkN "juusto" ;
+ fish_N = mkN "kala" ;
+ fresh_A = mkA "tuore" ;
+ warm_A = mkA "lämmin" ;
+ italian_A = mkA "italialainen" ;
+ expensive_A = mkA "kallis" ;
+ delicious_A = mkA "herkullinen" ;
+ boring_A = mkA "tylsä" ;
+ }
+```
+
+**Exercise**. Instantiate the functor ``FoodI`` to some language of
+your choice.
+
+
+==Division of labour revisited==
+
+One purpose with the resource grammars was stated to be a division
+of labour between linguists and application grammarians. We can now
+reflect on what this means more precisely, by asking ourselves what
+skills are required of grammarians working on different components.
+
+Building a GF application starts from the abstract syntax. Writing
+an abstract syntax requires
+- understanding the semantic structure of the application domain
+- knowledge of the GF fragment with categories and functions
+
+
+If the concrete syntax is written by means of a functor, the programmer
+has to decide what parts of the implementation are put to the interface
+and what parts are shared in the functor. This requires
+- knowing how the domain concepts are expressed in natural language
+- knowledge of the resource grammar library - the categories and combinators
+- understanding what parts are likely to be expressed in language-dependent
+ ways, so that they must belong to the interface and not the functor
+- knowledge of the GF fragment with function applications and strings
+
+
+Instantiating a ready-made functor to a new language is less demanding.
+It requires essentially
+- knowing how the domain words are expressed in the language
+- knowing, roughly, how these words are inflected
+- knowledge of the paradigms available in the library
+- knowledge of the GF fragment with function applications and strings
+
+
+Notice that none of these tasks requires the use of GF records, tables,
+or parameters. Thus only a small fragment of GF is needed; the rest of
+GF is only relevant for those who write the libraries.
+
+Of course, grammar writing is not always straightforward usage of libraries.
+For example, GF can be used for other languages than just those in the
+libraries - for both natural and formal languages. A knowledge of records
+and tables can, unfortunately, also be needed for understanding GF's error
+messages.
+
+**Exercise**. Design a small grammar that can be used for controlling
+an MP3 player. The grammar should be able to recognize commands such
+as //play this song//, with the following variations:
+- verbs: //play//, //remove//
+- objects: //song//, //artist//
+- determiners: //this//, //the previous//
+- verbs without arguments: //stop//, //pause//
+
+
+The implementation goes in the following phases:
++ abstract syntax
++ functor and lexicon interface
++ lexicon instance for the first language
++ functor instantiation for the first language
++ lexicon instance for the second language
++ functor instantiation for the second language
++ ...
+
+
+
+==Restricted inheritance==
+
+A functor implementation using the resource ``Syntax`` interface
+works as long as all concepts are expressed by using the same structures
+in all languages. If this is not the case, the deviant linearization can
+be made into a parameter and moved to the domain lexicon interface.
+
+Let us take a slightly contrived example: assume that English has
+no word for ``Pizza``, but has to use the paraphrase //Italian pie//.
+This paraphrase is no longer a noun ``N``, but a complex phrase
+in the category ``CN``. An obvious way to solve this problem is
+to change interface ``LexEng`` so that the constant declared for
+``Pizza`` gets a new type:
+```
+ oper pizza_CN : CN ;
+```
+But this solution is unstable: we may end up changing the interface
+and the function with each new language, and we must every time also
+change the interface instances for the old languages to maintain
+type correctness.
+
+A better solution is to use **restricted inheritance**: the English
+instantiation inherits the functor implementation except for the
+constant ``Pizza``. This is how we write:
+```
+ --# -path=.:present:prelude
+
+ concrete FoodEng of Food = FoodI - [Pizza] with
+ (Syntax = SyntaxEng),
+ (LexFood = LexFoodEng) **
+ open SyntaxEng, ParadigmsEng in {
+
+ lin Pizza = mkCN (mkA "Italian") (mkN "pie") ;
+ }
+```
+Restricted inheritance is available for all inherited modules. One can for
+instance exclude some mushrooms and pick up just some fruit in
+the ``FoodMarket`` example:
+```
+ abstract Foodmarket = Food, Fruit [Peach], Mushroom - [Agaric]
+```
+A concrete syntax of ``Foodmarket`` must then indicate the same inheritance
+restrictions.
+
+
+**Exercise**. Change ``FoodGer`` in such a way that it says, instead of
+//X is Y//, the equivalent of //X must be Y// (//X muss Y sein//).
+You will have to browse the full resource API to find all
+the functions needed.
+
+
+==Browsing the resource with GF commands=
+
+In addition to reading the
+[resource synopsis ../../lib/resource-1.0/synopsis.html], you
+can find resource function combinations by using the parser. This
+is so because the resource library is in the end implemented as
+a top-level ``abstract-concrete`` grammar, on which parsing
+and linearization work.
+
+Unfortunately, only English and the Scandinavian languages can be
+parsed within acceptable computer resource limits when the full
+resource is used.
+
+To look for a syntax tree in the overload API by parsing, do like this:
+```
+ > $GF_LIB_PATH
+ > i -path=alltenses:prelude alltenses/OverLangEng.gfc
+ > p -cat=S -overload "this grammar is too big"
+```
+To view linearizations in all languages by parsing from English:
+```
+ > i alltenses/langs.gfcm
+ > p -cat=S -lang=LangEng "this grammar is too big" | tb
+```
+
+**Exercise**. Find the resource grammar translations for the following
+English phrases (parse in the category ``Phr``). You can first try to
+build the terms manually.
+
+//every man loves a woman//
+
+//this grammar speaks more than ten languages//
+
+//which languages aren't in the grammar//
+
+//which languages did you want to speak//
=More concepts of abstract syntax=
-This section is about the use of the type theory part of GF for
-including more semantics in grammars. Some of the subsections present
-ideas that have not yet been used in real-world applications, and whose
-tool support outside the GF program is not complete.
-
-
==GF as a logical framework==
In this section, we will show how
@@ -2135,162 +2701,267 @@ abstract Arithm = {
And : Prop -> Prop -> Prop ; -- A and B
}
```
-A concrete syntax is given below, as an example of using the resource grammar
-library.
+
+**Exercise**. Give a concrete syntax of ``Arithm``, either from scatch or
+by using the resource library.
+
==Dependent types==
**Dependent types** are a characteristic feature of GF,
-inherited from the
-**constructive type theory** of Martin-Löf and
+inherited from the **constructive type theory** of Martin-Löf and
distinguishing GF from most other grammar formalisms and
functional programming languages.
-The initial main motivation for developing GF was, indeed,
-to have a grammar formalism with dependent types.
-As can be inferred from the fact that we introduce them only now,
-after having written lots of grammars without them,
-dependent types are no longer the only motivation for GF.
-But they are still important and interesting.
-
Dependent types can be used for stating stronger
-**conditions of well-formedness** than non-dependent types.
-A simple example is postal addresses. Ignoring the other details,
-let us take a look at addresses consisting of
-a street, a city, and a country.
-```
-abstract Address = {
- cat
- Address ; Country ; City ; Street ;
+**conditions of well-formedness** than ordinary types.
+A simple example is a "smart house" system, which
+defines voice commands for household appliances. This example
+is borrowed from the
+[Regulus Book http://cslipublications.stanford.edu/site/1575865262.html]
+(Rayner & al. 2006).
- fun
- mkAddress : Country -> City -> Street -> Address ;
+In a smart house, the owner or tennant can use speech to dim lights, swith
+on the fan, etc. For each ``Kind`` of a device, there is a set of
+``Actions`` that can be performed on it; thus one can dim the lights but
+ not the fan, for example. These dependencies can be expressed by
+by making the type ``Action`` dependent on ``Kind``. We express this
+as follows in ``cat`` declarations:
+```
+ cat
+ Command ;
+ Kind ;
+ Action Kind ;
+ Device Kind ;
+```
+The crucial use of the dependencies is made in the rule for forming commands:
+```
+ fun CAction : (k : Kind) -> Action k -> Device k -> Command ;
+```
+In other words: an action and a device can be combined into a command only
+if they are of the same ``Kind`` ``k``. If we have the functions
+```
+ DKindOne : (k : Kind) -> Device k ; -- the light
- UK, France : Country ;
- Paris, London, Grenoble : City ;
- OxfordSt, ShaftesburyAve, BdRaspail, RueBlondel, AvAlsaceLorraine : Street ;
- }
+ light, fan : Kind ;
+ dim : Action light ;
```
-The linearization rules are straightforward,
+we can form the syntax tree
```
- lin
- mkAddress country city street =
- ss (street.s ++ "," ++ city.s ++ "," ++ country.s) ;
- UK = ss ("U.K.") ;
- France = ss ("France") ;
- Paris = ss ("Paris") ;
- London = ss ("London") ;
- Grenoble = ss ("Grenoble") ;
- OxfordSt = ss ("Oxford" ++ "Street") ;
- ShaftesburyAve = ss ("Shaftesbury" ++ "Avenue") ;
- BdRaspail = ss ("boulevard" ++ "Raspail") ;
- RueBlondel = ss ("rue" ++ "Blondel") ;
- AvAlsaceLorraine = ss ("avenue" ++ "Alsace-Lorraine") ;
+ CAction light dim (DKindOne light)
```
-Notice that, in ``mkAddress``, we have
-reversed the order of the constituents. The type of ``mkAddress``
-in the abstract syntax takes its arguments in a "logical" order,
-with increasing precision. (This order is sometimes even used in the
-concrete syntax of addresses, e.g. in Russia).
+but we cannot form the trees
+```
+ CAction light dim (DKindOne fan)
+ CAction fan dim (DKindOne light)
+ CAction fan dim (DKindOne fan)
+```
+Linearization rules are written as usual: the concrete syntax does not
+know if a category is a dependent type. In English, you can write as follows:
+```
+ lincat Action = {s : Str} ;
+ lin CAction kind act dev = {s = act.s ++ dev.s} ;
+```
+Notice that the argument ``kind`` does not show in the linearization.
+The type checker will be able to reconstruct it from the ``dev`` argument.
-Both existing and non-existing addresses are recognized by this
-grammar. The non-existing ones in the following randomly generated
-list have afterwards been marked by *:
+Parsing with dependent types happens in two phases. If you just parse in
+the usual way, the ``kind`` argument is not found:
```
- > gr -cat=Address -number=7 | l
+ > parse "dim the light"
+ CAction ? dim (DKindOne light)
+```
+Moreover, type-incorrect commands are not rejected:
+```
+ > parse "dim the fan"
+ CAction ? dim (DKindOne fan)
+```
+The question mark ``?`` is a **metavariable**, and is returned by the parser
+for any subtree that is suppressed by a linearization rule.
- * Oxford Street , Paris , France
- * Shaftesbury Avenue , Grenoble , U.K.
- boulevard Raspail , Paris , France
- * rue Blondel , Grenoble , U.K.
- * Shaftesbury Avenue , Grenoble , France
- * Oxford Street , London , France
- * Shaftesbury Avenue , Grenoble , France
+To get rid of metavariables, you must feed the parse result into the
+second phase of **solving** them. The ``solve`` process uses the dependent
+type checker to restore the values of the metavariables. It is invoked by
+the command ``put_tree = pt`` with the flag ``-transform=solve``:
```
-Dependent types provide a way to guarantee that addresses are
-well-formed. What we do is to include **contexts** in
-``cat`` judgements:
+ > parse "dim the light" | put_tree -transform=solve
+ CAction light dim (DKindOne light)
```
- cat
- Address ;
- Country ;
- City Country ;
- Street (x : Country)(City x) ;
+The ``solve`` process may fail, in which case no tree is returned:
```
-The first two judgements are as before, but the third one makes
-``City`` dependent on ``Country``: there are no longer just cities,
-but cities of the U.K. and cities of France. The fourth judgement
-makes ``Street`` dependent on ``City``; but since
-``City`` is itself dependent on ``Country``, we must
-include them both in the context, moreover guaranteeing that
-the city is one of the given country. Since the context itself
-is built by using a dependent type, we have to use variables
-to indicate the dependencies. The judgement we used for ``City``
-is actually shorthand for
+ > parse "dim the fan" | put_tree -transform=solve
+ no tree found
```
- cat City (x : Country)
-```
-which is only possible if the subsequent context does not depend on ``x``.
-The ``fun`` judgements of the grammar are modified accordingly:
-```
- fun
- mkAddress : (x : Country) -> (y : City x) -> Street x y -> Address ;
-
- UK : Country ;
- France : Country ;
- Paris : City France ;
- London : City UK ;
- Grenoble : City France ;
- OxfordSt : Street UK London ;
- ShaftesburyAve : Street UK London ;
- BdRaspail : Street France Paris ;
- RueBlondel : Street France Paris ;
- AvAlsaceLorraine : Street France Grenoble ;
-```
-Since the type of ``mkAddress`` now has dependencies among
-its argument types, we have to use variables just like we used in
-the context of ``Street`` above. What we claimed to be the
-"logical" order of the arguments is now forced by the type system
-of GF: a variable must be declared (=bound) before it can be
-referenced (=used).
-The effect of dependent types is that the *-marked addresses above are
-no longer well-formed. What the GF parser actually does is that it
-initially accepts them (by using a context-free parsing algorithm)
-and then rejects them (by type checking). The random generator does not produce
-illegal addresses (this could be useful in bulk mailing!).
-The linearization algorithm does not care about type dependencies;
-actually, since the //categories// (ignoring their arguments)
-are the same in both abstract syntaxes,
-we use the same concrete syntax
-for both of them.
+**Exercise**. Write an abstract syntax module with above contents
+and an appropriate English concrete syntax. Try to parse the commands
+//dim the light// and //dim the fan//, with and without ``solve`` filtering.
-**Remark**. Function types //without//
+
+**Exercise**. Perform random and exhaustive generation, with and without
+``solve`` filtering.
+
+**Exercise**. Add some device kinds and actions to the grammar.
+
+
+==Polymorphism==
+
+Sometimes an action can be performed on all kinds of devices. It would be
+possible to introduce separate ``fun`` constants for each kind-action pair,
+but this would be tedious. Instead, one can use **polymorphic** actions,
+i.e. actions that take a ``Kind`` as an argument and produce an ``Action``
+for that ``Kind``:
+```
+ fun switchOn, switchOff : (k : Kind) -> Action k ;
+```
+Functions that are not polymorphic are **monomorphic**. However, the
+dichotomy into monomorphism and full polymorphism is not always sufficien
+for good semantic modelling: very typically, some actions are defined
+for a subset of devices, but not just one. For instance, both doors and
+windows can be opened, whereas lights cannot.
+We will return to this problem by introducing the
+concept of **restricted polymorphism** later,
+after a chapter proof objects.
+
+
+
+==Dependent types and spoken language models==
+
+We have used dependent types to control semantic well-formedness
+in grammars. This is important in traditional type theory
+applications such as proof assistants, where only mathematically
+meaningful formulas should be constructed. But semantic filtering has
+also proved important in speech recognition, because it reduces the
+ambiguity of the results.
+
+
+===Grammar-based language models===
+
+The standard way of using GF in speech recognition is by building
+**grammar-based language models**. To this end, GF comes with compilers
+into several formats that are used in speech recognition systems.
+One such format is GSL, used in the [Nuance speech recognizer www.nuance.com].
+It is produced from GF simply by printing a grammar with the flag
+``-printer=gsl``.
+```
+ > import -conversion=finite SmartEng.gf
+ > print_grammar -printer=gsl
+
+ ;GSL2.0
+ ; Nuance speech recognition grammar for SmartEng
+ ; Generated by GF
+
+ .MAIN SmartEng_2
+
+ SmartEng_0 [("switch" "off") ("switch" "on")]
+ SmartEng_1 ["dim" ("switch" "off")
+ ("switch" "on")]
+ SmartEng_2 [(SmartEng_0 SmartEng_3)
+ (SmartEng_1 SmartEng_4)]
+ SmartEng_3 ("the" SmartEng_5)
+ SmartEng_4 ("the" SmartEng_6)
+ SmartEng_5 "fan"
+ SmartEng_6 "light"
+```
+Now, GSL is a context-free format, so how does it cope with dependent types?
+In general, dependent types can give rise to infinitely many basic types
+(exercise!), whereas a context-free grammar can by definition only have
+finitely many nonterminals.
+
+This is where the flag ``-conversion=finite`` is needed in hte ``import``
+command. Its effect is to convert a GF grammar with dependent types to
+one without, so that each instance of a dependent type is replaced by
+an atomic type. This can then be used as a nonterminal in a context-free
+grammar. The ``finite`` conversion presupposes that every
+dependent type only has finitely many instances, which is in fact
+the case in the ``Smart`` grammar.
+
+
+*Exercise**. If you have access to the Nuance speech recognizer,
+test it with GF-generated language models for ``SmartEng``. Do this
+both with and without ``-conversion=finite``.
+
+**Exercise**. Construct an abstract syntax with infinitely many instances
+of dependent types.
+
+
+===Statistical language models===
+
+An alternative to grammar-based language models are
+**statistical language models** (**SLM**s). An SLM is
+built from a **corpus**, i.e. a set of utterances. It specifies the
+probability of each **n-gram**, i.e. sequence of //n// words. The
+typical value of //n// is 2 (bigrams) or 3 (trigrams).
+
+One advantage of SLMs over grammar-based models is that they are
+**robust**, i.e. they can be used to recognize sequences that would
+be out of the grammar or the corpus. Another advantage is that
+an SLM can be built "for free" if a corpus is available.
+
+However, collecting a corpus can require a lot of work, and writing
+a grammar can be less demanding, especially with tools such as GF or
+Regulus. This advantage of grammars can be combined with robustness
+by creating a back-up SLM from a **synthesized corpus**. This means
+simply that the grammar is used for generating such a corpus.
+In GF, this can be done with the ``generate_trees`` command.
+As with grammar-based models, the quality of the SLM is better
+if meaningless utterances are excluded from the corpus. Thus
+a good way to generate an SLM from a GF grammar is by using
+dependent types and filter the results with the type checker:
+```
+ > generate_trees | put_trees -transform=solve | linearize
+```
+
+
+**Exercise**. Measure the size of the corpus generated from
+``SmartEng``, with and without type checker filtering.
+
+
+
+==Digression: dependent types in concrete syntax==
+
+===Variables in function types===
+
+A dependent function type needs to introduce a variable for
+its argument type, as in
+```
+ switchOff : (k : Kind) -> Action k
+```
+Function types //without//
variables are actually a shorthand notation: writing
```
- fun PredV1 : NP -> V1 -> S
+ fun PredVP : NP -> VP -> S
```
is shorthand for
```
- fun PredV1 : (x : NP) -> (y : V1) -> S
+ fun PredVP : (x : NP) -> (y : VP) -> S
```
or any other naming of the variables. Actually the use of variables
sometimes shortens the code, since we can write e.g.
```
- oper triple : (x,y,z : Str) -> Str = ...
+ octuple : (x,y,z,u,v,w,s,t : Str) -> Str
```
If a bound variable is not used, it can here, as elsewhere in GF, be replaced by
a wildcard:
```
- oper triple : (_,_,_ : Str) -> Str = ...
+ octuple : (_,_,_,_,_,_,_,_ : Str) -> Str
+```
+A good practice for such functions is to indicate the number of arguments
+in the type:
+```
+ octuple : (x1,_,_,_,_,_,_,x8 : Str) -> Str
+```
+One can also use the variables to document what each argument is expected
+to provide, as is done in inflection paradigms in the resource grammar.
+```
+ mkV : (drink,drank,drunk : Str) -> V
```
-
-==Dependent types in concrete syntax==
+===Polymorphism in concrete syntax===
The **functional fragment** of GF
terms and types comprises function types, applications, lambda
@@ -2330,196 +3001,6 @@ for a Haskell or ML programmer.
-==Expressing selectional restrictions==
-
-This section introduces a way of using dependent types to
-formalize a notion known as **selectional restrictions**
-in linguistics. We first present a mathematical model
-of the notion, and then integrate it in a linguistically
-motivated syntax.
-
-In linguistics, a
-grammar is usually thought of as being about **syntactic well-formedness**
-in a rather liberal sense: an expression can be well-formed without
-being meaningful, in other words, without being
-**semantically well-formed**.
-For instance, the sentence
-```
- the number 2 is equilateral
-```
-is syntactically well-formed but semantically ill-formed.
-It is well-formed because it combines a well-formed
-noun phrase ("the number 2") with a well-formed
-verb phrase ("is equilateral") and satisfies the agreement
-rule saying that the verb phrase is inflected in the
-number of the noun phrase:
-```
- fun PredVP : NP -> VP -> S ;
- lin PredVP np v = {s = np.s ++ vp.s ! np.n} ;
-```
-It is ill-formed because the predicate "is equilateral"
-is only defined for triangles, not for numbers.
-
-In a straightforward type-theoretical formalization of
-mathematics, domains of mathematical objects
-are defined as types. In GF, we could write
-```
- cat Nat ;
- cat Triangle ;
- cat Prop ;
-```
-for the types of natural numbers, triangles, and propositions,
-respectively.
-Noun phrases are typed as objects of basic types other than
-``Prop``, whereas verb phrases are functions from basic types
-to ``Prop``. For instance,
-```
- fun two : Nat ;
- fun Even : Nat -> Prop ;
- fun Equilateral : Triangle -> Prop ;
-```
-With these judgements, and the linearization rules
-```
- lin two = ss ["the number 2"] ;
- lin Even x = ss (x.s ++ ["is even"]) ;
- lin Equilateral x = ss (x.s ++ ["is equilateral"]) ;
-```
-we can form the proposition ``Even two``
-```
- the number 2 is even
-```
-but no proposition linearized to
-```
- the number 2 is equilateral
-```
-since ``Equilateral two`` is not a well-formed type-theoretical object.
-It is not even accepted by the context-free parser.
-
-When formalizing mathematics, e.g. in the purpose of
-computer-assisted theorem proving, we are certainly interested
-in semantic well-formedness: we want to be sure that a proposition makes
-sense before we make the effort of proving it. The straightforward typing
-of nouns and predicates shown above is the way in which this
-is guaranteed in various proof systems based on type theory.
-(Notice that it is still possible to form //false// propositions,
-e.g. "the number 3 is even".
-False and meaningless are different things.)
-
-As shown by the linearization rules for ``two``, ``Even``,
-etc, it //is// possible to use straightforward mathematical typings
-as the abstract syntax of a grammar. However, this syntax is not very
-expressive linguistically: for instance, there is no distinction between
-adjectives and verbs. It is hard to give rules for structures like
-adjectival modification ("even number") and conjunction of predicates
-("even or odd").
-
-By using dependent types, it is simple to combine a linguistically
-motivated system of categories with mathematically motivated
-type restrictions. What we need is a category of domains of
-individual objects,
-```
- cat Dom
-```
-and dependencies of other categories on this:
-```
- cat
- S ; -- sentence
- V1 Dom ; -- one-place verb with specific subject type
- V2 Dom Dom ; -- two-place verb with specific subject and object types
- A1 Dom ; -- one-place adjective
- A2 Dom Dom ; -- two-place adjective
- NP Dom ; -- noun phrase for an object of specific type
- Conj ; -- conjunction
- Det ; -- determiner
-```
-Having thus parametrized categories on domains, we have to reformulate
-the rules of predication, etc, accordingly. This is straightforward:
-```
- fun
- PredV1 : (A : Dom) -> NP A -> V1 A -> S ;
- ComplV2 : (A,B : Dom) -> V2 A B -> NP B -> V1 A ;
- DetCN : Det -> (A : Dom) -> NP A ;
- ModA1 : (A : Dom) -> A1 A -> Dom ;
- ConjS : Conj -> S -> S -> S ;
- ConjV1 : (A : Dom) -> Conj -> V1 A -> V1 A -> V1 A ;
-```
-In linearization rules,
-we use wildcards for the domain arguments,
-because they don't affect linearization:
-```
- lin
- PredV1 _ np vp = ss (np.s ++ vp.s) ;
- ComplV2 _ _ v2 np = ss (v2.s ++ np.s) ;
- DetCN det cn = ss (det.s ++ cn.s) ;
- ModA1 cn a1 = ss (a1.s ++ cn.s) ;
- ConjS conj s1 s2 = ss (s1.s ++ conj.s ++ s2.s) ;
- ConjV1 _ conj v1 v2 = ss (v1.s ++ conj.s ++ v2.s) ;
-```
-The domain arguments thus get suppressed in linearization.
-Parsing initially returns metavariables for them,
-but type checking can usually restore them
-by inference from those arguments that are not suppressed.
-
-One traditional linguistic example of domain restrictions
-(= selectional restrictions) is the contrast between the two sentences
-```
- John plays golf
- golf plays John
-```
-To explain the contrast, we introduce the functions
-```
- human : Dom ;
- game : Dom ;
- play : V2 human game ;
- John : NP human ;
- Golf : NP game ;
-```
-Both sentences still pass the context-free parser,
-returning trees with lots of metavariables of type ``Dom``:
-```
- PredV1 ?0 John (ComplV2 ?1 ?2 play Golf)
- PredV1 ?0 Golf (ComplV2 ?1 ?2 play John)
-```
-But only the former sentence passes the type checker, which moreover
-infers the domain arguments:
-```
- PredV1 human John (ComplV2 human game play Golf)
-```
-To try this out in GF, use ``pt = put_term`` with the **tree transformation**
-that solves the metavariables by type checking:
-```
- > p -tr "John plays golf" | pt -transform=solve
- > p -tr "golf plays John" | pt -transform=solve
-```
-In the latter case, no solutions are found.
-
-A known problem with selectional restrictions is that they can be more
-or less liberal. For instance,
-```
- John loves Mary
- John loves golf
-```
-should both make sense, even though ``Mary`` and ``golf``
-are of different types. A natural solution in this case is to
-formalize ``love`` as a **polymorphic** verb, which takes
-a human as its first argument but an object of any type as its second
-argument:
-```
- fun love : (A : Dom) -> V2 human A ;
- lin love _ = ss "loves" ;
-```
-In other words, it is possible for a human to love anything.
-
-A problem related to polymorphism is **subtyping**: what
-is meaningful for a ``human`` is also meaningful for
-a ``man`` and a ``woman``, but not the other way round.
-One solution to this is **coercions**: functions that
-"lift" objects from subtypes to supertypes.
-
-
-==Case study: selectional restrictions and statistical language models TODO==
-
-
==Proof objects==
Perhaps the most well-known idea in constructive type theory is
@@ -2590,7 +3071,22 @@ by using the ``Less`` predicate:
cat Span ;
fun span : (m,n : Nat) -> Less m n -> Span ;
```
-A possible practical application of this idea is **proof-carrying documents**:
+
+**Exercise**. Write an abstract and concrete syntax with the
+concepts of this section, and experiment with it in GF.
+
+
+**Exercise**. Define the notions of "even" and "odd" in terms
+of proof objects. **Hint**. You need one function for proving
+that 0 is even, and two other functions for propagating the
+properties.
+
+
+
+
+===Proof-carrying documents===
+
+Another possible application of proof objects is **proof-carrying documents**:
to be semantically well-formed, the abstract syntax of a document must contain a proof
of some property, although the proof is not shown in the concrete document.
Think, for instance, of small documents describing flight connections:
@@ -2607,9 +3103,12 @@ The well-formedness of this text is partly expressible by dependent typing:
LH3043 : Flight Gothenburg Frankfurt ;
OK0537 : Flight Frankfurt Prague ;
```
-This rules out texts saying //take OK0537 from Gothenburg to Prague//. However, there is a
-further condition saying that it must be possible to change from LH3043 to OK0537 in Frankfurt.
-This can be modelled as a proof object of a suitable type, which is required by the constructor
+This rules out texts saying //take OK0537 from Gothenburg to Prague//.
+However, there is a
+further condition saying that it must be possible to
+change from LH3043 to OK0537 in Frankfurt.
+This can be modelled as a proof object of a suitable type,
+which is required by the constructor
that connects flights.
```
cat
@@ -2621,6 +3120,49 @@ that connects flights.
```
+==Restricted polymorphism==
+
+In the first version of the smart house grammar ``Smart``,
+all Actions were either of
+- **monomorphic**: defined for one Kind
+- **polymorphic**: defined for all Kinds
+
+
+To make this scale up for new Kinds, we can refine this to
+*restricted polymorphism**: defined for Kinds of a certain **class**
+
+
+The notion of class can be expressed in abstract syntax
+by using the Curry-Howard isomorphism as follows:
+- a class is a **predicate** of Kinds - a type depending of Kinds
+- a Kind is in a xlass if there is of proof object of this type
+
+
+Here is an example with switching and dimming.
+```
+cat
+ Switchable Kind ;
+ Dimmable Kind ;
+fun
+ switchable_light : Switchable light ;
+ switchable_fan : Switchable fan ;
+ dimmable_light : Dimmable light ;
+
+ switchOn : (k : Kind) -> Switchable k -> Action k ;
+ dim : (k : Kind) -> Dimmable k -> Action k ;
+```
+One advantage of this formalization is that classes for new
+actions can be added incrementally.
+
+**Exercise**. Write a new version of the ``Smart`` grammar with
+classes, and test it in GF.
+
+**Exercise**. Add some actions, kinds, and classes to the grammar.
+Try to port the grammar for a new language. You will probably find
+out that restricted polymorphism works differently in different languages.
+For instance, in Finnish not only doors but also TVs and radios
+can be "opened", which means switching them on.
+
==Variable bindings==
@@ -2661,8 +3203,6 @@ which corresponds to the ordinary notation
```
(All x)(x = x).
```
-
-
An abstract syntax where trees have functions as arguments, as in
the two examples above, has turned out to be precisely the right
thing for the semantics and computer implementation of
@@ -2735,14 +3275,12 @@ Thus we can compute the linearization of the formula,
```
All (\x -> Eq x x) --> {s = "[( All x ) ( x = x )]"}.
```
-
How did we get the //linearization// of the variable ``x``
into the string ``"x"``? GF grammars have no rules for
this: it is just hard-wired in GF that variable symbols are
linearized into the same strings that represent them in
the print-out of the abstract syntax.
-
To be able to //parse// variable symbols, however, GF needs to know what
to look for (instead of e.g. trying to parse //any//
string as a variable). What strings are parsed as variable symbols
@@ -2896,27 +3434,7 @@ which is equivalent to the two judgements
```
-==Case study: representing anaphoric reference TODO==
-
-
-=Transfer modules TODO=
-
-Transfer means noncompositional tree-transforming operations.
-The command ``apply_transfer = at`` is typically used in a pipe:
-```
- > p "John walks and John runs" | apply_transfer aggregate | l
- John walks and runs
-```
-See the
-[sources ../../transfer/examples/aggregation] of this example.
-
-See the
-[transfer language documentation ../transfer.html]
-for more information.
-
-
-=Practical issues TODO=
-
+=Practical issues=
==Lexers and unlexers==
@@ -2951,13 +3469,6 @@ Given by ``help -lexer``, ``help -unlexer``:
```
-==Efficiency of grammars==
-
-Issues:
-
-- the choice of datastructures in ``lincat``s
-- the value of the ``optimize`` flag
-- parsing efficiency: ``-fcfg`` vs. others
==Speech input and output==
@@ -2980,6 +3491,7 @@ Both Flite and ATK are freely available through the links
above, but they are not distributed together with GF.
+
==Multilingual syntax editor==
The
@@ -2994,19 +3506,14 @@ The grammars of the snapshot are from the
[Letter grammar package http://www.cs.chalmers.se/~aarne/GF/examples/letter].
-
-==Interactive Development Environment (IDE)==
-
-Forthcoming.
-
-
==Communicating with GF==
Other processes can communicate with the GF command interpreter,
and also with the GF syntax editor. Useful flags when invoking GF are
- ``-batch`` suppresses the promps and structures the communication with XML tags.
- ``-s`` suppresses non-output non-error messages and XML tags.
--- ``-nocpu`` suppresses CPU time indication.
+- ``-nocpu`` suppresses CPU time indication.
+
Thus the most silent way to invoke GF is
```
@@ -3019,7 +3526,6 @@ Thus the most silent way to invoke GF is
GF grammars can be used as parts of programs written in the
following languages. The links give more documentation.
-
- [Java http://www.cs.chalmers.se/~bringert/gf/gf-java.html]
- [Haskell http://www.cs.chalmers.se/~aarne/GF/src/GF/Embed/EmbedAPI.hs]
- [Prolog http://www.cs.chalmers.se/~peb/software.html]
@@ -3031,39 +3537,6 @@ A summary is given in the following chart of GF grammar compiler phases:
[../gf-compiler.png]
-=Larger case studies TODO=
-==Interfacing formal and natural languages==
-
-[Formal and Informal Software Specifications http://www.cs.chalmers.se/~krijo/thesis/thesisA4.pdf],
-PhD Thesis by
-[Kristofer Johannisson http://www.cs.chalmers.se/~krijo], is an extensive example of this.
-The system is based on a multilingual grammar relating the formal language OCL with
-English and German.
-
-A simpler example will be explained here.
-
-
-==A multimodal dialogue system==
-
-See TALK project deliverables, [TALK homepage http://www.talk-project.org]
-
-
-
-
-% Appendices
-
-=Appendix A: The GF Command Help=
-
-%!include: ../gf-help.txt
-
-
-=Appendix B: GF Quick Reference=
-
-%!include: ../gf-reference.txt
-
-
-=Appendix C: Resource Grammar Synopsis=
-
-%!include: ../resource-synopsis.txt
+=Further reading=
diff --git a/doc/tutorial/resource-food/FoodEng.gf b/doc/tutorial/resource-food/FoodEng.gf
new file mode 100644
index 000000000..0fdf8235c
--- /dev/null
+++ b/doc/tutorial/resource-food/FoodEng.gf
@@ -0,0 +1,9 @@
+--# -path=.:present:prelude
+
+concrete FoodEng of Food = FoodI - [Pizza] with
+ (Syntax = SyntaxEng),
+ (LexFood = LexFoodEng) **
+ open SyntaxEng, ParadigmsEng in {
+
+ lin Pizza = mkCN (mkA "Italian") (mkN "pie") ;
+}
diff --git a/doc/tutorial/resource-food/FoodFre.gf b/doc/tutorial/resource-food/FoodFre.gf
index fe9e22a40..60b8f0dc2 100644
--- a/doc/tutorial/resource-food/FoodFre.gf
+++ b/doc/tutorial/resource-food/FoodFre.gf
@@ -10,9 +10,9 @@ concrete FoodFre of Food = open SyntaxFre,ParadigmsFre in {
lin
Is item quality = mkUtt (mkCl item quality) ;
- This kind = SyntaxFre.mkNP (mkDet this_Quant) kind ;
- That kind = SyntaxFre.mkNP (mkDet that_Quant) kind ;
- All kind = SyntaxFre.mkNP all_Predet (SyntaxFre.mkNP defPlDet kind) ;
+ This kind = mkNP (mkDet this_Quant) kind ;
+ That kind = mkNP (mkDet that_Quant) kind ;
+ All kind = mkNP all_Predet (mkNP defPlDet kind) ;
QKind quality kind = mkCN quality kind ;
Wine = mkCN (mkN "vin") ;
Beer = mkCN (mkN "bière") ;
diff --git a/doc/tutorial/smarthouse/Smart.gf b/doc/tutorial/smarthouse/Smart.gf
new file mode 100644
index 000000000..f23082b47
--- /dev/null
+++ b/doc/tutorial/smarthouse/Smart.gf
@@ -0,0 +1,17 @@
+abstract Smart = {
+
+flags startcat = Command ;
+
+cat
+ Command ;
+ Kind ;
+ Action Kind ;
+ Device Kind ;
+fun
+ CAction : (k : Kind) -> Action k -> Device k -> Command ;
+ DKindOne : (k : Kind) -> Device k ;
+ light, fan : Kind ;
+ switchOn, switchOff : (k : Kind) -> Action k ;
+ dim : Action light ;
+}
+
diff --git a/doc/tutorial/smarthouse/SmartEng.gf b/doc/tutorial/smarthouse/SmartEng.gf
new file mode 100644
index 000000000..0f59cd1e0
--- /dev/null
+++ b/doc/tutorial/smarthouse/SmartEng.gf
@@ -0,0 +1,19 @@
+--# -path=.:prelude
+
+concrete SmartEng of Smart = open Prelude in {
+
+-- part of grammar Toy1 from the Regulus book
+
+lincat
+ Command, Kind, Action, Device = SS ;
+lin
+ CAction _ act dev = ss (act.s ++ dev.s) ;
+ DKindOne k = ss ("the" ++ k.s) ;
+
+ light = ss "light" ;
+ fan = ss "fan" ;
+ switchOn _ = ss ["switch on"] ;
+ switchOff _ = ss ["switch off"] ;
+ dim = ss "dim" ;
+}
+
diff --git a/lib/resource-1.0/abstract/Cat.gf b/lib/resource-1.0/abstract/Cat.gf
index 7e9ff2804..7a74183b7 100644
--- a/lib/resource-1.0/abstract/Cat.gf
+++ b/lib/resource-1.0/abstract/Cat.gf
@@ -72,16 +72,16 @@ abstract Cat = Common ** {
-- ``` Predet (QuantSg | QuantPl Num) Ord
-- as defined in [Noun Noun.html].
- CN ; -- common noun (without determiner) e.g. "red house"
- NP ; -- noun phrase (subject or object) e.g. "the red house"
- Pron ; -- personal pronoun e.g. "she"
- Det ; -- determiner phrase e.g. "those seven"
- Predet; -- predeterminer (prefixed Quant) e.g. "all"
- QuantSg;-- quantifier ('nucleus' of sing. Det) e.g. "every"
- QuantPl;-- quantifier ('nucleus' of plur. Det) e.g. "many"
- Quant ; -- quantifier with both sg and pl e.g. "this/these"
- Num ; -- cardinal number (used with QuantPl) e.g. "seven"
- Ord ; -- ordinal number (used in Det) e.g. "seventh"
+ CN ; -- common noun (without determiner) e.g. "red house"
+ NP ; -- noun phrase (subject or object) e.g. "the red house"
+ Pron ; -- personal pronoun e.g. "she"
+ Det ; -- determiner phrase e.g. "those seven"
+ Predet ; -- predeterminer (prefixed Quant) e.g. "all"
+ QuantSg ;-- quantifier ('nucleus' of sing. Det) e.g. "every"
+ QuantPl ;-- quantifier ('nucleus' of plur. Det) e.g. "many"
+ Quant ; -- quantifier with both sg and pl e.g. "this/these"
+ Num ; -- cardinal number (used with QuantPl) e.g. "seven"
+ Ord ; -- ordinal number (used in Det) e.g. "seventh"
--2 Numerals
diff --git a/lib/resource-1.0/doc/synopsis.html b/lib/resource-1.0/doc/synopsis.html
index a62c4796a..e6adcdb97 100644
--- a/lib/resource-1.0/doc/synopsis.html
+++ b/lib/resource-1.0/doc/synopsis.html
@@ -40,6 +40,11 @@ to the relevant source files, which give more information. Some of the files hav
not yet been prepared so that the machine generated documentation has the right format.
+Since the character encoding is UTF-8 for Russian and Latin-1 for other languages, you
+may have to change the encoding preference of your browser when reading different
+parts of the document.
+
+
The second-last chapter gives instructions on how to "browse" the library by
loading the grammars into the gf command editor.
@@ -233,6 +238,11 @@ Source 2: http://www.cs.chalmers.se/~aarne/GF
| "those seven" |
+Predet |
+predeterminer (prefixed Quant) |
+"all" |
+
+
Quant |
quantifier with both sg and pl |
"this/these" |