首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Prolog计算多维数据集列表

用Prolog计算多维数据集列表
EN

Stack Overflow用户
提问于 2012-08-13 08:44:00
回答 3查看 2.5K关注 0票数 1

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

代码语言:javascript
复制
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.

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

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

我不完全确定为什么会发生这个错误,但它似乎发生在最后一行,Cubes是NewCubes。如有任何帮助,我们将非常感谢:)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-08-13 09:45:35

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

代码语言:javascript
复制
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).
票数 1
EN

Stack Overflow用户

发布于 2012-08-13 14:02:54

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

抛开语法错误不谈,你应该注意到累加器在这里是无用的,因为一个列表的每个元素只与另一个列表的相应元素相关。

库(apply)具有适用于以下常见情况的maplist/3:

代码语言:javascript
复制
cube(N, C) :-
    C is N^3.
cubes(Ns, Cs) :-
    maplist(cube, Ns, Cs).

库(clpfd)有一些有趣的特性,允许(在整数域中)更好地处理算术运算。将上面的多维数据集替换为

代码语言:javascript
复制
:- [library(clpfd)].

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

你可以写下

代码语言:javascript
复制
?- cubes(X,[1,8,27]).
X = [1, 2, 3].
票数 5
EN

Stack Overflow用户

发布于 2012-08-15 03:34:02

在这种情况下,还可以使用差异列表来实现所需目标

代码语言:javascript
复制
cubes( [] , [] ) .
cubes( [X|Xs] , [Y|Ys] ) :-
  Y is X*X*X ,
  cubes( Xs , Ys )
  .

输出列表是在我们遍历源列表时构建的,向下递归。最终目标cubes([],[])将空列表[]与输出列表的尾部统一起来,使其成为一个正确的列表。

另一种方法是使用累加器,它以相反的顺序构建输出,然后反转它:

代码语言:javascript
复制
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 )
  .

两者都是(我们应该)正确的尾递归。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11927028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档