Convert Integer to (French) Words

"Les numéraux cardinaux sont invariables comme adjectifs et comme noms, sauf million, milliard, vingt dans quatre-vingts et cent dans deux cents, trois cents, etc. Toutefois, il est d`usage de ne pas mettre d`s lorsqu`ils sont complétés d`un autre adjectif numéral: quatre-vingt-deux, deux cent trois." [Dictionnaire de Français Contemporain, Larousse, 1971]

/* integer_words(Integer, Words) is true if the positive Integer less than */
/*   10 000 000 can be expressed by the (French) Words.                    */
integer_words(Integer, Words):-
  Integer > 0,
  int(Integer, `s`, Strings, []),
  cat(Strings, Words, _).

int(0, _) --> !.
int(I, _) --> 
  {I =< 16}, !, le16(I).
int(I, F) --> 
  {I =< 99}, !, {Q is I // 10, R is I mod 10}, le99(Q, R, F).
int(I, F) --> 
  {I =< 999}, !, {Q is I // 100, R is I mod 100}, le999(Q, R, F).
int(I, _) --> 
  {I =< 999999}, !, {Q is I // 1000, R is I mod 1000}, le999999(Q, R).
int(I, _) --> 
  {I =< 9999999, Q is I // 1000000, R is I mod 1000000}, le9999999(Q, R).

le16( 1) --> [`un`].
le16( 2) --> [`deux`].
le16( 3) --> [`trois`].
le16( 4) --> [`quatre`].
le16( 5) --> [`cinq`].
le16( 6) --> [`six`].
le16( 7) --> [`sept`].
le16( 8) --> [`huit`].
le16( 9) --> [`neuf`].
le16(10) --> [`dix`].
le16(11) --> [`onze`].
le16(12) --> [`douze`].
le16(13) --> [`treize`].
le16(14) --> [`quatorze`].
le16(15) --> [`quinze`].
le16(16) --> [`seize`].

le99(1, R, _) --> [`dix-`], le16(R).
le99(2, R, _) --> [`vingt`], le9(R).
le99(3, R, _) --> [`trente`], le9(R).
le99(4, R, _) --> [`quarante`], le9(R).
le99(5, R, _) --> [`cinquante`], le9(R).
le99(6, R, _) --> [`soixante`], le9(R).
le99(7, 1, _) --> !, [`soixante et onze`].
le99(7, R, _) --> [`soixante-`], {R1 is 10 + R}, int(R1, ``).
le99(8, 0, F) --> !, [`quatre-vingt`,F].
le99(8, R, _) --> [`quatre-vingt-`], le16(R).
le99(9, R, _) --> [`quatre-vingt-`], {R1 is 10 + R}, int(R1, ``).

le9(0) --> !.
le9(1) --> !, [` et un`].
le9(R) --> [`-`], le16(R).

le999(1, 0, _) --> !, [`cent`].
le999(1, R, F) --> !, [`cent `], int(R, F).
le999(Q, 0, F) --> !, le16(Q), [` cent`, F].
le999(Q, R, F) --> le16(Q), [` cent `], int(R, F).

le999999(1, 0) --> !, [`mille`].
le999999(1, R) --> !, [`mille `], int(R, `s`).
le999999(Q, 0) --> !, int(Q, ``), [` mille`].
le999999(Q, R) --> int(Q, ``), [` mille `], int(R, `s`).

le9999999(1, 0) --> !, [`un million`].
le9999999(Q, 0) --> !, le16(Q), [` millions`].
le9999999(Q, R) --> le16(Q), [` million `], int(R, `s`).

LPA Index     Home Page