concrete NumeralSom of Numeral = CatSom [Numeral,Digits,Decimal] **
  open Prelude, ResSom, ParamSom in {

oper
  LinDigit : Type = {
    unit : {s : DForm => Str ; ord : Str ; da : DefArticle} ;
    ten : {s, ord : Str ; da : DefArticle}
    } ;

  mkNum3 : (ucard,tcard,uord : Str) -> DefArticle -> LinDigit = \uc,tc,uo,ud -> {
    unit = {s = \\df => uc ; ord = uo ; da = ud} ;
    ten  = {s = tc ; ord = tc + "aad" ; da = M KA}
    } ;

  mkNum2 : (ucard,tcard : Str) -> LinDigit = \uc,tc ->
    let uo : Str = case uc of {
               x + "a" => x + "aad" ; -- ??
               x + #v + c@#c => x + c + "aad" ;
               _             => uc + "aad" } ;
     in mkNum3 uc tc uo (F DA) ;

  mkNum2Masc : (ucard,tcard : Str) -> LinDigit = \uc,tc ->
    let uo : Str = case uc of {
               x + "a" => x + "aad" ; -- ??
               x + #v + c@#c => x + c + "aad" ;
               _             => uc + "aad" } ;
     in mkNum3 uc tc uo (M KA) ;


lincat
  Digit = LinDigit ;

  {- Saeed p. 70-71: "When used with nouns, the cardinal numerals act as
  the head of the construction and the counted noun occurs in the genitive
  case. […] This construction also occurs with composite numerals like
  laba boqol 'two hundred',
  where laba 'two' is a feminine noun in absolutive case and
  boqol 'hundred' is a masculine noun in genitive case.
  Since laba is head, the whole nominal is feminine." -}
  Sub10, Sub100, Sub1000, Sub1000000, Sub1000000000, Sub1000000000000 = {
    s : DForm => Str ;
    thousand : Str ; -- TODO figure out if this really works so
    hasThousand : Bool ;
    ord : Str ;
    da : DefArticle ;
    n : Number
  } ;

----------------------------------------------------------------------------


--  num : Sub1000000 -> Numeral ;
lin num x = x ;

oper kow : DForm => Str = table {Kow => "kow" ; Hal => "hal" ; Mid => "mid"}  ;
oper n1 : LinDigit = let one : LinDigit = mkNum2 "kow" "toban" in one ** {
    unit = one.unit ** {s = kow}
    } ;
lin n2  = mkNum2 "laba" "labaatan" ;
lin n3  = mkNum2 "saddex" "soddon" ;
lin n4  = mkNum2 "afar" "afartan";
lin n5  = mkNum2 "shan" "konton";
lin n6  = mkNum2 "lix" "lixdan" ;
lin n7  = mkNum2 "toddoba" "toddobaatan" ;
lin n8  = mkNum2Masc "siddeed" "siddeetan" ;
lin n9  = mkNum2Masc "sagaal" "sagaashan" ;

lin pot01 = n1.unit ** {n = Sg ; thousand = [] ; hasThousand = False} ;

lin pot0 d = d.unit ** {n = Pl ; thousand = [] ; hasThousand = False} ;

lin pot110 = n1.ten ** {
    s = \\df => n1.ten.s ;
    thousand = [] ;
    hasThousand = False ;
    n = Pl
    } ;
lin pot111 = {
    s = \\_ => "koob iyo" ++ n1.ten.s ;
    ord = "koob iyo" ++ n1.ten.ord ;
    thousand = [] ;
    hasThousand = False ;
    da = M KA ;
    n = Pl
    } ;
lin pot1to19 d = {
    s = \\_ => d.unit.s ! Hal ++ "iyo" ++ n1.ten.s ;
    thousand = [] ;
    hasThousand = False ;
    ord = d.unit.s ! Hal ++ "iyo" ++ n1.ten.ord ;
    da = M KA ;
    n = Pl
    } ;
lin pot0as1 n = n ;
lin pot1 d = d.ten ** {
    s = \\df => d.ten.s ;
    thousand = [] ;
    hasThousand = False ;
    n = Pl
    } ;
lin pot1plus d e = d.ten ** {
    s = \\b => e.s ! b  ++ "iyo" ++ d.ten.s ;
    ord = e.s ! Hal ++ "iyo" ++ d.ten.ord ;
    thousand = [] ;
    hasThousand = False ;
    n = Pl ;
  } ;
lin pot1as2 n = n ;
lin pot2 d = d ** {
    thousand = "boqol" ;
    hasThousand = True ;
    ord = d.s ! Hal ++ "boqlaad"
    } ;
lin pot2plus d e = d ** {
    thousand = "boqol iyo" ++ e.s ! Hal ;
    hasThousand = True ;
    ord = d.s ! Hal ++ "boqol iyo" ++ e.ord ;
    n = Pl} ;
lin pot2as3 n = n ;
lin pot3 n = n ** {
    thousand = n.thousand ++ "kun" ;
    hasThousand = True ;
    ord = n.s ! Hal ++ "kunaad" ;
    n = Pl } ;

lin pot3plus n m = n ** {
  s = \\b => n.s ! b ++ "kun iyo" ++ m.s ! b ;
  ord = n.ord ++ "kun iyo" ++ m.ord ;
  n = Pl} ;

lin pot3as4 n = n ;
lin pot4as5 n = n ;


----------------------------------------------------------------------------

lincat Dig = TDigit ;

oper
  TDigit : Type = { s : CardOrd => Str ; n : Number } ;
  mkDig : Str -> TDigit = \c -> mk2Dig c Pl ;

  mk2Dig : Str -> Number -> TDigit = \c,num ->
   { s = table { NCard => c ;
                 NOrd  => c + "aan" } ;
     n = num } ;


lin D_0 = mkDig "0" ;
lin D_1 = mk2Dig "1" Sg ;
lin D_2 = mkDig "2" ;
lin D_3 = mkDig "3" ;
lin D_4 = mkDig "4" ;
lin D_5 = mkDig "5" ;
lin D_6 = mkDig "6" ;
lin D_7 = mkDig "7" ;
lin D_8 = mkDig "8" ;
lin D_9 = mkDig "9" ;

    -- : Dig -> Digits ;
lin IDig dig = dig ;
    -- : Dig -> Digits -> Digits ;
lin IIDig dig digs = digs ** {s = \\co => glue (dig.s ! co) (digs.s ! co) } ;
lin PosDecimal d = d ** {hasDot=False} ;
lin NegDecimal d = {
      s = \\co => glue "-" (d.s ! co) ;
      n = Pl ;
      hasDot=False
    } ;
    IFrac d i = {
      s = \\co => d.s ! co ++
                  if_then_Str d.hasDot BIND (BIND++"."++BIND) ++
                  i.s ! co;
      n = Pl ;
      hasDot=True
    } ;

}
