Prolog - 域错误:'acyclic_term'预计

时间:2017-04-20 15:26:46

标签: prolog

我要做的是,写一个谓词乘法/ 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]])'

第二次追加电话

如果有人知道我收到错误的原因,如何解决或以其他方式解决这个问题,我愿意接受这些想法。

3 个答案:

答案 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,但它会永远运行。