packages feed

gf-3.4: lib/src/bulgarian/ResBul.gf

--# -path=.:../abstract:../common:../../prelude

--1 Bulgarian auxiliary operations.

-- This module contains operations that are needed to make the
-- resource syntax work. To define everything that is needed to
-- implement $Test$, it moreover contains regular lexical
-- patterns needed for $Lex$.

resource ResBul = ParamX ** open Prelude, Predef in {

  flags
    coding=cp1251 ;  optimize=all ;


-- Some parameters, such as $Number$, are inherited from $ParamX$.

--2 For $Noun$

-- This is the worst-case $Case$ needed for pronouns.

  param
    Role = RSubj | RObj Case | RVoc ;
    Case = Acc | Dat;

    NForm = 
        NF Number Species
      | NFSgDefNom
      | NFPlCount
      | NFVocative
      ;
      
    NNumber =
        NNum Number
      | NCountable
      ;

    GenNum = GSg Gender | GPl ;

-- Agreement of $NP$ is a record. We'll add $Gender$ later.

  oper
    Agr = {gn : GenNum ; p : Person} ;

  param
    Gender = Masc | Fem | Neut ;
    
    Species = Indef | Def ;
 
-- The plural never makes a gender distinction.

--2 For $Verb$

    Aspect = Imperf | Perf ;

    VForm = 
       VPres      Number Person
     | VAorist    Number Person
     | VImperfect Number Person
     | VPerfect    AForm
     | VPluPerfect AForm
     | VPassive    AForm
     | VPresPart   AForm
     | VImperative Number
     | VNoun NForm
     | VGerund
     ;
     
    VType =
       VNormal
     | VMedial  Case
     | VPhrasal Case
     ;

    VVType = VVInf | VVGerund ;

-- The order of sentence is needed already in $VP$.

    Order = Main | Inv | Quest ;

--2 For $Adjective$

    AForm = 
       ASg Gender Species
     | ASgMascDefNom
     | APl Species
     ;

--2 For $Numeral$

    Animacy = Human | NonHuman ;

    AGender =
       AMasc Animacy
     | AFem
     | ANeut
     ;
    
    CardForm =
       CFMasc Species Animacy
     | CFMascDefNom   Animacy
     | CFFem  Species
     | CFNeut Species
     ;

    CardOrd = NCard CardForm | NOrd AForm ;
    NumF  = Formal | Informal ;
    DForm = unit | teen NumF | ten NumF | hundred ;

--2 Transformations between parameter types

  oper
    agrP3 : GenNum -> Agr = \gn -> 
      {gn = gn; p = P3} ;

    conjGenNum : GenNum -> GenNum -> GenNum = \a,b ->
      case <a,b> of {
        <GSg _,GSg g> => GSg g ;
        _             => GPl
    } ;

    conjAgr : Agr -> Agr -> Agr = \a,b -> {
      gn = conjGenNum a.gn b.gn ;
      p  = conjPerson a.p b.p
      } ;

    gennum : AGender -> Number -> GenNum = \g,n ->
      case n of {
        Sg => GSg (case g of {
                     AMasc _       => Masc ;
                     AFem          => Fem ;
                     ANeut         => Neut
                   }) ;
        Pl => GPl
        } ;

    numGenNum : GenNum -> Number = \gn -> 
      case gn of {
        GSg _  => Sg ;
        GPl    => Pl
      } ;

    numnnum : NNumber -> Number = \nn ->
      case nn of {
        NNum n     => n ;
        NCountable => Pl
      } ;

    aform : GenNum -> Species -> Role -> AForm = \gn,spec,role -> 
      case gn of {
        GSg g  => case <g,spec,role> of {
                    <Masc,Def,RSubj> => ASgMascDefNom ;
                    _                => ASg g spec
                  } ;
        GPl    => APl spec
      } ;

    dgenderSpecies : AGender -> Species -> Role -> CardForm =
      \g,spec,role -> case <g,spec> of {
                        <AMasc a,Indef> => CFMasc Indef a ;
                        <AMasc a,Def>   => case role of {
                                             RSubj => CFMascDefNom a ;
                                             _     => CFMasc Def a
                                           } ;
                        <AFem   ,Indef> => CFFem Indef ;
                        <AFem   ,Def>   => CFFem Def ;
                        <ANeut  ,Indef> => CFNeut Indef ;
                        <ANeut  ,Def>   => CFNeut Def
                      } ;

    nform2aform : NForm -> AGender -> AForm
      = \nf,g -> case nf of {
                   NF n spec  => aform (gennum g n) spec (RObj Acc) ;
                   NFSgDefNom => aform (gennum g Sg) Def RSubj ;
                   NFPlCount  => APl Indef ;
                   NFVocative => aform (gennum g Sg) Indef (RObj Acc)
                 } ;

    indefNForm : NForm -> NForm
      = \nf -> case nf of {
                 NF n spec  => NF n  Indef ;
                 NFSgDefNom => NF Sg Indef ;
                 NFPlCount  => NFPlCount ;
                 NFVocative => NFVocative
               } ;

    numNForm : NForm -> Number
      = \nf -> case nf of {
                 NF n spec  => n ;
                 NFSgDefNom => Sg ;
                 NFPlCount  => Pl ;
                 NFVocative => Sg
               } ;
      
  oper
-- For $Verb$.
    VTable = VForm => Str ;

    Verb : Type = {
      s      : Aspect => VTable ;
      vtype  : VType
    } ;

    VP : Type = {
      s     : Aspect => VTable ;
      ad    : {isEmpty : Bool; s : Str} ;          -- sentential adverb
      compl : Agr => Str ;
      vtype : VType
    } ;
    
    VPSlash = {
      s      : Aspect => VTable ;
      ad     : {isEmpty : Bool; s : Str} ;         -- sentential adverb
      compl1 : Agr => Str ;
      compl2 : Agr => Str ;
      vtype  : VType ;
      c2     : Preposition
    } ;

    predV : Verb -> VP = \verb -> {
      s     = verb.s ;
      ad    = {isEmpty=True; s=[]} ;
      compl = \\_ => [] ;
      vtype = verb.vtype ;
    } ;

    slashV : Verb -> Preposition -> VPSlash = \verb,prep -> {
      s      = verb.s ;
      ad     = {isEmpty=True; s=[]} ;
      compl1 = \\_ => [] ;
      compl2 = \\_ => [] ;
      vtype  = verb.vtype ;
      c2     = prep ;
    } ;

    insertObj : (Agr => Str) -> VP -> VP = \obj,vp -> {
      s     = vp.s ;
      ad    = vp.ad ;
      compl = \\a => vp.compl ! a ++ obj ! a ;
      vtype = vp.vtype
      } ;

    insertSlashObj1 : (Agr => Str) -> VPSlash -> VPSlash = \obj,slash -> {
      s      = slash.s ;
      ad     = slash.ad ;
      compl1 = \\a => slash.compl1 ! a ++ obj ! a ;
      compl2 = slash.compl2 ;
      vtype  = slash.vtype ;
      c2     = slash.c2
      } ;

    insertSlashObj2 : (Agr => Str) -> VPSlash -> VPSlash = \obj,slash -> {
      s      = slash.s ;
      ad     = slash.ad ;
      compl1 = slash.compl1 ;
      compl2 = \\a => slash.compl2 ! a ++ obj ! a ;
      vtype  = slash.vtype ;
      c2     = slash.c2
      } ;

    auxBe : VTable =
      table {
        VPres      Sg P1  => "ñúì" ; 
        VPres      Sg P2  => "ñè" ;
        VPres      Sg P3  => "å" ;
        VPres      Pl P1  => "ñìå" ; 
        VPres      Pl P2  => "ñòå" ;
        VPres      Pl P3  => "ñà" ;
        VAorist    Sg P1  => "áÿõ" ; 
        VAorist    Sg _   => "áåøå" ;
        VAorist    Pl P1  => "áÿõìå" ; 
        VAorist    Pl P2  => "áÿõòå" ;
        VAorist    Pl P3  => "áÿõà" ;
        VImperfect Sg P1  => "áÿõ" ; 
        VImperfect Sg _   => "áåøå" ;
        VImperfect Pl P1  => "áÿõìå" ; 
        VImperfect Pl P2  => "áÿõòå" ;
        VImperfect Pl P3  => "áÿõà" ;
        VPerfect    aform => regAdjective "áèë" ! aform ;
        VPluPerfect aform => regAdjective "áèë" ! aform ;
        VPassive    aform => regAdjective "áúäåí" ! aform ;
        VPresPart   aform => regAdjective "áúäåù" ! aform ;
        VImperative Sg    => "áúäè" ;
        VImperative Pl    => "áúäåòå" ;
        VNoun _           => "";
        VGerund           => "áèäåéêè"
      } ;

    auxWould : VTable =
      table {
        VPres      Sg P1  => "áúäà" ; 
        VPres      Sg P2  => "áúäåø" ;
        VPres      Sg P3  => "áúäå" ; 
        VPres      Pl P1  => "áúäåì" ; 
        VPres      Pl P2  => "áúäåòå" ;
        VPres      Pl P3  => "áúäàò" ;
        VAorist    Sg P1  => "áèõ" ; 
        VAorist    Sg _   => "áè" ;
        VAorist    Pl P1  => "áèõìå" ; 
        VAorist    Pl P2  => "áèõòå" ;
        VAorist    Pl P3  => "áèõà" ;
        VImperfect Sg P1  => "áúäåõ" ; 
        VImperfect Sg _   => "áúäåøå" ;
        VImperfect Pl P1  => "áúäåõìå" ; 
        VImperfect Pl P2  => "áúäåõòå" ;
        VImperfect Pl P3  => "áúäåõà" ;
        VPerfect    aform => regAdjective "áèë" ! aform ;
        VPluPerfect aform => regAdjective "áúäåë" ! aform ;
        VPassive    aform => regAdjective "áúäåí" ! aform ;
        VPresPart   aform => regAdjective "áúäåù" ! aform ;
        VImperative Sg    => "áúäè" ;
        VImperative Pl    => "áúäåòå" ;
        VNoun _           => "";
        VGerund           => "áúäåéêè"
      } ;

    verbBe    : Verb = {s=\\_=>auxBe ;    vtype=VNormal} ;
    verbWould : Verb = {s=\\_=>auxWould ; vtype=VNormal} ;

    reflClitics : Case => Str = table {Acc => "ñå"; Dat => "ñè"} ;

    personalClitics : Case => GenNum => Person => Str =
      table {
        Acc => table {
                 GSg g => table {
                            P1 => "ìå" ;
                            P2 => "òå" ;
                            P3 => case g of {
                                    Masc => "ãî" ;
                                    Fem  => "ÿ" ;
                                    Neut => "ãî"
                                  }
                          } ;
                 GPl   => table {
                            P1 => "íè" ;
                            P2 => "âè" ;
                            P3 => "ãè"
                          }
               } ;
        Dat => table {
                 GSg g => table {
                            P1 => "ìè" ;
                            P2 => "òè" ;
                            P3 => case g of {
                                    Masc => "ìó" ;
                                    Fem  => "é" ;
                                    Neut => "ìó"
                                  }
                          } ;
                 GPl   => table {
                            P1     => "íè" ;
                            P2     => "âè" ;
                            P3     => "èì"
                          }
               }
      } ;

    ia2e : Str -> Str =           -- to be used when the next syllable has vowel different from "à","ú","î" or "ó"
      \s -> case s of {
              x@(_*+_) + "ÿ" + y@(("á"|"â"|"ã"|"ä"|"æ"|"ç"|"ê"|"ë"|"ì"|"í"|"ï"|"ð"|"ñ"|"ò"|"ô"|"õ"|"ö"|"÷"|"ø"|"ù")*)
                => x+"e"+y;
              _ => s
            };

  regAdjective : Str -> AForm => Str = 
    \base -> 
       let base0 : Str
                 = case base of {
                     x+"è" => x;
                     x     => x
                   }
       in table {
            ASg Masc Indef => base  ;
            ASg Masc Def   => (base0+"èÿ") ;
            ASgMascDefNom  => (base0+"èÿò") ;
            ASg Fem  Indef => (base0+"à") ;
            ASg Fem  Def   => (base0+"aòa") ;
            ASg Neut Indef => (base0+"î") ;
            ASg Neut Def   => (base0+"îòî") ;
            APl Indef      => (ia2e base0+"è") ;
            APl Def        => (ia2e base0+"èòå")
          };
    
-- For $Sentence$.

  Clause : Type = {
    s : Tense => Anteriority => Polarity => Order => Str
  } ;

  mkClause : Str -> Agr -> VP -> Clause =
    \subj,agr,vp -> {
      s = \\t,a,p,o => 
        let
          verb  : Bool => Str
                = \\q => vpTenses vp ! t ! a ! p ! agr ! q ! Perf ;
          compl = vp.compl ! agr
        in case o of {
             Main  => subj ++ verb ! False ++ compl ;
             Inv   => verb ! False ++ compl ++ subj ;
             Quest => subj ++ verb ! True ++ compl
           }
    } ;

  vpTenses : VP -> Tense => Anteriority => Polarity => Agr => Bool => Aspect => Str =
    \verb -> \\t,a,p,agr,q0,asp =>
      let clitic = case verb.vtype of {
                     VNormal    => {s=[]; agr=agr} ;
                     VMedial c  => {s=reflClitics ! c; agr=agr} ;
                     VPhrasal c => {s=personalClitics ! c ! agr.gn ! agr.p; agr={gn=GSg Neut; p=P3}}
                   } ;

          present = verb.s ! asp ! (VPres   (numGenNum clitic.agr.gn) clitic.agr.p) ;
          presentImperf = verb.s ! Imperf ! (VPres   (numGenNum clitic.agr.gn) clitic.agr.p) ;
          aorist = verb.s ! asp ! (VAorist (numGenNum clitic.agr.gn) clitic.agr.p) ;
          perfect = verb.s ! asp ! (VPerfect (aform clitic.agr.gn Indef (RObj Acc))) ;

          auxPres   = auxBe ! VPres (numGenNum clitic.agr.gn) clitic.agr.p ;
          auxAorist = auxBe ! VAorist (numGenNum clitic.agr.gn) clitic.agr.p ;
          auxCond   = auxWould ! VAorist (numGenNum clitic.agr.gn) clitic.agr.p ;

          apc : Str -> Str = \s ->
            case <numGenNum clitic.agr.gn, clitic.agr.p> of {
              <Sg, P3> => clitic.s++auxPres++s ;
              _        => auxPres++s++clitic.s
            } ;

          li0 = case <verb.ad.isEmpty,q0> of {<False,True> => "ëè"; _ => []} ;

          q   = case verb.ad.isEmpty of {True => q0; False => False} ;
          li  = case q of {True => "ëè"; _ => []} ;

          vf1 : Str -> {s1 : Str; s2 : Str} = \s ->
            case p of {
              Pos => case q of {True  => {s1=[]; s2="ëè"++apc []};
                                False => {s1=apc []; s2=[]}} ;
              Neg => {s1="íå"++apc li; s2=[]}
            } ;

          vf2 : Str -> {s1 : Str; s2 : Str} = \s ->
            case p of {
              Pos => case q of {True  => {s1=[]; s2="ëè"++s};
                                False => {s1=s;  s2=[]}} ;
              Neg => case verb.vtype of
                       {VNormal => {s1="íå"; s2=li} ;
			_       => {s1="íå"++s++li; s2=[]}}
            } ;

          vf3 : Str -> {s1 : Str; s2 : Str} = \s ->
            case p of {
              Pos => {s1="ùå"++s; s2=li} ;
              Neg => {s1="íÿìà"++li++"äà"++s; s2=[]}
            } ;

          vf4 : Str -> {s1 : Str; s2 : Str} = \s ->
            case p of {
              Pos => {s1=      s++li++clitic.s; s2=[]} ;
              Neg => {s1="íå"++s++li++clitic.s; s2=[]}
            } ;

          verbs : {aux:{s1:Str; s2:Str}; main:Str} =
            case <t,a> of {
              <Pres,Simul> => {aux=vf2 clitic.s;  main=presentImperf}
              ;                                                    --# notpresent
              <Pres,Anter> => {aux=vf1 clitic.s;  main=perfect} ; --# notpresent
              <Past,Simul> => {aux=vf2 clitic.s;  main=aorist} ; --# notpresent
              <Past,Anter> => {aux=vf4 auxAorist; main=perfect} ; --# notpresent
              <Fut, Simul> => {aux=vf3 clitic.s;  main=present} ; --# notpresent
              <Fut, Anter> => {aux=vf3 (apc []);  main=perfect} ; --# notpresent
              <Cond,_    > => {aux=vf4 auxCond ;  main=perfect} --# notpresent
            }

      in verb.ad.s ++ li0 ++ verbs.aux.s1 ++ verbs.main ++ verbs.aux.s2 ;

  daComplex : Anteriority -> Polarity -> VP -> Aspect => Agr => Str =
    \a,p,vp -> \\asp,agr =>
      let clitic = case vp.vtype of {
                     VNormal    => {s=[]; agr=agr} ;
                     VMedial c  => {s=reflClitics ! c; agr=agr} ;
                     VPhrasal c => {s=personalClitics ! c ! agr.gn ! agr.p; agr={gn=GSg Neut; p=P3}}
                   } ;
          pol = case p of {Pos => ""; Neg => "íå"}
      in vp.ad.s ++ "äà" ++ pol ++ clitic.s ++
         case a of {
           Simul => vp.s ! asp ! VPres (numGenNum clitic.agr.gn) clitic.agr.p ;
           Anter => auxBe ! VPres (numGenNum clitic.agr.gn) clitic.agr.p ++
                    vp.s ! asp ! (VPerfect (aform clitic.agr.gn Indef (RObj Acc)))
         } ++
         vp.compl ! agr ;

  gerund : VP -> Aspect => Agr => Str =
    \vp -> \\asp,agr =>
      let clitic = case vp.vtype of {
                     VNormal    => {s=[]; agr=agr} ;
                     VMedial c  => {s=reflClitics ! c; agr=agr} ;
                     VPhrasal c => {s=personalClitics ! c ! agr.gn ! agr.p; agr={gn=GSg Neut; p=P3}}
                   }
      in vp.ad.s ++ clitic.s ++ vp.s ! asp ! VGerund ++ vp.compl ! agr ;

-- For $Numeral$.

    mkDigit : Str -> Str -> Str -> Str -> Str -> Str -> {s : DForm => CardOrd => Str} =
      \dva, dvama, dve, vtori, dvaiset, dvesta ->
      {s = table {
             unit                  => mkCardOrd dva dvama dve vtori ;
             teen nf               => case nf of {
                                        Formal   => mkCardOrd (dva+"íàäåñåò") (dva+"íàäåñåòèìà") (dva+"íàäåñåò") (dva+"íàäåñåòè") ;
                                        Informal => mkCardOrd (dva+"íàéñåò")  (dva+"íàéñåò")     (dva+"íàéñåò")  (dva+"íàéñòè")
                                      } ;
             ten  nf               => case nf of {
                                        Formal   => mkCardOrd (dva+"äåñåò")   (dva+"äåñåòèìà")   (dva+"äåñåò")   (dva+"äåñåòè") ;
                                        Informal => mkCardOrd dvaiset         dvaiset            dvaiset         (dvaiset+"è")
                                      } ;
             hundred               => let dvesten : Str
                                                  = case dvesta of {
                                                      dvest+"à"        => dvest+"åí" ;
                                                      chetiristot+"èí" => chetiristot+"åí"
                                                    }
                                      in mkCardOrd100 dvesta dvesten
           }
      } ;

    mkCardOrd : Str -> Str -> Str -> Str -> CardOrd => Str =
      \dva, dvama, dve, vtori ->
               table {
                 NCard dg   => digitGenderSpecies dva dvama dve ! dg ;
                 NOrd aform => let vtora = init vtori + "à" ;
                                   vtoro = init vtori + "î"
                               in case aform of {
                                    ASg Masc Indef => vtori ;
                                    ASg Masc Def   => vtori+"ÿ" ;
                                    ASgMascDefNom  => vtori+"ÿò" ;
                                    ASg Fem  Indef => vtora ;
                                    ASg Fem  Def   => vtora+"òà" ;
                                    ASg Neut Indef => vtoro ;
                                    ASg Neut Def   => vtoro+"òî" ;
                                    APl Indef      => vtori ;
                                    APl Def        => vtori+"òå"
                                  }
               } ;

    mkCardOrd100 : Str -> Str -> CardOrd => Str =
      \sto, stoten ->
               table {
                 NCard dg   => sto ;
                 NOrd aform => let stotn = init (init stoten) + last stoten ;
                               in case aform of {
                                    ASg Masc Indef => stoten ;
                                    ASg Masc Def   => stotn+"èÿ" ;
                                    ASgMascDefNom  => stotn+"èÿò" ;
                                    ASg Fem  Indef => stotn+"à" ;
                                    ASg Fem  Def   => stotn+"àòà" ;
                                    ASg Neut Indef => stotn+"î" ;
                                    ASg Neut Def   => stotn+"îòî" ;
                                    APl Indef      => stotn+"è" ;
                                    APl Def        => stotn+"èòå"
                                  }
               } ;

    digitGenderSpecies : Str -> Str -> Str -> CardForm => Str =
      \dva, dvama, dve
            -> let addDef : Str -> Str =
                     \s -> case s of {
		             dves+"òà" => dves+"òàòå" ;
		             dv+"à"    => dv+"àòà" ;
		             x         => x+"òå"
                           }
               in table {
                    CFMasc Indef  NonHuman => dva ;
                    CFMasc Def    NonHuman => addDef dva ;
                    CFMascDefNom  NonHuman => addDef dva ;
                    CFMasc Indef  Human    => dvama ;
                    CFMasc Def    Human    => addDef dvama ;
                    CFMascDefNom  Human    => addDef dvama ;
                    CFFem  Indef           => dve ;
                    CFFem  Def             => addDef dve ;
                    CFNeut Indef           => dve ;
                    CFNeut Def             => addDef dve
                  } ;

    mkIP : Str -> Str -> GenNum -> {s : Role => QForm => Str ; gn : GenNum} =
      \koi,kogo,gn -> {
      s = table {
            RSubj    => table QForm [koi;  koi+"òî"] ;
            RObj Acc => table QForm [kogo; kogo+"òî"] ;
            RObj Dat => table QForm ["íà" ++ kogo; kogo+"òî"] ;
            RVoc     => table QForm [koi;  koi+"òî"]
          } ;
      gn = gn
      } ;

    mkPron : (az,men,mi,moj,moia,moiat,moia_,moiata,moe,moeto,moi,moite : Str) -> GenNum -> Person -> {s : Role => Str; gen : AForm => Str; a : Agr} =
      \az,men,mi,moj,moia,moiat,moia_,moiata,moe,moeto,moi,moite,gn,p -> {
      s = table {
            RSubj    => az ;
            RObj Acc => men ;
            RObj Dat => mi ;
            RVoc     => az
          } ;
      gen = table {
              ASg Masc Indef => moj ;
              ASg Masc Def   => moia ;
              ASgMascDefNom  => moiat ;
              ASg Fem  Indef => moia_ ;
              ASg Fem  Def   => moiata ;
              ASg Neut Indef => moe ;
              ASg Neut Def   => moeto ;
              APl Indef      => moi ;
              APl Def        => moite
            } ;
      a = {
           gn = gn ;
           p = p
          }
      } ;

    mkNP : Str -> GenNum -> Person -> {s : Role => Str; a : Agr} =
      \s,gn,p -> {
      s = table {
            RSubj    => s ;
            RObj Acc => s ;
            RObj Dat => "íà" ++ s ;
            RVoc     => s
          } ;
      a = {
           gn = gn ;
           p = p
          }
      } ;
      
    Preposition : Type = {s : Str; c : Case};

    mkQuestion : 
      {s : QForm => Str} -> Clause -> 
      {s : Tense => Anteriority => Polarity => QForm => Str} = \wh,cl ->
      {
      s = \\t,a,p,qform => 
            let cls = cl.s ! t ! a ! p ;
            in wh.s ! qform ++ cls ! case qform of {
                                       QDir   => Inv ;
                                       QIndir => Main
                                     }
      } ;

    whichRP : GenNum => Str
            = table {
                GSg Masc => "êîéòî" ;
                GSg Fem  => "êîÿòî" ;
                GSg Neut => "êîåòî" ;
                GPl      => "êîèòî"
              } ;

    suchRP : GenNum => Str
           = table {
               GSg Masc => "òàêúâ" ;
               GSg Fem  => "òàêàâà" ;
               GSg Neut => "òàêîâà" ;
               GPl      => "òàêèâà"
             } ;
             
    thisRP : GenNum => Str
           = table {
               GSg Masc => "òîçè" ;
               GSg Fem  => "òaçè" ;
               GSg Neut => "òîâà" ;
               GPl      => "òåçè"
             } ;

    linCoord : Ints 2 => Str ;
    linCoord = table {0 => "è"; 1=>"èëè"; 2=>"íèòî"} ;
    
    linCoordSep : Str -> Bool => Ints 2 => Str ;
    linCoordSep s = table {True => linCoord; False=> \\_ => s} ;
}