0
votes

Want to expand the argument q(M,N):- that should evaluate true , only if we can express M as sum of two numbers , that also these same two numbers would give the the product of N. Meaning something like A+B=M and A*B=N (M,N>0 both Integers)

So I've tried something like :

sum(A,B,M) :- M is A+B.

prod(A,B,N) :- N is A*B.

q(M,N) :- sum(A,B,M),
          prod(A,B,N).

But yeah not a great plan.

some expected outcomes should be:

| ?- q(18,45).
yes
| ?- q(45,18).
no
| ?- q(4,4).
yes
| ?- q(5,5).
no
| ?- q(16,64).
yes
| ?- q(12,25).
no
| ?- q(25,24).
yes
| ?- q(36,120).
no
| ?- q(100,2499).
yes
| ?- q(100,267).
no
| ?- q(653,98770).
yes
| ?- q(653,98880).
no
1
You should apecify the range of A and B. You can use clpfd library to do thisdamianodamiano
both A and B Integers >0 yes , from the test questions in the end you can seeKevinWendellCrumb

1 Answers

0
votes

A very basic solution for your problem, using between/3 from swi prolog, without heavilly modifing your program is:

sum(A,B,M) :- M is A+B.

prod(A,B,N) :- N is A*B.

q(M,N) :- 
    between(0,1000,A),
    between(0,1000,B),
    sum(A,B,M),
    prod(A,B,N).

In this case, all numbers between 0 and 1000 are considered for A and B. However, there are some weakness. For instance, values for A and B can be exchanged (q(18,45) succeeds for A = 3 and B = 15 and A = 15 and B = 3). To remove this redundancy you can impose B < A. To further improve the algorithm, you can set a range for A and B based on the value of the sum and the product. Certainly both A and B must be less than the value M in your code. Like:

q(M,N) :- 
    between(0,M,A),
    between(0,A,B),
    M is A+B,
    N is A*B.

You can add further constraints to improve the performances, for instance considering cases where the product is 0 etc...

You can use also clpfd library to solve this problem.