From b90e0364723294972cefca449ab123069bea34ff Mon Sep 17 00:00:00 2001 From: Herbert Lange Date: Tue, 25 Jun 2019 17:17:46 +0200 Subject: [PATCH] kind of working implementation of cardinal numbers --- src/latin/CatLat.gf | 4 +- src/latin/NumeralLat.gf | 199 ++++++++++++++++++++++++++++------------ src/latin/ResLat.gf | 57 ++++++++++-- 3 files changed, 192 insertions(+), 68 deletions(-) diff --git a/src/latin/CatLat.gf b/src/latin/CatLat.gf index 7f95ff773..a1ce8a5be 100644 --- a/src/latin/CatLat.gf +++ b/src/latin/CatLat.gf @@ -1,4 +1,4 @@ -concrete CatLat of Cat = CommonX-[Adv] ** open ResLat, ParamX, Prelude in { +concrete CatLat of Cat = CommonX-[Adv,Voc] ** open ResLat, ParamX, Prelude in { flags optimize=all_subs ; @@ -60,7 +60,7 @@ concrete CatLat of Cat = CommonX-[Adv] ** open ResLat, ParamX, Prelude in { -- ---- Numeral -- - Numeral = ResLat.Numeral ; + Numeral = ResLat.TNumeral ; Digits = {s : Str ; unit : Unit} ; -- ---- Structural diff --git a/src/latin/NumeralLat.gf b/src/latin/NumeralLat.gf index 4e51cfe10..075915b62 100644 --- a/src/latin/NumeralLat.gf +++ b/src/latin/NumeralLat.gf @@ -1,77 +1,151 @@ -concrete NumeralLat of Numeral = CatLat ** open ResLat,ParadigmsLat,Prelude in { +concrete NumeralLat of Numeral = CatLat, ParamX[Number] ** open ParadigmsLat, Prelude, ResLat, Predef in { lincat Digit = TDigit ; - Sub10 = Numeral ; - Sub100 = Numeral ; - Sub1000 = Numeral ; - Sub1000000 = Numeral ; + Sub10 = TNumeral ; + Sub100 = TNumeral ; + Sub1000 = TNumeral ; + Sub1000000 = TNumeral ; lin num x = x ; - n2 = lin Digit ( mkDigit "duo" "viginti" "ducenti" "secundus" ) ; - n3 = lin Digit ( mkDigit "tres" "triginta" "trecenti" "tertius" ) ; - n4 = lin Digit ( mkDigit "quattuor" "quadraginta" "quadringenti" "quartus" ) ; - n5 = lin Digit ( mkDigit "quinque" "quinquaginta" "quingenti" "quintus" ) ; - n6 = lin Digit ( mkDigit "sex" "sexaginta" "sescenti" "sextus" ) ; - n7 = lin Digit ( mkDigit "septem" "septuaginta" "septingenti" "septimus" ) ; - n8 = lin Digit ( mkDigit "octo" "octoginta" "octingenti" "ocatvus" ) ; - n9 = lin Digit ( mkDigit "novem" "nonaginta" "nongenti" "nonus") ; + n2 = lin Digit ( mkDigit "duo" "duodecim" "viginti" "ducenti" "secundus" "triginta" Yes ) ; + n3 = lin Digit ( mkDigit "tres" "tredecim" "triginta" "trecenti" "tertius" "quadraginta" Yes ) ; + n4 = lin Digit ( mkDigit "quattuor" "quattuordecim" "quadraginta" "quadringenti" "quartus" "quinquaginta" Yes ) ; + n5 = lin Digit ( mkDigit "quinque" "quindecim" "quinquaginta" "quingenti" "quintus" "sexaginta" Yes ) ; + n6 = lin Digit ( mkDigit "sex" "sedecim" "sexaginta" "sescenti" "sextus" "septuaginta" Yes ) ; + n7 = lin Digit ( mkDigit "septem" "septendecim" "septuaginta" "septingenti" "septimus" "octoginta" Yes ) ; + n8 = lin Digit ( mkDigit "octo" "duodeviginti" "octoginta" "octingenti" "ocatvus" "nonaginta" No8 ) ; + n9 = lin Digit ( mkDigit "novem" "undeviginti" "nonaginta" "nongenti" "nonus" "centum" No9 ) ; -- 1 - pot01 = { s = n1.s ! one ; n = Sg } ; + pot01 = { s = n1.s ! one ; d = n1.s ; n = singular ; below8 = n1.below8 } ; -- d * 1 - pot0 d = { s = d.s ! one ; n = Pl } ; + pot0 d = { + s = d.s ! one ; + d = table { + thousand => \\g,c => d.s ! one ! g ! c ++ d.s ! thousand ! g ! c ; + u => \\g,c => d.s ! u ! g ! c + } ; + n = plural ; + below8 = d.below8 + } ; -- 10 - pot110 = { s = n1.s ! ten ; n = Sg } ; + pot110 = { + s = n1.s ! ten ; + d = table { + thousand => \\g,c => n1.s ! ten ! g ! c ++ n1.s ! thousand ! g ! c ; + u => \\g,c => n1.s ! u ! g ! c + } ; + n = singular ; + below8 = Yes + } ; -- 11 --- pot111 = pot1to19 pot01 ; --- -- 10 + d --- -- pot1to19 d = mkNum "" "" "" "" ; -- {s = d.s ! teen} ** {n = Pl} ; + pot111 = pot1to19 n1 ; + -- 10 + d + pot1to19 d = { + s = d.s ! eleven ; + d = table { + thousand => \\g,c => d.s ! eleven ! g ! c ++ n1.s ! thousand ! g ! c ; + u => \\g,c => d.s ! u ! g ! c + } ; + n = plural ; + below8 = Ign + } ; -- coercion of 1..9 pot0as1 n = n ; -- d * 10 - pot1 d = {s = d.s ! ten ; n = Pl} ; + pot1 d = { + s = d.s ! ten ; + d = table { + thousand => \\g,c => d.s ! ten ! g ! c ++ n1.s ! thousand ! g ! c ; + u => \\g,c => d.s ! u ! g ! c + } ; + n = plural ; + below8 = Yes + } ; -- d * 10 + n - -- pot1plus d e = { - -- s = \\c => d.s ! ten ++ "-" ++ e.s ! one ! c ; - -- n = Pl} ; + pot1plus d n = + let + newS : Gender => Case => Str = \\g,c => case n.below8 of { + No8 => "duo" ++ Prelude.BIND ++ "-" ++ Prelude.BIND ++ "de" ++ Prelude.BIND ++ "-" ++ Prelude.BIND ++ d.tenNext ; + No9 => "un" ++ Prelude.BIND ++ "-" ++ Prelude.BIND ++ "de" ++ Prelude.BIND ++ "-" ++ Prelude.BIND ++ d.tenNext ; + _ => d.s ! ten ! g ! c ++ n.s ! g ! c + } in + { + s = newS ; + d = table { + thousand => \\g,c => newS ! g ! c ++ n1.s ! thousand ! g ! c ; + u => \\g,c => n.d ! u ! g ! c + } ; + below8 = Ign ; + n = plural + } ; -- coercion of 1..99 pot1as2 n = n ; -- m * 100 --- pot2 d = {s = d.s ! hundred ; n = Pl} ; --- -- m * 100 + n --- --lin pot2plus d e = { --- -- s = \\c => d.s ! unit ! NCard ++ "hundred" ++ "and" ++ e.s ! c ; n = Pl} ; + pot2 n = { + s = n.d ! hundred ; + d = table { + thousand => \\g,c => n.d ! hundred ! g ! c ++ n1.s ! thousand ! g ! c ; + u => \\g,c => n.d ! u ! g ! c + } ; + n = plural ; + below8 = Yes} ; + -- d * 100 + n + pot2plus d n = + let + newS : Gender => Case => Str = \\g,c => d.d ! hundred ! g ! c ++ "et" ++ n.s ! g ! c + in + { + s = newS ; + d = table { + thousand => \\g,c => newS ! g ! c ++ n1.s ! thousand ! g ! c ; + u => \\g,c => n.d ! u ! g ! c + } ; + below8 = Ign ; + n = plural + } ; -- coercion of 1..999 pot2as3 n = n ; --- -- m * 1000 --- --lin pot3 n = { --- -- s = \\c => n.s ! NCard ++ mkCard c "thousand" ; n = Pl} ; --- -- m * 1000 + n --- --lin pot3plus n m = { --- -- s = \\c => n.s ! NCard ++ "thousand" ++ m.s ! c ; n = Pl} ; + -- m * 1000 + pot3 n = { + s = \\g,c => n.s ! g ! c ++ n.d ! thousand ! g ! c ; + d = table { thousand => \\g,c => n.s ! g ! c ++ n.d ! thousand ! g ! c ; + u => \\g,c => n.d ! u ! g ! c + } ; + below8 = Ign ; + n = plural + } ; + + -- d * 1000 + n + pot3plus d n = { + s = \\g,c => d.d ! thousand ! g ! c ++ "et" ++ n.s ! g ! c ; + d = n.d ; + below8 = Ign ; + n = plural + } ; oper - n1 : Digit = lin Digit ( fullDigit "unus" "decem" "primus" "decimus" "centesimus" "millesimus" ) ; - - mkDigit : (ones, tens, hundreds, ord : Str) -> TDigit = - \ones, tens, hundreds, ord -> + mkDigit : (ones, eleven, tens, hundreds, ord : Str) -> Str -> Below8 -> TDigit = + \ones, eleven, tens, hundreds, ord -> case of { - <"decem",_> => fullDigit ones tens hundreds ord "decimus" "centesimus" ; - <"viginti",_> => fullDigit ones tens hundreds ord "vicesimus" "ducentesimus" ; - <"triginta",_> => fullDigit ones tens hundreds ord "tricesimus" "trecentesimus" ; - => fullDigit ones tens hundreds ord (quadra + "gesimus") (quadringent + "esimus") ; + <"decem",_> => fullDigit ones eleven tens hundreds ord "decimus" "centesimus" ; + <"viginti",_> => fullDigit ones eleven tens hundreds ord "vicesimus" "ducentesimus" ; + <"triginta",_> => fullDigit ones eleven tens hundreds ord "tricesimus" "trecentesimus" ; + => fullDigit ones eleven tens hundreds ord (quadra + "gesimus") (quadringent + "esimus") ; _ => Predef.error "Invalid number" } ; - fullDigit : (ones, tens, hundreds, ord1,ord10,ord100 : Str) -> TDigit = - \ones, tens, hundreds, ord1,ord10,ord100 -> + fullDigit : (ones, eleven, tens, hundreds, ord1,ord10,ord100, tenNext : Str) -> Below8 -> TDigit = + \ones, eleven, tens, hundreds, ord1,ord10,ord100,tenNext,b8 -> { s = table { one => cardFlex ones ; + eleven => cardFlex eleven ; ten => cardFlex tens ; hundred => cardFlex hundreds ; - thousand => \\_,_ => nonExist ; + thousand => cardFlex "milia" ; ten_thousand => \\_,_ => nonExist ; - hundred_thousand => \\_,_ => nonExist } --- n = case ones of { "unus" => Sg ; _ => Pl } ; + hundred_thousand => \\_,_ => nonExist + } ; +-- n = case ones of { "unus" => singular ; _ => plural } ; -- ord = -- \\_,_ => [] ; -- -- table { one => (mkA ord1).s ! Posit; @@ -80,7 +154,11 @@ concrete NumeralLat of Numeral = CatLat ** open ResLat,ParadigmsLat,Prelude in { -- -- thousand => \\_,_ => nonExist ; -- -- ten_thousand => \\_ => nonExist ; -- -- hundred_thousand => \\_ => nonExist } ; - } ; + tenNext = tenNext ; + below8 = b8 + } ; + n1 : Digit = lin Digit ( fullDigit "unus" "decem" "undecim" "primus" "decimus" "centesimus" "millesimus" "viginti" Yes ) ; + -- numerals as sequences of digits lincat @@ -94,30 +172,31 @@ concrete NumeralLat of Numeral = CatLat ** open ResLat,ParadigmsLat,Prelude in { unit = inc i.unit } ; - D_0 = mkDig "" "" "" "" "" "" ; - D_1 = mkDig "I" "X" "C" "M" "(X)" "(C)" ; - D_2 = mkDig "II" "XX" "CC" "MM" "(XX)" "(CC)" ; - D_3 = mkDig "III" "XXX" "CCC" "MMM" "(XXX)" "(CCC)" ; - D_4 = mkDig "IV" "XL" "CD" "(IV)" "(XL)" "(CD)" ; - D_5 = mkDig "V" "L" "D" "(V)" "(L)" "(D)" ; - D_6 = mkDig "VI" "LX" "DC" "(VI)" "(LX)" "(DC)" ; - D_7 = mkDig "VII" "LXX" "DCC" "(VII)" "(LXX)" "(DCC)" ; - D_8 = mkDig "VIII" "LXXX" "DCCC" "(VIII)" "(LXXX)" "(DCCC)" ; - D_9 = mkDig "IX" "XC" "CM" "(IX)" "(XC)" "(CM)" ; + D_0 = mkDig "" "" "" "" "" "" "" ; + D_1 = mkDig "I" "XI" "X" "C" "M" "(X)" "(C)" ; + D_2 = mkDig "II" "XII" "XX" "CC" "MM" "(XX)" "(CC)" ; + D_3 = mkDig "III" "XIII" "XXX" "CCC" "MMM" "(XXX)" "(CCC)" ; + D_4 = mkDig "IV" "XIV" "XL" "CD" "(IV)" "(XL)" "(CD)" ; + D_5 = mkDig "V" "XV" "L" "D" "(V)" "(L)" "(D)" ; + D_6 = mkDig "VI" "XVI" "LX" "DC" "(VI)" "(LX)" "(DC)" ; + D_7 = mkDig "VII" "XVII" "LXX" "DCC" "(VII)" "(LXX)" "(DCC)" ; + D_8 = mkDig "VIII" "XVIII" "LXXX" "DCCC" "(VIII)" "(LXXX)" "(DCCC)" ; + D_9 = mkDig "IX" "XIX" "XC" "CM" "(IX)" "(XC)" "(CM)" ; oper TDig = { s : Unit => Str } ; - mkDig : Str -> Str -> Str -> Str -> Str -> Str -> TDig = - \one,ten,hundred,thousand,ten_thousand,hundred_thousand -> { - s = table Unit [one;ten;hundred;thousand;ten_thousand;hundred_thousand] + mkDig : Str -> Str -> Str -> Str -> Str -> Str -> Str -> TDig = + \one,eleven,ten,hundred,thousand,ten_thousand,hundred_thousand -> { + s = table Unit [one;eleven;ten;hundred;thousand;ten_thousand;hundred_thousand] } ; inc : Unit -> Unit = \u -> case u of { one => ten ; + eleven => hundred ; ten => hundred ; hundred => thousand ; thousand => ten_thousand ; diff --git a/src/latin/ResLat.gf b/src/latin/ResLat.gf index cd2a2f1f6..0235bddd9 100644 --- a/src/latin/ResLat.gf +++ b/src/latin/ResLat.gf @@ -190,7 +190,51 @@ param audaces audaces (audac + "ium") (audac + "ibus") g ; - + regAdj : Str -> Gender => Number => Case => Str = \s -> + case s of { + un + "us" => \\g,n,c => un + (regAdjSuffixes s g n c) + } ; + + regAdjSuffixes : Str -> Gender -> Number -> Case -> Str = \str,g,n,c -> + case of { + => "us" ; + => "i" ; + => "o" ; + => "um" ; + => "o" ; + => case str of { _ + "ius" => "i" ; _ => "e" } ; + => "i" ; + => "orum" ; + => "is" ; + => "os" ; + => "is" ; + => "i" ; + => "um" ; + => "i" ; + => "o" ; + => "um" ; + => "o" ; + => "um"; + => "a" ; + => "orum" ; + => "is" ; + => "os" ; + => "is" ; + => "a" ; + => "a" ; + => "ae" ; + => "ae" ; + => "am" ; + => "a" ; + => "a"; + => "ae" ; + => "arum" ; + => "is" ; + => "as" ; + => "is" ; + => "ae" + } ; + emptyAdj : Adjective = { s = \\_,_ => "" ; comp_adv = "" ; super_adv = "" ; adv = { s = \\_ => "" } } ; @@ -1421,11 +1465,12 @@ oper -- numerals param -- CardOrd = NCard | NOrd ; - Unit = one | ten | hundred | thousand | ten_thousand | hundred_thousand ; + Unit = one | eleven | ten | hundred | thousand | ten_thousand | hundred_thousand ; + Below8 = Yes | No8 | No9 | Ign ; oper -- Numerals are by default cardinal numbers but have a field for ordinal numbers - TDigit : Type = { s : Unit => Gender => Case => Str } ; -- ord : Unit => Agr => Str } ; - Numeral : Type = { s : Gender => Case => Str ; n : Number } ; -- ord : Unit => Agr => Str } ; + TDigit : Type = { s : Unit => Gender => Case => Str ; tenNext : Str ; below8 : Below8 } ; -- ord : Unit => Agr => Str } ; + TNumeral : Type = { s : Gender => Case => Str ; d : Unit => Gender => Case => Str ; n : Number ; below8 : Below8 } ; -- ord : Unit => Agr => Str } ; -- Inflection for cardinal numbers cardFlex : Str -> Gender => Case => Str = @@ -1442,9 +1487,9 @@ oper => "tria" ; <_, Nom | Acc | Voc > => "tres" ; <_, Gen> => "trium" ; <_, Dat | Abl > => "tribus" } ; + tre + "centi" => \\g,c => regAdj (tre + "centus") ! g ! Pl ! c ; "milia" => table { - Neutr => table Case [ "milia" ; "milia" ; "milium" ; "milibus" ; "milibus" ; "milia" ] ; - _ => \\_ => nonExist + _ => table Case [ "milia" ; "milia" ; "milium" ; "milibus" ; "milibus" ; "milia" ] } ; _ => \\_,_ => c } ;