在prolog中实现一个名为“stepWith”的规则,它接受三个参数,一个列表L和两个整数i和j

时间:2015-05-16 23:01:37

标签: prolog

实现一个名为“stepWith”的规则,它带有三个参数,        列表L和两个整数i和j。如果是,则规则返回true        价值我可以“步入”到价值j,只使用合法的“步骤”。        列表L提供了一组构成法律步骤的整数。

   For example, stepWith([7,12,19],6,32) would return true, because,
   starting at 6, there exists at least one sequence of additions using
   only the numbers in the list (7, 3, and 12), producing 28.  Namely:
   6+7+7+12 = 32.

   By contrast, stepWith([7,12,19],6,31) would be an example that should
   return false, since there is no sequence of additions starting from 6,
   and using only the values 7, 12, and 19, that results in 31.

   Make sure that your rule works for various values, and various size
   lists for L.  You can assume that all of the integers are positive,
   and that i is less than j.

 *** CLARIFICATION ***

   The value i, in the above description, can only be included in
   the addition once, at the very beginning.  The numbers in the 
   list L can be used as many times as necessary (or zero times).

这是我到目前为止所做的,但它只是通过列表的第一个元素并减去它直到它达到0.我需要它遍历每个元素以找到获得给定值的组合。 / p>

stepWith(L,I,J) :- Z is J-I, step(L,Z).

step([F|L],Z) :- N1 is Z - F, goThrough(N1,L).
step([],0).

goThrough(X,[X|Y]).
goThrough(X,[M|N]) :- goThrough(X,N).

1 个答案:

答案 0 :(得分:1)

我不太明白为什么要引用goThrough谓词。

如果没有这个,你几乎得到了解决方案,只需要纠正两件事:

  • 步骤(A,0)对于你获得的任何A都是正确的,不仅是空列表(因为你描述的规则,当你达到0时,如果有一些数字你没有尝试过并不重要。)< / LI>
  • 以两种方式递归步骤:仅传递L,然后传递[F|L],这意味着如果您尝试了一个号码,则不再使用它,或者您可以使用它更多次。

这是一个可能的解决方案:

stepWith(L,I,J) :- Z is J-I, step(L,Z).

step(_,0).
step([F|L],Z) :- Z > 0, step(L,Z).
step([F|L],Z) :- Z > 0, Z1 is Z-F, step([F|L],Z1).

请注意,我还添加了Z > 0以保证通用终止。如果删除Z > 0,则谓词的顺序变得很重要,如果在递归规则之后移动基本情况,则可以获得非终止行为。 (作为练习,尝试删除它并自我实验,因为无论如何你正在学习Prolog: - ))。