I'm trying to explore the concepts of natural numbers, Peano numbers, arithmetic, etc. in Prolog. Right now I'm trying to create a predicate that will allow me to enter the name of any number and get it's numerical value (or vice versa). How would I go about this? My idea was that I would translate the numbers given and them add them together using the plus function (e.g. one hundred and forty-five: one, hundred = 100, and = 0, forty = 40, five = 5 -> 100 + 0 + 40 + 5 = 145.
Here's an example of some queries:
?- numnames(X, 375).
X = [three, hundred, and, seventy, five] ;
false.
?- numnames([seven], 7).
true ;
false.
Here are some of my exhaustive facts (I just picked some that would address a certain category):
numnames([],0).
numnames(and,0).
numnames([one],1).
numnames([ninety],90).
numnames([one, hundred], 100).
I'm just confused as to how to translate the numbers before the arithmetic, and also where/when do I stop making exhaustive facts and start making rules? Thanks for the help.
This is a nice application for Prolog grammar rules or DCGs (basically syntactic sugar that hides some list manipulation and has a relatively straightforward translation to normal Prolog rules).
This work both ways (and can enumerate all the numbers):
[I had originally used a #=/2 constraint instead of is/2 to make the code work in both modes, but was reminded by @CapelliC's post that the same can be achieved in plain Prolog by moving the arithmetic to the end of the respective rules...]
I have an extravagant solution, which, nevertheless, could be practical for some situations.
Suppose the max number you plan to use is not too big, maybe a 1000 or 10000. And also you don't want to spend too much time creating Prolog program, don't want to deal with corner cases and are afraid of spelling errors (for example, because you are not a native English speaker, like me).
Then you can generate your Prolog program (list of facts) with another tool. Common Lisp has a standard tool to convert numbers to English words. Let's use it:
Fragment of the Prolog program generated with CLISP (other Lisp implementations can use American spelling, without 'and'):
I will report a well thought DCG solution proposed by Ken Johnson. Full code is here, with a small modification to make it usable (I tested in SWI-Prolog). I amended rules like
ten_to_nine{*filter*}(13) --> [thir{*filter*}].
that sincerely I don't know how to handle.