2015-04-03 18 views
1

我想写一个规则,可以返回两个列表(相同长度)的每个元素的乘积的总和。Prolog:将其中的1个列表乘以2列表未实例化?

这是我现在所拥有的:

sum(0, _, []). 
sum(Result, [H1|T1], [H2|T2]) :- 
    sum(Remaining,T1, T2), 
    Remaining is Result - (H1*H2). 

时不会被实例化的列表中一个它不会工作。为了做到以下几点,我需要做出什么样的改变?

sum([1,2],X,3). 
X = [3,0]. 

谢谢。

+1

我想'X = [1,1]'在你的例子中也是正确的答案。你想让它产生所有答案吗?或者你有其他约束?基于这个例子,我假设你只处理非负整数?你没有说。这是一项任务吗?你可以使用CLPFD库吗?这将是处理这个问题的自然方法。 – lurker 2015-04-03 01:06:23

+0

@lurker是的,它应该产生所有答案与非原生整数输入。它来自任务,因此我不能使用任何库。谢谢。 – Pig 2015-04-03 01:27:43

回答

3

您正在计算的内容通常被称为dot product(也称为标量产品或内积)。

你写你不允许使用库。这肯定是指外部库---不是标准库是SWI Prolog的一部分,对不对?

以下谓词list_list_dotProduct/3大致对应于您实施的代码。它采用有限域约束(#>=)/2(#=)/2允许非单向整数运算:

:- use_module(library(clpfd)). 

list_list_dotProduct([],[],0). 
list_list_dotProduct([X|Xs],[Y|Ys],Sum) :- 
    X #>= 0, 
    Y #>= 0, 
    Sum #= X*Y + Sum0, 
    list_list_dotProduct(Xs,Ys,Sum0). 

考虑下面的查询:

?- list_list_dotProduct([1,2],Xs,3), label(Xs). 
Xs = [1, 1] ; 
Xs = [3, 0]. 

作为一个额外的好处,这里是一个替代实现即基于预定义的谓词same_length/2,ins/2scalar_product/4

list_list_dotProduct(Xs,Ys,Prod) :- 
    same_length(Xs,Ys), 
    Xs ins 0..sup, 
    Ys ins 0..sup, 
    scalar_product(Xs,Ys,#=,Prod). 
+4

很棒的回答。过去一周左右,这个问题出现了大量的变化。仍然不清楚是否有人明确禁止使用像clp(fd)这样的图书馆,或者学生是否被误解。班上的老师让学生如此措手不及,这也有点令人伤心。 – 2015-04-03 06:57:59

+3

你会惊讶地发现Prolog在某些高等教育机构中的教学效果如何。如此糟糕,以至于说“有一种叫做Prolog的语言,谷歌它”并将它留在那里会更好。严重的教学只会造成损害。 – 2015-04-03 07:54:40

+2

伟大的解决方案,+1!请注意,虽然'scalar_product/4'需要第一个参数,所以当第一个参数包含变量时,第二个版本的list_list_dotProduct/3将不起作用,例如:??list_list_dotProduct ([X,Y],[1,2],Prod).'。在这种情况下,您的初始版本也能按预期工作。我也强烈建议CLP(FD)限制这类问题。我认为需要CLP(FD)的人不需要在这种情况下使用“需要使用Prolog而不使用Prolog”。 – mat 2015-04-03 22:58:21