Prolog - 将列表与未实例化的列表相乘

Prolog - Multiplying A list with an uninstantiated list

此谓词的输入是 S、整数列表 I 和整数列表 T。假设 S 和 I 都已完全实例化,但不是 T。该函数将 I 中的第一个元素相乘用 T 中的第一个元素然后将它与 I 中的第二个元素相乘乘以 [...] 你明白了。但是,我遇到的困难是在 T 未实例化时使该函数成功。我不想使用 use_module(library(clpfd)),尽管它可能更容易。 作为帮手,我已经有了可以正确繁殖的东西。为了摆脱 "uninstantiated variable" 问题,我想我让一个变量 = S div 成为 I 的头部,所以我会实例化一个新变量,并且我会为列表 I 中的每个项目执行此操作。然后我会生成所有排列,使得列表中项目的乘法总和为 S

mult_prod(A, B, S) :-
    sum_prod(A, B, 0, S).
mult_prod([A | As], [B | Bs], Accum, S) :-
    Accum1 is Accum + A*B,
    mult_prod(As, Bs, Accum1, S).
mult_prod([], [], Accum, Accum).


multSum(S, I, T) :- 

我天真的解决方案:

multSum(0, [], []).
multSum(S, [I | Is], [T | Ts]) :-
    between(0, S, T),
    S1 is S - I * T,
    multSum(S1, Is, Ts).

示例输出:

?- multSum(42, [6, 7, 8, 9], T).
T = [0, 0, 3, 2] ;
T = [0, 1, 1, 3] ;
T = [0, 6, 0, 0] ;
T = [1, 0, 0, 4] ;
T = [1, 4, 1, 0] ;
T = [2, 2, 2, 0] ;
T = [2, 3, 0, 1] ;
T = [3, 0, 3, 0] ;
T = [3, 1, 1, 1] ;
T = [4, 0, 0, 2] ;
T = [7, 0, 0, 0] ;
false.

潜在问题:

  • 这太简单了;我一定是忽略了您问题中的某些内容或完全误解了它。
  • 仅在 SWI Prolog 中测试;依赖于 between/3. If necessary, you can implement this predicate yourself.
  • 限于非负数。
  • 穷举所有的可能性,可以说是相当多了
  • 可能不是最有效的实施方式...