所以我在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是NewCubes。如有任何帮助,我们将非常感谢:)
发布于 2012-08-13 09:45:35
首先,您使用不同数量的参数制作不同的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-13 14:02:54
我认为您正在尝试使用一种称为累加器的模式,用一个包含中间结果的附加参数重写一个二元关系。
抛开语法错误不谈,你应该注意到累加器在这里是无用的,因为一个列表的每个元素只与另一个列表的相应元素相关。
库(apply)具有适用于以下常见情况的maplist/3:
cube(N, C) :-
C is N^3.
cubes(Ns, Cs) :-
maplist(cube, Ns, Cs).库(clpfd)有一些有趣的特性,允许(在整数域中)更好地处理算术运算。将上面的多维数据集替换为
:- [library(clpfd)].
cube(N, C) :-
N ^ 3 #= C.你可以写下
?- cubes(X,[1,8,27]).
X = [1, 2, 3].发布于 2012-08-15 03:34:02
在这种情况下,还可以使用差异列表来实现所需目标
cubes( [] , [] ) .
cubes( [X|Xs] , [Y|Ys] ) :-
Y is X*X*X ,
cubes( Xs , Ys )
.输出列表是在我们遍历源列表时构建的,向下递归。最终目标cubes([],[])将空列表[]与输出列表的尾部统一起来,使其成为一个正确的列表。
另一种方法是使用累加器,它以相反的顺序构建输出,然后反转它:
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 )
.两者都是(我们应该)正确的尾递归。
https://stackoverflow.com/questions/11927028
复制相似问题