Using Fractions in GF

95 views Asked by At

I'm trying to add decimals and fractions of two digits into RGL while keeping the original singular/plural rules of the noun that comes after mkNumeral or mkDigits. I tried using multiple nouns as

    mkNP(mkCN
           (mkN("ein"))
           (mkNP(mkCN
               (mkN("ein"))
               (mkNP(mkN("halb"))))));

but this method doesn't work for all languages as in German eineinhalb has no space in between, and using aPl_Det to get the plural of a noun might work for English and German, but not for other languages such as French which actually has a real aPl_Det.

Thus I tried extending an NP and added multiple strings into its s, such as follow

open SyntaxEng, ParadigmsEng, ResEng in {
oper 
   newNp : Str -> N -> NP =
       \num, noun -> case occur (".")(num) of{
           PTrue => 
              let myNewNP = it_NP ** {s = (mkNP(mkDet(mkNumeral(dropDec num)))).s ++ "point" ++ (mkNP(mkDet(mkNumeral(decNum num)))).s ++ noun ! Pl} ;
                   -- noun is plural here because any number greater than 1 is plural, and I don't expect the user to input 1.00

              in myNewNP;
           PFalse => mkNP(mkDet(mkNumeral (num)))(noun)};

   decNum : Str -> Str = \num -> dp (2) (num);
   dropDec : Str -> Str = \num -> tk (3) (num);
}}

The error message I get is as below. The signs (...) mean there are other instances of mkDet, but they are not important for this problem.

no overload instance of mkDet
for 
    {s : Bool => CardOrd => Case => Str; lock_Numeral : {}; n : Number}
among
...
...
    {s : Bool => CardOrd => Case => Str; lock_Numeral : {}; n : Number}
...
...
with value type Str

What does with value type Str mean and how to solve such a problem?

1

There are 1 answers

0
inariksit On BEST ANSWER

Card/Det or NP

Do you want to use fractions as determiners ("eineinhalb Katzen"), or just standalone noun phrases ("eineinhalb")? Either way, there are a couple different ways, none of which requires extending NPs.

Quick and dirty solution if the fractions don't inflect

Unfortunately, the RGL oper for mkCard expects input like "35", and it gives an error if you type letters or decimal points.

But if your fractions don't inflect, or even if they inflect in the language but your application doesn't need the inflection, then the easiest way is to use Symbolic module, particularly the following pair of opers

mkSymb : Str -> Symb  ;     -- x
symb   : Symb -> Card ;     -- n (number)

That symb function makes the Card plural by default. So you can make any Card like this:

oper myMkCard : Str -> Card = \s -> symb (mkSymb s) ;

GF grammar

Here's working GF code for German.

resource Fractions = open SymbolicGer, SyntaxGer, LexiconGer in {
  oper
    one_and_half_Card : Card = symb (mkSymb "eineinhalb") ;

    one_and_half_NP : NP = mkNP (mkDet one_and_half_Card) ; -- standalone NP
    one_and_half_cats_NP : NP = mkNP one_and_half_Card cat_N ; -- determiner for cat_N
}

Test the output:

> cc -unqual -table one_and_half_cats_NP
s . NPC Nom => eineinhalb Katzen
s . NPC Acc => eineinhalb Katzen
s . NPC Dat => eineinhalb Katzen
s . NPC Gen => eineinhalb Katzen
s . NPP CAnDat => an eineinhalb Katzen
s . NPP CInAcc => in eineinhalb Katzen
s . NPP CInDat => in eineinhalb Katzen
s . NPP CZuDat => zu eineinhalb Katzen
s . NPP CVonDat => von eineinhalb Katzen
a . Ag Fem Pl P3

Depending on the language and application, this could be an acceptable quick and dirty solution. But in general, this should be addressed in the RGL, not so that everyone makes their own hacks.

It's very much nontrivial to know which parts of the fractions inflect. For instance in Swedish, "one" is "en" or "ett" depending on the gender, and "one and half" is "en och en halv" or "ett och ett halvt". These are complicated things whose implementation belongs in the RGL.

General solution for inflecting fractions

We should just extend the mkCard oper in the RGL so that it accepts input like "3.5" or "1½". I can volunteer to do that for the languages I know myself, but it won't be on top of my priority list.

If you want to give it a try in your own fork of the RGL, have a look at the Numeral modules of different languages, and see how the numerals are constructed. For instance, this is the mkDigit for German, you can play with it and try to figure out the following questions

  • What do you need to change or add to make it output "eineinhalb"?
  • How does eineinhalb behave in different cases and numbers? Would you say "einereinhalb", "eineinhalber" or something else?
  • How about ordinals -- can you say "the first and halfth"? (I'm assuming not in general, that's why I'm only suggesting to change mkCard, not mkNumeral :-P)