:- module roman. :- interface. :- import_module io. :- pred main(io::di, io::uo) is det. :- implementation. :- import_module char, int, list, string. main(!IO) :- command_line_arguments(Args, !IO), filter(is_all_digits, Args, CleanArgs), foldl((pred(Arg::in, !.IO::di, !:IO::uo) is det :- ( Roman = to_roman(Arg) -> format("%s => %s", [s(Arg), s(Roman)], !IO), nl(!IO) ; format("%s cannot be converted.", [s(Arg)], !IO), nl(!IO) ) ), CleanArgs, !IO). :- func to_roman(string::in) = (string::out) is semidet. to_roman(Number) = from_char_list(build_roman(reverse(to_char_list(Number)))). :- func build_roman(list(char)) = list(char). :- mode build_roman(in) = out is semidet. build_roman([]) = []. build_roman([D|R]) = Roman :- map(promote, build_roman(R), Interim), Roman = Interim ++ digit_to_roman(D). :- func digit_to_roman(char) = list(char). :- mode digit_to_roman(in) = out is semidet. digit_to_roman('0') = []. digit_to_roman('1') = ['I']. digit_to_roman('2') = ['I','I']. digit_to_roman('3') = ['I','I','I']. digit_to_roman('4') = ['I','V']. digit_to_roman('5') = ['V']. digit_to_roman('6') = ['V','I']. digit_to_roman('7') = ['V','I','I']. digit_to_roman('8') = ['V','I','I','I']. digit_to_roman('9') = ['I','X']. :- pred promote(char::in, char::out) is semidet. promote('I', 'X'). promote('V', 'L'). promote('X', 'C'). promote('L', 'D'). promote('C', 'M'). :- end_module roman.