【问题标题】:Prolog - Multiply the even elements of a list by a number (F)Prolog - 将列表的偶数元素乘以数字(F)
【发布时间】:2021-10-24 05:52:26
【问题描述】:

我正在使用 Prolog 编程,从任何给定的数字 (F) 开始,将列表的偶数元素相乘;保留那些不是的值,开发了以下内容,实际上程序“编译”没有任何错误,但是在输入值时它只返回“false”,我哪里错了?:

% base case
evenproduct(_,[],[]) :- !.

% recursive case
evenproduct(F,[X|Xs], [Y|Ys]) :-
   Y is F*X,
   X mod 2 =:= 0,
   evenproduct(F, Xs, Ys), !.

谢谢!!

【问题讨论】:

  • 当一个值失败时,整个谓词失败,因此递归失败。当条件失败时,您需要另一个递归案例来跳过添加值。还可以考虑重新设计谓词,使守卫位于谓词的开头。
  • 由于这是一个过滤列表问题,请使用此 SO 查询查看相关答案[prolog] filter list is:answer
  • 很可能这是一个重复的问题,但要搜索的答案太多,无法找到重复的问题。

标签: list prolog


【解决方案1】:

您不应该使用削减(! 目标)。 Cuts 是一个高级的 Prolog 概念,只有在您是更高级的 Prolog 程序员时才有用。在此之前,削减只会让你感到困惑。此外,削减通常不会使您的程序更频繁地成功,但它们会使它更频繁地失败。您的问题是您的程序经常失败!削减可能是您的问题的一部分。

另外,你的程序总是返回 false 也不完全正确。看,它确实适用于某些输入:

?- evenproduct(3, [2, 4, 6], Ys).
Ys = [6, 12, 18].

也就是说,如果给定的列表只包含偶数,那么您的程序将完全按照预期运行。到目前为止做得很好!

您现在需要做的是,在列表中的一个数字是奇数的情况下也使此操作成功。让 Prolog 程序更频繁地成功的一种主要方法是:向某个谓词添加更多子句。

到目前为止,您对evenproduct/3 的定义有两个子句。到目前为止,您看到的所有列表处理谓词可能总是正好有两个子句,一个用于“基本情况”,一个用于“递归情况”。但是有几个非递归或几个递归子句是完全可以的,而且通常是非常必要的。在您的情况下,您可以将以下子句添加到您的程序中以使其工作:

evenproduct(F,[X|Xs], [Y|Ys]) :-
   Y = X,
   X mod 2 =:= 1,
   evenproduct(F, Xs, Ys).

所以现在您总共将有 三个 子句,一个非递归子句和两个递归子句。

现在也接受奇数:

?- evenproduct(3, [1, 2, 3, 7, 11, 22], Ys).
Ys = [1, 6, 3, 7, 11, 66] ;
false.

【讨论】:

  • Isabelle @isabelle-newbie 非常感谢你,你的解释很精彩,现在我更清楚了一些递归概念,再次感谢。
  • 您应该在这里真正展示您的更优越的封闭式解决方案,至少作为替代方案,因为另一个问题已作为该问题的重复而关闭,并且该答案已被接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 2016-05-23
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多