1

所以我在 SWI-Prolog 中做一些 Prolog,我遇到了一些障碍。给定一个输入列表,我必须创建一个多维数据集列表。我目前拥有的代码是

cubes([Head|Tail],Cubes) :-
    cubes([Head|Tail],Cubes,[]).
cubes([Head|Tail],Cubes,ActualCubes) :-
    X is Head^3,
    append(ActualCubes,[X],NewCubes),
    cubes(Tail,Cubes,NewCubes).
cubes([Tail],Cubes,ActualCubes) :-
    X is Tail^3,
    append(ActualCubes,[X],NewCubes),
    Cubes is NewCubes.

当我运行它时,它会给出一个错误,特别是......

ERROR: '.'/2: Type error: `[]' expected, found `[8]' ("x" must hold one character)
   Exception: (7) cbList([1, 2], _G296, []) ? creep

我不完全确定为什么会发生这个错误,但它似乎发生在最后一行,Cubes is NewCubes。任何帮助表示赞赏:)

4

3 回答 3

5

我认为您正在尝试使用一种称为accumulator的模式,使用包含中间结果的附加参数重写二进制关系。

除了语法错误,您应该注意累加器在这里没用,因为列表的每个元素与另一个列表的相应元素相关。

对于这种常见情况,library( apply ) 具有maplist /3 :

cube(N, C) :-
    C is N^3.
cubes(Ns, Cs) :-
    maplist(cube, Ns, Cs).

并且 library( clpfd ) 具有有趣的功能,可以(在整数域中)更好地处理算术。将上面的立方体替换为

:- [library(clpfd)].

cube(N, C) :-
    N ^ 3 #= C.

你可以写

?- cubes(X,[1,8,27]).
X = [1, 2, 3].
于 2012-08-13T06:02:54.307 回答
1

首先,您cubes使用不同数量的参数制作不同的谓词。这必然会导致概念和句法问题,所以在这一点上,重新考虑你在做什么。在这种情况下,尝试扩展您可以使用模式匹配和递归的方式:

cubes([],[]).
cubes([H|T], [Y|Z]):-
        Y is H*H*H,
        cubes(T,Z).


betterCubes([],[]).
betterCubes([H|T], [Y|Z]):-
        ( 
          var(Y) , nonvar(H)    -> Y is H*H*H
        ; nonvar(Y) , var(H)    -> H is Y**(1.0/3.0) 
        ; nonvar(Y) , nonvar(H) -> H*H*H =:= Y
        ),
        betterCubes(T,Z).
于 2012-08-13T01:45:35.167 回答
-1

In this case, one can also accomplish the desired goal with a difference list:

cubes( [] , [] ) .
cubes( [X|Xs] , [Y|Ys] ) :-
  Y is X*X*X ,
  cubes( Xs , Ys )
  .

The output list is built as we traverse the source list, recursing down. The final goal cubes([],[]) unifies the empty list [] with the tail of the output list, making it a correct list.

The other approach is to use an accumulator, which builds the output in reverse order, then reverses it:

cubes(Xs,Ys) :-
  cubes(Xs,[],T) ,
  reverse(T,Ys)
  .

cubes( [] , Ys, Ys ).
cubes( [X|Xs] , Ts , Ys ) :-
  T is X*X*X ,
  cubes( Xs , [T|Ts] , Ys )
  .

Both are (our should be) properly tail recursive.

于 2012-08-14T19:34:02.067 回答