2015-03-31 29 views
3

该谓词的输入是S,整数列表I和整数列表T.假设是S和I都被完全实例化,但不是T.函数将I中的第一个元素与T中的第一个元素相乘,然后与I中的第二个元素相加,得到这个想法。然而,我遇到的困难是当T没有被实例化时,使这个函数成功。即使可能更容易,我也不想使用use_module(library(clpfd))。 我已经有一些东西可以正确乘法,作为帮手。为了摆脱“无实际意义的变量”问题,我想我让一个变量= S div的头,所以我会实例化一个新变量,并且我会为列表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) :- 
+2

停止打电话给他们的功能,他们不是:)但实际上,Prolog的谓词是不是一个函数。再一次,你甚至没有表现出自己试图解决它。你至少可以尝试一下,对吧?否则,这个问题看起来像懒惰的教授给学生的那些“填补空白”之一。 – 2015-03-31 06:43:08

+0

这不适用于学校。这完全是为了我的学习。我同意我至少应该尝试一些事情,事实上,我确实尝试了一些:)我写了mult_prod,它实际上解决了这个问题。但是,当我没有证据时,它不起作用,因为我得到了无关变量的投诉。 – 2015-03-31 15:44:27

+0

好吧鲍里斯。我其实写代码,但它变得一团糟。然而,为了摆脱“无实际意义的变量”问题,我想我让一个变量= S div的头,所以我会实例化一个新变量,并且我会为列表I中的每个项目执行此操作。然后, d生成所有排列,使列表中的项目相乘的结果总和为S. – 2015-03-31 17:48:18

回答

1

我天真的解决方案:

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。如有必要,您可以implement this predicate yourself
  • 限于非负数。
  • 彻底地产生所有可能性,这可能是相当多的。
  • 可能不是最有效的实现可能的...
+0

负整数怎么样? – mat 2015-04-08 21:34:34

+0

@mat允许正整数和负整数都会导致无限数量的组合,除非我们同意某些(任意)边界。例如:'multSum(3,[1,-1],T)'应该由'T = [X,X-3]'满足_every_整数X.同样,'multSum(3,[1,1], T)'产生'T = [X,3-X]'。 – 2015-04-09 09:40:22