Produced by gfdoc - a rudimentary GF document generator. (c) Aarne Ranta (aarne@cs.chalmers.se) 2002 under GNU GPL.

Implementation of MOLTO Phrasebook

The functor for (mostly) common structures

  incomplete concrete SentencesI of Sentences = Numeral ** 
    open
      Syntax,
      Lexicon,
      Symbolic,  -- for names as strings
      Prelude
    in {
    lincat
      Phrase = Text ;
      Sentence = S ;
      Question = QS ;
      Proposition = Cl ;
      Item = NP ;
      Kind = CN ;
      MassKind = CN ;
      Quality = AP ;
      Property = A ;
      Object = NP ;
      PrimObject = NP ;
      Place = NPPlace ; -- {name : NP ; at : Adv ; to : Adv} ;
      PlaceKind = CNPlace ; -- {name : CN ; at : Prep ; to : Prep} ;
      Currency = CN ;
      Price = NP ;
      Action = Cl ;
      Person = NPPerson ; -- {name : NP ; isPron : Bool ; poss : Quant} ;
      Nationality = NPNationality ; -- {lang : NP ; country : NP ; prop : A} ; 
      Language = NP ;
      Citizenship = A ;
      Country = NP ;
      Day = NPDay ; -- {name : NP ; point : Adv ; habitual : Adv} ;
      Date = Adv ;
      Name = NP ;
      Number = Card ;
      ByTransport = Adv ;
      Transport = {name : CN ; by : Adv} ;
      Superlative = Det ;
    lin
      PSentence s = mkText s | lin Text (mkUtt s) ;  -- optional '.'
      PQuestion s = mkText s | lin Text (mkUtt s) ;  -- optional '?'
  
      PObject x = mkPhrase (mkUtt x) ;
      PKind x = mkPhrase (mkUtt x) ;
      PMassKind x = mkPhrase (mkUtt x) ;
      PQuality x = mkPhrase (mkUtt x) ;
      PNumber x = mkPhrase (mkUtt x) ;
      PPlace x = mkPhrase (mkUtt x.name) ;
      PPlaceKind x = mkPhrase (mkUtt x.name) ;
      PCurrency x = mkPhrase (mkUtt x) ;
      PPrice x = mkPhrase (mkUtt x) ;
      PLanguage x = mkPhrase (mkUtt x) ;
      PCountry x = mkPhrase (mkUtt x) ;
      PCitizenship x = mkPhrase (mkUtt (mkAP x)) ;
      PDay d = mkPhrase (mkUtt d.name) ;
      PTransport t = mkPhrase (mkUtt t.name) ;
      PByTransport t = mkPhrase (mkUtt t) ;
  
      PYes = mkPhrase yes_Utt ;
      PNo = mkPhrase no_Utt ;
      PYesToNo = mkPhrase yes_Utt ;
  
      Is = mkCl ;
  
      SProp = mkS ;
      SPropNot = mkS negativePol ;
      QProp p = mkQS (mkQCl p) ;
  
      WherePlace place = mkQS (mkQCl where_IAdv place.name) ;
      WherePerson person = mkQS (mkQCl where_IAdv person.name) ;
  
      PropAction a = a ;
  
      AmountCurrency num curr = mkNP num curr ;
  
      ObjItem i = i ;
      ObjNumber n k = mkNP n k ;
      ObjIndef k = mkNP a_Quant k ;
      ObjPlural k = mkNP aPl_Det k ;
      ObjMass k = mkNP k ;
      ObjAndObj = mkNP and_Conj ;
      OneObj o = o ; 
  
      This kind = mkNP this_Quant kind ;
      That kind = mkNP that_Quant kind ;
      These kind = mkNP this_Quant plNum kind ;
      Those kind = mkNP that_Quant plNum kind ;
      The kind = mkNP the_Quant kind ;
      Thes kind = mkNP the_Quant plNum kind ;
      ThisMass kind = mkNP this_Quant kind ;
      ThatMass kind = mkNP that_Quant kind ;
      TheMass kind = mkNP the_Quant kind ;
  
      SuchKind quality kind = mkCN quality kind ;
      SuchMassKind quality kind = mkCN quality kind ;
      Very property = mkAP very_AdA (mkAP property) ;
      Too property = mkAP too_AdA (mkAP property) ;
      PropQuality property = mkAP property ;
  
      ThePlace kind = let dd = if_then_else Det kind.isPl thePl_Det theSg_Det 
                       in placeNP dd kind ;
      APlace kind = let dd = if_then_else Det kind.isPl thePl_Det theSg_Det 
                       in placeNP dd kind ;
  
      IMale, IFemale = mkPerson i_Pron ;
      YouFamMale, YouFamFemale = mkPerson youSg_Pron ;
      YouPolMale, YouPolFemale = mkPerson youPol_Pron ;
  
      LangNat n = n.lang ;
      CitiNat n = n.prop ;
      CountryNat n = n.country ;
      PropCit c = c ;
  
      OnDay d = d.point ;
      Today = today_Adv ;
  
      PersonName n = 
        {name = n ; isPron = False ; poss = mkQuant he_Pron} ; -- poss not used
      NameNN = symb "NN" ;
  
      NNumeral n = mkCard <lin Numeral n : Numeral>  ;
  
      SHave   p obj = mkS (mkCl p.name have_V2 obj) ;
      SHaveNo p k = mkS negativePol (mkCl p.name have_V2 (mkNP aPl_Det k)) ;
      SHaveNoMass p m = mkS negativePol (mkCl p.name have_V2 (mkNP m)) ;
      QDoHave p obj = mkQS (mkQCl (mkCl p.name have_V2 obj)) ;
  
      AHaveCurr p curr = mkCl p.name have_V2 (mkNP aPl_Det curr) ;
      ACitizen p n = mkCl p.name n ;
      ABePlace p place = mkCl p.name place.at ;
      ByTransp t = t.by ;
  
  oper 
These operations are used internally in Sentences.
    mkPhrase : Utt -> Text = \u -> lin Text u ; -- no punctuation
  
    mkPerson : Pron -> {name : NP ; isPron : Bool ; poss : Quant} = \p -> 
      {name = mkNP p ; isPron = True ; poss = mkQuant p} ;
These are used in Words for each language.
    NPNationality : Type = {lang : NP ; country : NP ; prop : A} ;
  
    mkNPNationality : NP -> NP -> A -> NPNationality = \la,co,pro ->
          {lang = la ; 
           country = co ;
           prop = pro
          } ;
  
    NPDay : Type = {name : NP ; point : Adv ; habitual : Adv} ;
  
    mkNPDay : NP -> Adv -> Adv -> NPDay = \d,p,h ->
        {name = d ; 
         point = p ;
         habitual = h
        } ;
  
    NPPlace : Type = {name : NP ; at : Adv ; to : Adv} ;
    CNPlace : Type = {name : CN ; at : Prep ; to : Prep; isPl : Bool} ;
  
    mkCNPlace : CN -> Prep -> Prep -> CNPlace = \p,i,t -> {
      name = p ;
      at = i ;
      to = t ;
      isPl = False
      } ;
  
   mkCNPlacePl : CN -> Prep -> Prep -> CNPlace = \p,i,t -> {
      name = p ;
      at = i ;
      to = t ;
      isPl = True
      } ;
  
    placeNP : Det -> CNPlace -> NPPlace = \det,kind ->
      let name : NP = mkNP det kind.name in {
        name = name ;
        at = mkAdv kind.at name ;
        to = mkAdv kind.to name
      } ;
  
    NPPerson : Type = {name : NP ; isPron : Bool ; poss : Quant} ;
  
    relativePerson : GNumber -> CN -> (Num -> NP -> CN -> NP) -> NPPerson -> NPPerson = 
      \n,x,f,p -> 
        let num = if_then_else Num n plNum sgNum in {
        name = case p.isPron of {
          True => mkNP p.poss num x ;
          _    => f num p.name x
          } ;
        isPron = False ;
        poss = mkQuant he_Pron -- not used because not pron
        } ;
  
    GNumber : PType = Bool ;
    sing = False ; plur = True ;
for languages without GenNP, use the wife of p
    mkRelative : Bool -> CN -> NPPerson -> NPPerson = \n,x,p ->
      relativePerson n x 
        (\a,b,c -> mkNP (mkNP the_Quant a c) (Syntax.mkAdv possess_Prep b)) p ;
for languages with GenNP, use p's wife relativePerson n x (\a,b,c -> mkNP (GenNP b) a c) p ;
  }

