concrete NounAra of Noun = CatAra ** open ResAra, Prelude in { flags optimize=noexpand ; lin DetCN det cn = let { cas : Case -> Case = if_then_else Case det.is1sg Bare ; number = case cn.isDual of { True => case sizeToNumber det.n of { Sg => Sg ; _ => Dl } ; False => sizeToNumber det.n } ; determiner : Case -> Str = \c -> det.s ! cn.h ! detGender cn.g det.n ! c ; noun : Case -> Str = \c -> cn.s ! number ! nounState det.d number ! nounCase c det.n det.d ; adj : Case -> Str = \c -> cn.s2 ! number ! (definite ! det.d) -- Indef remains Indef, rest become Def ! c } in emptyNP ** { s = \\c => -- Dat is just a hack for liPrep let c' = case c of {Dat => Gen ; x => x} in case cnB4det det of { False => determiner c' ++ noun c' ++ adj c' ++ cn.np ! c' ; True => noun (cas c) -- deal with possessive suffix + dative hack ++ determiner c' ++ adj c' ++ cn.np ! c' }; a = { pgn = agrP3 cn.h cn.g number; isPron = False } ; isHeavy = cn.isHeavy } ; UsePN pn = emptyNP ** { s = pn.s; a = {pgn = Per3 pn.g Sg ; isPron = False} }; UsePron p = p ; DetNP det = case det.isEmpty of { True => case of { -- if the s field is empty, make up some other determiner => he_Pron ; => theyMasc_Pron ; => emptyNP ** {s = someSg_Det.s ! NoHum ! Masc} ; _ => emptyNP ** {s = somePl_Det.s ! NoHum ! Masc} } ; False => emptyNP ** {s = det.s ! NoHum ! Masc} } ; PredetNP det np = np ** { s = \\c => case det.isDecl of { True => det.s ! c ++ bindIf np.a.isPron ++ np.s ! Gen ; -- akvaru l-awlAdi False => det.s ! c ++ np.s ! c } ; a = np.a ** {isPron=False} } ; {- PPartNP np v2 = let x = case np.a.pgn of { Per3 g n => positAdj (v2.s ! VPPart) ) ! g ! n ! Indef ; -- doesn't work because trying to glue runtime tokens Per2 g n => \\_ => [] ; _ => \\_ => [] } in np ** { s = \\c => np.s ! c ++ v2.s ! VPPart ---- TODO: agreement }; -} AdvNP np adv = np ** { s = \\c => np.s ! c ++ adv.s ; isHeavy = True ; }; DetQuantOrd quant num ord = quant ** { s = \\h,g,c => let d = toDef quant.d num.n in quant.s ! Pl ! h ! g ! c -- TODO what is this Pl? Was there when I started /IL ++ num.s ! g ! d ! c --FIXME check this: ++ ord.s ! g ! case d of {Poss => Def ; _ => d} ! c ; n = num.n; isNum = orB num.isNum ord.isNum ; -- ord may come from OrdDigits or OrdNumeral -- num may come from NumCard : Card -> Num isEmpty = False } ; DetQuant quant num = quant ** { s = \\h,g,c => quant.s ! sizeToNumber num.n ! h ! g ! c ++ num.s ! g ! (toDef quant.d num.n) ! c ; n = num.n; isNum = -- Num may come from NumCard : Card -> Num case num.n of { None => False; _ => num.isNum } ; isEmpty = case quant.isEmpty of { True => notB num.isNum ; _ => False } } ; PossPron p = baseQuant ** { s = \\_,_,_,_ => BIND ++ p.s ! Gen; d = Poss; is1sg = is1sg p.a ; isPron = p.a.isPron} ; NumSg = { s = \\_,_,_ => [] ; n = One ; isNum = False } ; NumPl = { s = \\_,_,_ => [] ; n = None ; isNum = False } ; NumDigits digits = digits ** { s = \\_,_,_ => digits.s ; isNum = True }; NumDecimal dec = dec ** { s = \\_,_,_ => dec.s ; isNum = True }; NumNumeral numeral = numeral ** { s = numeral.s ! NCard ; isNum = True }; NumCard n = n ; AdNum adn num = num ** { s = \\g,d,c => adn.s ++ num.s ! g ! d ! c ; } ; OrdDigits digits = digits ** { s = \\_,d,_ => Al ! d ++ digits.s; isNum = True }; -- OrdNumeral : Numeral -> Ord ; -- fifty-first OrdNumeral numeral = numeral ** { s = numeral.s ! NOrd ; isNum = True }; -- FIXME, "the biggest house" would better translate into -- akbaru baytin rather than al-baytu l-2akbaru -- DetCN (DetSg DefArt (OrdSuperl big_A)) (UseN house_N) OrdSuperl a = { s = \\_,d,c => a.s ! AComp d c; n = One ; isNum = False } ; DefArt = { s = \\_,_,_,_ => []; d = Def ; isNum,isPron,is1sg = False ; isEmpty = True } ; IndefArt = { s = \\_,_,_,_ => []; d = Indef ; isNum,isPron,is1sg = False ; isEmpty = True } ; MassNP cn = emptyNP ** { s = \\c => cn2str cn Sg Indef c ; a = {pgn = Per3 cn.g Sg ; isPron = False} ; isHeavy = cn.isHeavy ; } ; UseN, UseN2 = useN ; Use2N3 n3 = n3 ; Use3N3 n3 = n3 ** {c2 = n3.c3} ; ComplN2 n2 np = UseN n2 ** { np = \\c => n2.c2.s ++ bindIf n2.c2.binds ++ np.s ! n2.c2.c } ; ComplN3 n3 np = ComplN2 n3 np ** {c2 = n3.c3} ; AdjCN ap cn = cn ** { s2 = \\n,d,c => cn.s2 ! n ! d ! c ++ ap.s ! cn.h ! cn.g ! n ! (definite ! d) ! c }; RelCN cn rs = cn ** { s2 = \\n,s,c => cn.s2 ! n ! s ! c ++ rs.s ! Per3 cn.g n ! c ; isHeavy = True } ; RelNP np rs = np ** { s = \\c => np.s ! c ++ rs.s ! np.a.pgn ! c ; isHeavy = True } ; AdvCN, SentCN = \cn,ss -> cn ** { np = \\c => cn.np ! c ++ ss.s ; isHeavy = True } ; ApposCN cn np = cn ** { np = \\c => cn.np ! c ++ np.s ! c } ; -- : CN -> NP -> CN ; -- house of Paris, house of mine PossNP cn np = cn ** { s = \\n,d,c => cn.s ! n ! case d of {Poss=>d ; _=>Const} ! c ; s2 = \\n,d,c => cn.s2 ! n ! case d of {Poss=>d ; _=>Const} ! Gen ; np = \\c => cn.np ! c ++ case is1sg np.a of { True => "لَدَي" ++ np.empty ; False => case np.a.isPron of { True => "لَدَي" ++ BIND ++ np.s ! Gen ; False => np.s ! Gen } } }; DetDAP d = d ; QuantityNP n m = emptyNP ** { s = \\c => preOrPost m.isPre m.s n.s ; a = { pgn = agrP3 NoHum Masc (sizeToNumber n.n); isPron = False } }; }