Search code examples
prolog

Multiplication of two tables in Prolog


I am trying to create a prolog function that gets a two table multiplication .

My code is currently as follows:

mult(L1,L2,L). So for example I would like a query such as:

?- mult([x,x],[x,x,x],R). To display something like:

R=[x,x,x,x,x,x] how could I fix my code?

i tried with recusion ,but didn't know how to implement it.


Solution

  • I would write:

    mult(Ls, Rs, Answer) :-
        findall(X, (member(L, Ls),
                    member(R, Rs),
                    X is L * R),
                Answer).
    

    e.g.

    ?- mult([10,100], [1,2,3], Answer).
    Answer = [10, 20, 30, 100, 200, 300]
    

    but you are probably supposed to use recursion, so:

    % Multiply a list of numbers R(ight)s, each by
    % one integer L from the original L(eft)s list
    mult_row([], _, []).
    mult_row([R|Rs], L, [Product|RowAnswers]) :-
        Product is L * R,
        mult_row(Rs, L, RowAnswers).
    
    % Multiply two lists of integers L(eft)s and R(ight)s
    mult([], _, []).
    mult([L|Ls], Rs, Answers) :-
        mult_row(Rs, L, As1),
        mult(Ls, Rs, As2),
        flatten([As1, As2], Answers).
    

    e.g.

    ?- mult([10,100,1000], [1,2,3], Answers).
    Answers = [10, 20, 30, 100, 200, 300, 1000, 2000, 3000]
    

    To multiply [10,100,1000] * [1,2,3] it does this:

    • Take the first number from the left list (10)

    • calls mult_row to calculate (10 * 1,2,3)

    • that makes a list of [10, 20, 30] into As1.

    • Then the remaining [100, 1000] go through this from the start (recursion).

    • Take the first number from the left list (100)

    • calls mult_row to calculate (100 * 1,2,3)

    • that makes a list of [100, 200, 300] into (a new variable) As1.

    • Then the remaining [1000] go through this from the start (recursion).

    • Take the first number from the left list (1000)

    • calls mult_row to calculate (1000 * 1,2,3)

    • that makes a list of [1000, 2000, 3000] into (a new variable) As1.

    • Then the remaining [] go through this from the start (recursion).

    • Take the first number from the left list ([] - empty)

    • flatten [[1000, 2000, 3000], []] into Answers [1000, 2000, 3000]

    • finish [[100, 200, 300], [1000, 2000, 3000]] into (a new variable) Answers. [100, 200, 300, 1000, 2000, 3000]

    • finish [[10, 20, 30], [100, 200, 300], [1000, 2000, 3000]] into (a new variable) answers with the final answer.

    • finish.

    And the call to mult_row does the same pattern; a recursive walk over the list, multiplying 10x1, 10x2, 10x3 into an answer list, for each row.