Prolog 代码,可达到总和为目标的数字组合

Prolog Code that reachs a combination of numbers that sums up to a goal

我找到了这段代码,我只需要了解它的想法以及它是如何工作的。 它输出一个数字列表,总和为特定数字(目标)

示例 运行:

?- threeSum([3,8,9,10,12,14],27,Output).
   Output = [3, 10, 14] ;
   Output = [8, 9, 10] ;
   false.

代码如下:

threeSum([H|T], Goal, Output):-
    solve(Goal,[H|T],Output).

subset([], []).
subset([H|T], [H|T1]):-
  subset(T,T1).
subset([_|T],T1):-
  subset(T, T1).

solve(MaxVal,Lin,Lout):-
    subset(Lin,Lout),
    sumlist(Lout,Val),
    Val = MaxVal.

subset/2 有三种不同的情况:

  1. subset([], []).

    基本情况:如果输入列表为空,它returns也是一个空列表

  2. subset([H|T], [H|T1]):- subset(T,T1).

    (如果列表不为空则默认选择这种情况):设置输出列表的第一个元素等于输入列表的第一个元素。然后递归计算列表的尾部。

  3. subset([_|T],T1) :- subset(T, T1).

    选择这种情况,如果大写字母以某种方式失败:忽略输入列表的头部元素,并再次递归计算尾部。

solve/3的最后一部分只是将Lout的值相加,与目标值进行比较,如果失败则回溯,即尝试为[=10]寻找另一个解决方案=].

首先选择subset/2的第二种情况,直到输入列表为空。 所以在solve/3中的第一个subset([3,8,9,10,12,14], Lout)之后,Lout就变成了[3,8,9,10,12,14]。 这个列表的总和不等于MaxVal,所以失败,开始回溯。 现在最后一次调用带有选择点的 subset/3,即 subset([14], Lout) 失败,因此调用了 subset/3 的第三种情况。 因此,在第一个回溯步骤之后,subset([3,8,9,10,12,14], Lout) 中的 Lout 的值现在是 [3,8,9,10,12]。 这又不等于 MaxVal 并且开始下一个回溯。 这一直持续到 Val = MaxVal 为真。