我如何 return 给定列表中的数字列表 mod 0 目标数字?

How can I return a list of numbers from a given list that mod 0 a target number?

在我的函数 modded(X,Y,Z) 中,根据给定的数字 Y 和给定的数字列表 Z 生成一个列表。我想要做的是为每个数字遍历列表 Z它的值,看看列表中的当前值是否会干净地除以 Y,(Y/Zz == 0)。我对如何访问每个 Z 的值有点困惑,因为 Prolog 没有传统的迭代器。

预期的行为是将 (X,16,[2,3,4,5,7,8]) 修改为 return [2,4,8] 的列表。只允许完整的除数。

modded([],Y,Z):-
    % X is the generated list, Y is the number, Z is a list of given numbers.
    %Base case: Z is empty
    Z =:= [],
    X =:= Z.

modded([Zz|T],Y,[H|T]):-
    %Recursive is Y > 1, Zz is an element of Z
    0 is Y mod Zz,
    Y =< Z - 1,
    Zz is Z + 1,
    % Want to add to a if Y mod Zz == 0
    modded(T,Y,Zz).
modded([], _, []).

modded([Zz|T], Y, [Zz|Z]) :- % Case where Zz is a divisor of Y.
    0 =:= Y mod Zz,
    modded(T, Y, Z).

modded(T, Y, [Zz|Z]) :- % Case where Zz is not a divisor of Y.
    0 =\= Y mod Zz,
    modded(T, Y, Z).

然后

?- modded(X,16,[2,3,4,5,7,8]).
X = [2, 4, 8]

基本情况适用于输入和输出的空列表。

如果 Zz 是除数并添加到结果列表 [Zz|T] 中,则中间情况成立。

如果 Zz 不是除数且未添加到结果列表 T,则最后一种情况成立。

两种计算情况都递归剩余的 Z 列表以填充剩余的结果 T。


如果你不是被迫使用递归,你可以这样写:

modded(X, Y, Z) :-
    findall(Zz, (member(Zz, Z), 0 =:= Y mod Zz), X).

“找到所有Z的成员和Y的约数的Zz,并将它们存储在X中”。

num_divisor(Y, Zz) :-
    0 =:= Y mod Zz.

modded(X, Y, Z) :-
    include(num_divisor(Y), Z, X).

您可能需要听到但可能不会关心的评论:

如果您使用的是 SWI Prolog,那么 https://swish.swi-prolog.org/ 是一个出色的工具,您可以在没有 edit/saving/reload 的情况下立即尝试一些代码。尝试将您的一些代码放入其中:

Z =:= []
Type error: `evaluable' expected, found `[]' (an empty_list)

那条线永远行不通。下一行也不是:

X =:= Z.
Arguments are not sufficiently instantiated
In:
   [1] _1722=:=_1724

modded([Zz|T],Y,[H|T]) 行中,通过在那些地方使用 T,您是说两个列表的尾部必须相同。这些列表之一是输入,一个是过滤后的输出。那不行。

0 is Y mod Zz 行说 Zz 除 Y。modded 的参数不应该是(结果、数字、输入)吗?所以 modded([Zz|T],Y,[H|T]) 不会是 H 分成 Y,而不是 Zz 还没有价值吗?

0 is Y mod Zz 行中它说 Zz 除以 Y。但是如果它确实有效并且输入到达 3 则该行将是错误的,因为 3 不能平均除以 16,所以整个程序会失败。如果数字不是除数,则无法处理该怎么做。

Y =< Z - 1 也不像其他语言那样工作,=< 不会计算 Z - 1。这几乎是幸运的,因为 Z 在代码中没有值。 (即使它有,你不是说它是输入列表吗? Y =< [2,3,4,5,7,8] - 1 会是什么?)

Zz is Z + 1 Z 在这里也没有值,但如果它有它就会失败,因为 Zz 在顶部与 modded([Zz 绑定并且它 modded(T,Y,Zz) 不是输入列表 modded 的最后一个参数,为什么它现在是除数?第一个参数是结果,现在是输入列表的尾部?

是的,你很困惑,你需要先熟悉基础知识,然后再尝试构建它们。

Unification and proof search

Recursing down lists 在 LearnPrologNow。