Search code examples
prolog

Combining two numbers in prolog


Kindly, could you help me in the following:

I am writing a Prolog program that takes two numbers digits then combine them as one number, for example:

Num1: 5
Num2: 1

Then the new number is 51.

Assume V1 is the first number digit and V2 is the second number digit. I want to combine V1 and V2 then multiply the new number with V3, so my question is how I can do it?

calculateR(R, E, V1, V2, V3, V4):-
  R is V1 V2 * V3,
  E is R * V4.

Your help is appreciated.


Solution

  • Edit: In a comment, @false pointed out that this answer is SWI-Prolog specific.

    You can achieve your desired goal by treating the numerals as atoms and concatenating them, and then converting the resultant atom into a number.

    I'll use atom_concat/3 to combine the two numerals. In this predicate, the third argument with be the combination of atoms in its first and second arguments. E.g.,

    ?- atom_concat(blingo, dingo, X).
    X = blingodingo.
    

    Note that, when you do this with two numerals, the result is an atom not a number. This is indicated by the single quotes enclosing the the result:

    ?- atom_concat(5, 1, X).
    X = '51'.
    

    But 51 \= '51' and we cannot multiply an atom by number. We can use atom_number/2 to convert this atom into a number:

    ?- atom_number('51', X).
    X = 51.
    

    That's all there is to it! Your predicate might look like this:

    calculateR(No1, No2, Multiplier, Result) :-
        atom_concat(No1, No2, NewNoAtom),
        atom_number(NewNoAtom, NewNo),
        Result is NewNo * Multiplier.
    

    Usage example:

    ?- calculateR(5, 1, 3, X).
    X = 153.
    

    Of course, you'll need more if you want to prompt the user for input.

    I expect @Wouter Beek's answer is more efficient, since it doesn't rely on converting the numbers to and from atoms, but just uses the assumption that each numeral is a single digit to determine the resulting number based on their position. E.g., if 5 is in the 10s place and 1 is in the 1s place, then the combination of 5 and 1 will be 5 * 10 + 1 * 1. The answer I suggest here will work with multiple digit numerals, e.g., in calculateR(12, 345, 3, Result), Result is 1234 * 3. Depending on what you're after this may or may not be a desired result.