我要做的是,写一个谓词乘法/ 3,其第一个参数是一个整数,第二个参数是一个列表,第三个参数是整数与列表相乘的结果,例如:
- 乘法(3,[2,7,4],结果)。
应该返回
结果= [6,21,12]。
这是我的代码:
Multiplication(X,[],Result).
Multiplication(X,[Head|Tail],Result) :-
Y is X*Head,
append([Result], [Y], L),
append([],L,Result), // HERE
Multiplication(X,Tail,Result).
我收到以下错误:
第二次追加电话域错误:'acyclic_term'预期,找到'@(列表:追加([],S_1,S_1),[S_1 = [S_1,1]])'
。
如果有人知道我收到错误的原因,如何解决或以其他方式解决这个问题,我愿意接受这些想法。
答案 0 :(得分:3)
您的两个目标append([Result], [Y], L), append([],L,Result)
与以下内容完全相同:
L = [Result,Y], L = Result.
甚至更简单:
L = [L,Y]
会导致无声失败或无限期。相反,您的Prolog会产生错误,以便您可以更正您的程序。
答案 1 :(得分:2)
在原始代码中:
Multiplication(X,[Head|Tail],Result) :-
Y is X*Head,
append([Result], [Y], L),
append([],L,Result), // HERE
Multiplication(X,Tail,Result).
你正在进行一个"周期"因为您要将Result
附加到要获取L
的内容,然后向L
添加内容以获取Result
。那不好。您还有一个大写的谓词名称,这是一个语法错误。 (我认为,既然您运行了代码,它在原始版本中没有大写。)
您提出的新解决方案过于复杂。你为什么需要第四个论点?另外,return
的基本情况(return(X, [], Result)
没有意义,因为它必须使用单例变量。使用append/3
是过度的,因为递归处理迭代列表元素。
从顶部开始,您在Prolog中有一个共同模式,您希望在两个或多个列表的相应元素上运行查询。一个简单的递归解决方案看起来像这样:
multiplication(_, [], []). % Multiplying anything by the empty list is the empty list
multiplication(M, [X|Xs], [XX|XXs]) :-
XX is M * X,
multiplication(M, Xs, XXs).
在Prolog中实现此类模式的另一种方法是使用maplist/3
。您可以先在相应的元素上定义查询:
multiply(X, Y, Product) :- Product is X * Y.
然后使用maplist/3
:
multiplication(M, List, Result) :-
maplist(multiply(M), List, Result).
Maplist
会对call(multiply(M), ...)
和List
的每对相应元素执行Result
。
答案 2 :(得分:0)
我编辑了代码并想出了这个:
multiplication(X,[],Result,Result).
multiplication(X,[Head|Tail],List,Result) :-
Y is X*Head,
append(List, [Y], L),
multiplication(X,Tail,L,Result).
return(X,[],Result).
return(X,L,Result) :-
multiplication(X,L,_,Result).
和查询:
返回(2,[1,2],结果)。
第一次运行后,似乎应该返回Result,但它会永远运行。