论点-简单的序言

时间:2019-05-27 11:36:17

标签: prolog

仅在以下情况下想扩展应为true的参数q(M,N):- 我们可以将M表示为两个数字的和,这两个相同的数字也将得到N的乘积。表示类似A+B=MA*B=NM,N>0都是整数)

所以我尝试了类似的事情:

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).

但是,不是一个好计划。

一些预期结果应该是:

| ?- 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 个答案:

答案 0 :(得分:0)

使用swi prolog中的between/3而无需费力修改程序的非常基本解决方案是:

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).

在这种情况下,01000的所有数字在AB之间。但是,存在一些弱点。例如,可以交换AB的值(q(18,45)成功用于A = 3B = 15以及A = 15B = 3 )。要删除此冗余,您可以使用B < A。为了进一步改进算法,您可以根据总和值和乘积为A和B设置范围。当然,AB都必须小于代码中的值M。喜欢:

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

您可以添加更多约束来提高性能,例如考虑乘积为0等的情况。

您也可以使用clpfd library来解决此问题。