Implementations of Words, with English as example

  concrete WordsEng of Words = SentencesEng ** 
      open 
        SyntaxEng, 
        ParadigmsEng, 
        (L = LexiconEng), 
        (P = ParadigmsEng), 
        IrregEng, 
        ExtraEng, 
        Prelude in {
    lin
Kinds; many of them are in the resource lexicon, others can be built by mkN.
      Apple = mkCN L.apple_N ;
      Beer = mkCN L.beer_N ;
      Bread = mkCN L.bread_N ;
      Cheese = mkCN (mkN "cheese") ;
      Chicken = mkCN (mkN "chicken") ;
      Coffee = mkCN (mkN "coffee") ;
      Fish = mkCN L.fish_N ;
      Meat = mkCN (mkN "meat") ;
      Milk = mkCN L.milk_N ;
      Pizza = mkCN (mkN "pizza") ;
      Salt = mkCN L.salt_N ;
      Tea = mkCN (mkN "tea") ;
      Water = mkCN L.water_N ;
      Wine = mkCN L.wine_N ;
Properties; many of them are in the resource lexicon, others can be built by mkA.
      Bad = L.bad_A ;
      Boring = mkA "boring" ;
      Cheap = mkA "cheap" ;
      Cold = L.cold_A ;
      Delicious = mkA "delicious" ;
      Expensive = mkA "expensive" ;
      Fresh = mkA "fresh" ;
      Good = L.good_A ;
      Suspect = mkA "suspect" ;
      Warm = L.warm_A ;
Places require different prepositions to express location; in some languages also the directional preposition varies, but in English we use to, as defined by mkPlace.
      Airport = mkPlace "airport" "at" ;
      AmusementPark = mkCompoundPlace "amusement" "park" "at" ;
      Bank = mkPlace "bank" "at" ;
      Bar = mkPlace "bar" "in" ;
      Cafeteria = mkPlace "canteen" "in" ;
      Center = mkPlace "center" "in" ;
      Cinema = mkPlace "cinema" "at" ;
      Church = mkPlace "church" "in" ;
      Disco = mkPlace "disco" "at" ;
      Hospital = mkPlace "hospital" "in" ;
      Hotel = mkPlace "hotel" "in" ;
      Museum = mkPlace "museum" "at" ;
      Park = mkPlace "park" "in" ;
      Parking = mkCompoundPlace "car" "park" "in" ; 
      Pharmacy = mkPlace "pharmacy" "at" ;
      PostOffice = mkCompoundPlace "post" "office" "at" ;
      Pub = mkPlace "pub" "at" ;
      Restaurant = mkPlace "restaurant" "in" ;
      School = mkPlace "school" "at" ;
      Shop = mkPlace "shop" "at" ;
      Station = mkPlace "station" "at" ;
      Supermarket = mkPlace "supermarket" "at" ; 
      Theatre = mkPlace "theatre" "at" ;
      Toilet = mkPlace "toilet" "in" ;
      University = mkPlace "university" "at" ;
      Zoo = mkPlace "zoo" "at" ;
  
      CitRestaurant cit = mkCNPlace (mkCN cit (mkN "restaurant")) in_Prep to_Prep ;
Currencies; crown is ambiguous between Danish and Swedish crowns.
      DanishCrown = mkCN (mkA "Danish") (mkN "crown") | mkCN (mkN "crown") ;
      Dollar = mkCN (mkN "dollar") ;
      Euro = mkCN (mkN "euro" "euros") ; -- to prevent euroes
      Lei = mkCN (mkN "leu" "lei") ;
      Leva = mkCN (mkN "lev") ;
      NorwegianCrown = mkCN (mkA "Norwegian") (mkN "crown") | mkCN (mkN "crown") ;
      Pound = mkCN (mkN "pound") ;
      Rouble = mkCN (mkN "rouble") ;
      SwedishCrown = mkCN (mkA "Swedish") (mkN "crown") | mkCN (mkN "crown") ;
      Zloty = mkCN (mkN "zloty" "zloty") ;
Nationalities
      Belgian = mkA "Belgian" ;
      Belgium = mkNP (mkPN "Belgium") ;
      Bulgarian = mkNat "Bulgarian" "Bulgaria" ;
      Catalan = mkNPNationality (mkNP (mkPN "Catalan")) (mkNP (mkPN "Catalonia")) (mkA "Catalonian") ;
      Danish = mkNat "Danish" "Denmark" ;
      Dutch =  mkNPNationality (mkNP (mkPN "Dutch")) (mkNP the_Quant (mkN "Netherlands")) (mkA "Dutch") ;
      English = mkNat "English" "England" ;
      Finnish = mkNat "Finnish" "Finland" ;
      Flemish = mkNP (mkPN "Flemish") ;
      French = mkNat "French" "France" ; 
      German = mkNat "German" "Germany" ;
      Italian = mkNat "Italian" "Italy" ;
      Norwegian = mkNat "Norwegian" "Norway" ;
      Polish = mkNat "Polish" "Poland" ;
      Romanian = mkNat "Romanian" "Romania" ;
      Russian = mkNat "Russian" "Russia" ;
      Spanish = mkNat "Spanish" "Spain" ;
      Swedish = mkNat "Swedish" "Sweden" ;
Means of transportation
     Bike = mkTransport L.bike_N ;
     Bus = mkTransport (mkN "bus") ;
     Car = mkTransport L.car_N ;
     Ferry = mkTransport (mkN "ferry") ;
     Plane = mkTransport L.airplane_N ;
     Subway = mkTransport (mkN "subway") ;
     Taxi = mkTransport (mkN "taxi") ;
     Train = mkTransport (mkN "train") ;
     Tram = mkTransport (mkN "tram") ;
  
     ByFoot = P.mkAdv "by foot" ;
Actions: the predication patterns are very often language-dependent.
      AHasAge p num = mkCl p.name (mkNP (mkNP num L.year_N) (ParadigmsEng.mkAdv "old"));
      AHasChildren p num = mkCl p.name have_V2 (mkNP num L.child_N) ;
      AHasRoom p num = mkCl p.name have_V2 
        (mkNP (mkNP a_Det (mkN "room")) (SyntaxEng.mkAdv for_Prep (mkNP num (mkN "person")))) ;
      AHasTable p num = mkCl p.name have_V2 
        (mkNP (mkNP a_Det (mkN "table")) (SyntaxEng.mkAdv for_Prep (mkNP num (mkN "person")))) ;
      AHasName p name = mkCl (nameOf p) name ;
      AHungry p = mkCl p.name (mkA "hungry") ;
      AIll p = mkCl p.name (mkA "ill") ;
      AKnow p = mkCl p.name IrregEng.know_V ;
      ALike p item = mkCl p.name (mkV2 (mkV "like")) item ;
      ALive p co = mkCl p.name (mkVP (mkVP (mkV "live")) (SyntaxEng.mkAdv in_Prep co)) ;
      ALove p q = mkCl p.name (mkV2 (mkV "love")) q.name ;
      AMarried p = mkCl p.name (mkA "married") ;
      AReady p = mkCl p.name (mkA "ready") ;
      AScared p = mkCl p.name (mkA "scared") ;
      ASpeak p lang = mkCl p.name  (mkV2 IrregEng.speak_V) lang ;
      AThirsty p = mkCl p.name (mkA "thirsty") ;
      ATired p = mkCl p.name (mkA "tired") ;
      AUnderstand p = mkCl p.name IrregEng.understand_V ;
      AWant p obj = mkCl p.name (mkV2 (mkV "want")) obj ;
      AWantGo p place = mkCl p.name want_VV (mkVP (mkVP IrregEng.go_V) place.to) ;
miscellaneous
      QWhatName p = mkQS (mkQCl whatSg_IP (mkVP (nameOf p))) ;
      QWhatAge p = mkQS (mkQCl (ICompAP (mkAP L.old_A)) p.name) ;
      HowMuchCost item = mkQS (mkQCl how8much_IAdv (mkCl item IrregEng.cost_V)) ; 
      ItCost item price = mkCl item (mkV2 IrregEng.cost_V) price ;
  
      PropOpen p = mkCl p.name open_Adv ;
      PropClosed p = mkCl p.name closed_Adv ;
      PropOpenDate p d = mkCl p.name (mkVP (mkVP open_Adv) d) ; 
      PropClosedDate p d = mkCl p.name (mkVP (mkVP closed_Adv) d) ; 
      PropOpenDay p d = mkCl p.name (mkVP (mkVP open_Adv) d.habitual) ; 
      PropClosedDay p d = mkCl p.name (mkVP (mkVP closed_Adv) d.habitual) ; 
Building phrases from strings is complicated: the solution is to use mkText : Text -> Text -> Text ;
      PSeeYouDate d = mkText (lin Text (ss ("see you"))) (mkPhrase (mkUtt d)) ;
      PSeeYouPlace p = mkText (lin Text (ss ("see you"))) (mkPhrase (mkUtt p.at)) ;
      PSeeYouPlaceDate p d = 
        mkText (lin Text (ss ("see you"))) 
          (mkText (mkPhrase (mkUtt p.at)) (mkPhrase (mkUtt d))) ;
Relations are expressed as my wife or my son's wife, as defined by xOf below. Languages without productive genitives must use an equivalent of the wife of my son for non-pronouns.
      Wife = xOf sing (mkN "wife") ;
      Husband = xOf sing (mkN "husband") ;
      Son = xOf sing (mkN "son") ;
      Daughter = xOf sing (mkN "daughter") ;
      Children = xOf plur L.child_N ;
week days
      Monday = mkDay "Monday" ;
      Tuesday = mkDay "Tuesday" ;
      Wednesday = mkDay "Wednesday" ;
      Thursday = mkDay "Thursday" ;
      Friday = mkDay "Friday" ;
      Saturday = mkDay "Saturday" ;
      Sunday = mkDay "Sunday" ;
  
      Tomorrow = P.mkAdv "tomorrow" ;
modifiers of places
      TheBest = mkSuperl L.good_A ;
      TheClosest = mkSuperl L.near_A ; 
      TheCheapest = mkSuperl (mkA "cheap") ;
      TheMostExpensive = mkSuperl (mkA "expensive") ;
      TheMostPopular = mkSuperl (mkA "popular") ;
      TheWorst = mkSuperl L.bad_A ;
  
      SuperlPlace sup p = placeNP sup p ;
transports
      HowFar place = mkQS (mkQCl far_IAdv place.name) ;
      HowFarFrom x y = mkQS (mkQCl far_IAdv (mkNP y.name (SyntaxEng.mkAdv from_Prep x.name))) ;
      HowFarFromBy x y t = 
        mkQS (mkQCl far_IAdv (mkNP (mkNP y.name (SyntaxEng.mkAdv from_Prep x.name)) t)) ;
      HowFarBy y t = mkQS (mkQCl far_IAdv (mkNP y.name t)) ;
  
      WhichTranspPlace trans place = 
        mkQS (mkQCl (mkIP which_IDet trans.name) (mkVP (mkVP L.go_V) place.to)) ;
  
      IsTranspPlace trans place =
        mkQS (mkQCl (mkCl (mkCN trans.name place.to))) ;
auxiliaries
    oper
  
      mkNat : Str -> Str -> NPNationality = \nat,co -> 
        mkNPNationality (mkNP (mkPN nat)) (mkNP (mkPN co)) (mkA nat) ;
  
      mkDay : Str -> {name : NP ; point : Adv ; habitual : Adv} = \d ->
        let day = mkNP (mkPN d) in 
        mkNPDay day (SyntaxEng.mkAdv on_Prep day) 
          (SyntaxEng.mkAdv on_Prep (mkNP a_Quant plNum (mkCN (mkN d)))) ;
  
      mkCompoundPlace : Str -> Str -> Str -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \comp, p, i ->
       mkCNPlace (mkCN (P.mkN comp (mkN p))) (P.mkPrep i) to_Prep ;
  
      mkPlace : Str -> Str -> {name : CN ; at : Prep ; to : Prep; isPl : Bool} = \p,i -> 
        mkCNPlace (mkCN (mkN p)) (P.mkPrep i) to_Prep ;
  
      open_Adv = P.mkAdv "open" ;
      closed_Adv = P.mkAdv "closed" ;
  
      xOf : GNumber -> N -> NPPerson -> NPPerson = \n,x,p -> 
        relativePerson n (mkCN x) (\a,b,c -> mkNP (GenNP b) a c) p ;
  
      nameOf : NPPerson -> NP = \p -> (xOf sing (mkN "name") p).name ;
  
      mkTransport : N -> {name : CN ; by : Adv} = \n -> {
        name = mkCN n ; 
        by = SyntaxEng.mkAdv by8means_Prep (mkNP n)
        } ;
  
      mkSuperl : A -> Det = \a -> SyntaxEng.mkDet the_Art (SyntaxEng.mkOrd a) ;
  
     far_IAdv = ExtraEng.IAdvAdv (ss "far") ;
  
  }