2014-11-20 60 views
1

我想做一个谓词返回一个数字分隔符的列表。 示例:72 = 2 * 2 * 2 * 3 * 3。序言:除数

prdel(A,[],_):- 
     A is 1. 
prdel(P,[D|L],D):- 
     0 is mod(P,D), 
     P1 is P/D, 
     prdel(P1,L,D). 
prdel(P,L,D):- 
     D1 is D+1, 
     prdel(P,L,D1). 

这个工作并返回正确的列表。问题在于它不会在那之后停止,但是如果我按下空格,会一遍又一遍地返回相同的列表(我很抱歉,当您使用相同的谓词来获得不同的答案时,我不知道英语中的术语)。我希望它在第一次后停止。

我试图编辑最后那个样子,

prdel(P,L,D):- 
     D1 is D+1, 
     D1<P, 
     prdel(P,L,D1). 

,但现在它只返回错误,而不是名单。

编辑:

我正在寻找一个没有削减的答案。

+0

'使用相同的谓词来获得不同的答案':通过解决方案回溯 – CapelliC 2014-11-20 22:12:00

回答

1

代码中的一个问题是,即使明确划分不会成功,因为D过高,它仍会继续尝试将P除以D。这使D“没有限制地逃跑”。

添加支票D1为低于或等于P修复了这个问题:

prdel(1,[],_). 

prdel(P,[D|L],D):- 
     0 is mod(P,D), 
     P1 is P/D, 
     prdel(P1,L,D). 

prdel(P,L,D):- 
     D1 is D+1, 
     D1 =< P, 
     prdel(P,L,D1). 

这产生约数的所有组合,包括非原酮(demo)。

[[2, 2, 2, 3, 3], [2, 2, 2, 9], [2, 2, 3, 6], 
[2, 2, 18], [2, 3, 3, 4], [2, 3, 12], [2, 4, 9], 
[2, 6, 6], [2, 36], [3, 3, 8], [3, 4, 6], [3, 24], 
[4, 18], [6, 12], [8, 9], [72]] 

如果你不希望出现这种情况,加上一条,mod(P,D) > 0最后子句中:

prdel(1,[],_). 

prdel(P,[D|L],D):- 
    0 is mod(P,D), 
    P1 is P/D, 
    prdel(P1,L,D). 

prdel(P,L,D):- 
    mod(P,D) > 0, 
    D1 is D+1, 
    D1 =< P, 
    prdel(P,L,D1). 

这仅产生[2, 2, 2, 3, 3]demo)。

+0

非常感谢您,因此我必须检查以下或相等,但不仅限于以下内容。 – chnging 2014-11-20 19:40:10

+0

@ chnging是的,否则你永远不会达到基础子句(除非你以'P'开始等于'1')。 – dasblinkenlight 2014-11-20 19:42:15