Prolog 中的算术 - 数字的倍数
Arithmetic in Prolog - Multiples of a number
我想创建一个函数 multiples(X, N, R)
,其中 R
是一个列表,其中包含从 X
到 X * N
的所有 X
的倍数。
一个例子是:multiples(3, 4, [12, 9, 6, 3])
,它应该给出 true。
到目前为止我的代码:
multiples(X, N, R) :- X >= 1, N >= 1, Z is X*N, contains(Z, R).
contains(Z, [Z|_]).
contains(Z, [W|V]) :- contains(Z,V), L is Z-X, L >= X, contains(L, V).
multiples(3,4,X).
的控制台输出是 X = [12|_xxxx]
,当我键入 ;
时发生错误。
我如何设法收到我想要的列表?
(也许我的想法是完全错误的)。
对您的代码稍作修改。 contains predicate
会收集一个列表中的数字,N会不断递减,直到满足基本谓词。
multiples(X, N, R) :- X >= 1, N >= 1, contains(X,N, R),!.
contains(_,0,[]).
contains(X,N,[Z|List]):-
Z is X*N,
N1 is N-1,
contains(X,N1,List).
示例:
?- multiples(3,4,R).
R = [12, 9, 6, 3]
?- multiples(2,5,R).
R = [10, 8, 6, 4, 2]
?- multiples(25,5,R).
R = [125, 100, 75, 50, 25]
我发现您的代码有 4 个问题。这是固定代码,解释如下:
multiples(X, N, R) :-
X >= 1,
N >= 1,
Z is X*N,
contains(X, Z, R).
contains(X, Z, [Z|V]) :-
L is Z-X,
L >= X,
contains(X, L, V).
contains(_, Z, [Z]).
?- multiples(3,4,X).
X = [12, 9, 6, 3] ;
X = [12, 9, 6] ;
X = [12, 9] ;
X = [12] ;
false.
首先,在您的 contains
谓词中,您访问 X
和 W
并且从不声明它们的值。通过向谓词添加另一个属性来解决 X
。通过将其替换为 Z
.
来解决 W
另一个问题是规则的顺序。较大的 contains
规则应该是“主要”规则,只有当这个规则失败时,另一个才应该“触发”。通过将默认规则置于顶部,您将获得正确的结果。
规则 contains(_, Z, [Z]).
也标记结束,因此 return 列表中只有元素 Z
,不包含任何其他(未知)元素。
最后一点是您不需要在 contains
主规则中调用两次 contains
。
该示例适用于第一个答案。但是,您可以通过剪切 (!
) 来改进这一点,这会阻止在成功访问第一条规则后转到第二条规则:
contains(X, Z, [Z|V]) :-
L is Z-X,
L >= X,
!,
contains(X, L, V).
contains(_, Z, [Z]).
?- multiples(3,4,X).
X = [12, 9, 6, 3].
我想创建一个函数 multiples(X, N, R)
,其中 R
是一个列表,其中包含从 X
到 X * N
的所有 X
的倍数。
一个例子是:multiples(3, 4, [12, 9, 6, 3])
,它应该给出 true。
到目前为止我的代码:
multiples(X, N, R) :- X >= 1, N >= 1, Z is X*N, contains(Z, R).
contains(Z, [Z|_]).
contains(Z, [W|V]) :- contains(Z,V), L is Z-X, L >= X, contains(L, V).
multiples(3,4,X).
的控制台输出是 X = [12|_xxxx]
,当我键入 ;
时发生错误。
我如何设法收到我想要的列表?
(也许我的想法是完全错误的)。
对您的代码稍作修改。 contains predicate
会收集一个列表中的数字,N会不断递减,直到满足基本谓词。
multiples(X, N, R) :- X >= 1, N >= 1, contains(X,N, R),!.
contains(_,0,[]).
contains(X,N,[Z|List]):-
Z is X*N,
N1 is N-1,
contains(X,N1,List).
示例:
?- multiples(3,4,R).
R = [12, 9, 6, 3]
?- multiples(2,5,R).
R = [10, 8, 6, 4, 2]
?- multiples(25,5,R).
R = [125, 100, 75, 50, 25]
我发现您的代码有 4 个问题。这是固定代码,解释如下:
multiples(X, N, R) :-
X >= 1,
N >= 1,
Z is X*N,
contains(X, Z, R).
contains(X, Z, [Z|V]) :-
L is Z-X,
L >= X,
contains(X, L, V).
contains(_, Z, [Z]).
?- multiples(3,4,X).
X = [12, 9, 6, 3] ;
X = [12, 9, 6] ;
X = [12, 9] ;
X = [12] ;
false.
首先,在您的 contains
谓词中,您访问 X
和 W
并且从不声明它们的值。通过向谓词添加另一个属性来解决 X
。通过将其替换为 Z
.
W
另一个问题是规则的顺序。较大的 contains
规则应该是“主要”规则,只有当这个规则失败时,另一个才应该“触发”。通过将默认规则置于顶部,您将获得正确的结果。
规则 contains(_, Z, [Z]).
也标记结束,因此 return 列表中只有元素 Z
,不包含任何其他(未知)元素。
最后一点是您不需要在 contains
主规则中调用两次 contains
。
该示例适用于第一个答案。但是,您可以通过剪切 (!
) 来改进这一点,这会阻止在成功访问第一条规则后转到第二条规则:
contains(X, Z, [Z|V]) :-
L is Z-X,
L >= X,
!,
contains(X, L, V).
contains(_, Z, [Z]).
?- multiples(3,4,X).
X = [12, 9, 6, 3].