Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Prolog中计算多维数据集列表_Prolog_Clpfd - Fatal编程技术网

在Prolog中计算多维数据集列表

在Prolog中计算多维数据集列表,prolog,clpfd,Prolog,Clpfd,所以我正在用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,New

所以我正在用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。感谢您的帮助:)

首先,您正在使用不同数量的参数创建不同的
多维数据集。这必然会导致概念和句法上的问题,所以在这一点上,重新思考你在做什么。在这种情况下,请尝试扩展使用模式匹配和递归的方法:

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).

首先,使用不同数量的参数生成不同的
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).

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

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

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

cube(N, C) :-
    C is N^3.
cubes(Ns, Cs) :-
    maplist(cube, Ns, Cs).
library()具有一些有趣的特性,允许(在整数域中)更好地处理算术关系。将上面的立方体替换为

:- [library(clpfd)].

cube(N, C) :-
    N ^ 3 #= C.
你被允许写作

?- cubes(X,[1,8,27]).
X = [1, 2, 3].

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

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

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

cube(N, C) :-
    C is N^3.
cubes(Ns, Cs) :-
    maplist(cube, Ns, Cs).
library()具有一些有趣的特性,允许(在整数域中)更好地处理算术关系。将上面的立方体替换为

:- [library(clpfd)].

cube(N, C) :-
    N ^ 3 #= C.
你被允许写作

?- cubes(X,[1,8,27]).
X = [1, 2, 3].

在这种情况下,还可以通过差异列表来实现预期目标:

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

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

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 )
  .

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

在这种情况下,一个人也可以通过一个不同的列表来实现所需的目标:

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

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

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 )
  .

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

下一个练习,尝试以更简单的方式进行。你能在这里取消使用
is
吗?我应该澄清一下,输入类似于立方体([1,2,3],X),输出应该是X=1,8,27,如果他们输入X(即立方体([1,2,3],[1,8,27]),那么它应该返回false。好吧,我想让它保持模糊,以便让你能够解决一些问题。但我在我的答案中添加了更多内容,这正是你想要的。作为奖励,如果你留下第二个参数变量,这个函数也会计算立方根,但是我留下了一个小小的错误(当你这样使用解释器时,解释器需要额外的
),所以如果你感兴趣的话,这是一个很好的练习来解决这个问题,给自己一个立方体函数,它也会自动生成立方体根。下一个练习,试着用一种更简单的方式来实现。你能在这里取消使用
is
吗?我应该澄清一下,输入类似于立方体([1,2,3],X),输出应该是X=1,8,27,如果他们输入X(即立方体([1,2,3],[1,8,27]),那么它应该返回false。好吧,我想让它保持模糊,以便让你能够解决一些问题。但我在我的答案中添加了更多内容,这正是你想要的。作为奖励,如果你留下第二个参数变量,这个函数也会计算立方根,但是我留下了一个小小的错误(当你这样使用解释器时,解释器需要额外的
),所以如果你感兴趣的话,这是一个很好的练习来解决这个问题,给自己一个多维数据集函数,它也会自动生成多维数据集根。在我的解释器(swi prolog)中,当
N
作为变量保留时,多维数据集函数会给出一个未实例化的错误。这是口译员的区别吗?也不清楚为什么这会满足OP的要求,我还有一个抱怨,使用
maplist
有点像作弊,因为这样的练习显然是为了让程序员考虑模式匹配和简洁的递归。对于一个学习者来说,把它扫到地图列表中是人为的简洁。@EMS:你是对的,并且已经解释了well OP的问题。关于库(clpfd)的问题,AFAIK这样的代码应该可以工作。当然,使用(#=)/2,而is/2会给出错误…@EMS:一个练习可以有很多解决方案,我认为最好的解决方案是在这里发现要应用的全局模式是一个映射列表,然后重新编码映射列表(如果您感兴趣的话)。通过这种方式,您可以同时学习递归和函数习惯用法,但使用maplist是否正确完全取决于上下文。在我曾经参加过的语言处理研究生班上,我们整个学期都在使用Prolog,并且禁止使用maplist(等等)。教授认为这会混淆你在做什么。我知道这是一个极端的例子,但对于计算立方体这样的练习来说,假设t是合理的