在Prolog中找到主要因素

时间:2019-03-02 16:08:14

标签: prolog primes

prime_factors(N, [_:_]) :- prime_factors(N, [_:_], 2).

prime_factors(N, [_:_], D) :- N mod D == 0,  N1 is N div D, 
                          prime_factors(N1, [_:D], D).

prime_factors(N, [_:_], D) :- N mod D =\= 0, D1 is D+1, prime_factors(N, [_:_], D1).

这是我提出的用于找到输入N的素因数的解决方案。

当我尝试运行它时,遇到这样的谓词/ 2不存在的错误-扩展谓词/ 3的语法是否有误?

1 个答案:

答案 0 :(得分:4)

使用似乎仅在第二种情况下是统一的第二个参数似乎没有多大意义。而且,无论如何,这都不是您在Prolog中构造列表的方式,因为:

  1. “ cons”的语法为[H|T],因此应为[_|_];
  2. 通过使用下划线,谓词对值不感兴趣,您每次都传递其他参数;和 在Prolog中,
  3. 通常不使用答案构建列表,通常使用回溯。以后可以使用findall/3来构造列表。通常这样做会更好,因为这意味着我们也可以像prime_factor(1425, 3)一样查询以检查3是否是1425的主要因素。

因此,我们可以构建一个类似于以下内容的谓词:

prime_factor(N, D) :-
    find_prime_factor(N, 2, D).

find_prime_factor(N, D, D) :-
    0 is N mod D.
find_prime_factor(N, D, R) :-
    D < N,
    (0 is N mod D
    -> (N1 is N/D, find_prime_factor(N1, D, R))
    ;  (D1 is D + 1, find_prime_factor(N, D1, R))
    ).

例如:

?- prime_factor(1425, R).
R = 3 ;
R = 5 ;
R = 5 ;
R = 19 ;
false.

?- prime_factor(1724, R).
R = 2 ;
R = 2 ;
R = 431 ;
false.

如果我们需要所有主要因素的列表,可以为此使用findall/3

prime_factors(N, L) :-
    findall(D, prime_factor(N, D), L).

例如:

?- prime_factors(1425, R).
R = [3, 5, 5, 19].

?- prime_factors(1724, R).
R = [2, 2, 431].

?- prime_factors(14, R).
R = [2, 7].

?- prime_factors(13, R).
R = [13].