在prolog中实现一个名为;stepWith";,这需要三个参数,一个列表L和两个整数i和j

在prolog中实现一个名为;stepWith";,这需要三个参数,一个列表L和两个整数i和j,prolog,Prolog,实现一个名为“stepWith”的规则,该规则包含三个参数, 一个列表L和两个整数i和j。如果 值i可以“步进”到值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 number

实现一个名为“stepWith”的规则,该规则包含三个参数, 一个列表L和两个整数i和j。如果 值i可以“步进”到值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。我需要它遍历每个元素,找到得到给定值的组合

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).

我不太明白你为什么要引入
goThrough
谓词

如果没有这一点,您几乎可以得到解决方案,只需纠正两件事:

  • 步骤(A,0)适用于您得到的任何A,而不仅仅是空列表(因为您描述的规则,当您达到0时,是否有一些数字您没有尝试过并不重要)
  • 以两种方式递归步骤,只传递
    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:-)。

您的问题不是针对SWI的,因此不要使用该标签。