Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/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程序转换为Haskell程序_Haskell_Prolog - Fatal编程技术网

将Prolog程序转换为Haskell程序

将Prolog程序转换为Haskell程序,haskell,prolog,Haskell,Prolog,我有一次考试的复习题,我需要一些指导 使用以下Prolog程序作为可执行规范 mix(Xs,Ys):-remix(Xs,[],Ys). remix([],Ys,Ys). remix([X|Xs],Ys,Zs):-remix(Xs,[X|Ys],Zs). 编写一个等价的Haskell程序 这是迄今为止我对Haskell代码的了解: mix Xs Ys=remix Xs[]Ys 混音[]Ys Zs=Zs 混音(X:Xs)Ys Zs=X:(混音Xs Ys Zs) 这个Haskell程序等

我有一次考试的复习题,我需要一些指导

使用以下Prolog程序作为可执行规范

mix(Xs,Ys):-remix(Xs,[],Ys).

remix([],Ys,Ys).    
remix([X|Xs],Ys,Zs):-remix(Xs,[X|Ys],Zs).
编写一个等价的Haskell程序

这是迄今为止我对Haskell代码的了解:

mix Xs Ys=remix Xs[]Ys
混音[]Ys Zs=Zs
混音(X:Xs)Ys Zs=X:(混音Xs Ys Zs)

这个Haskell程序等同于上面的Prolog代码吗?如果没有,我做错了什么?

直译为:

mix xs = remix xs []
remix [] ys = ys
remix (x:xs) ys = remix xs (x:ys)
假设
mix/2
的第一个参数严格来说是输入参数,
mix/2
remix/3
的最后一个参数都是输出参数。然后,Haskell函数的返回值是您正在翻译的Prolog谓词的最后一个参数。否则,Haskell版本与Prolog完全相同,只是正确的Haskell语法。将它与您的尝试进行比较,您将看到许多细微的差异(我猜Haskell编译器也会告诉您这些吗?)

(如果这是错误的,请Haskellers纠正我)

然而,这方面存在一些问题。可以通过两种方式查询原始Prolog程序:

?- mix([1,2,3], M).
M = [3, 2, 1].

?- mix(M, [3,2,1]).
M = [1, 2, 3] .
甚至:

?- mix(X, Y), numbervars(X-Y, 0, _).
X = Y, Y = [] ;
X = Y, Y = [A] ;
X = [A, B],
Y = [B, A] ;
X = [A, B, C],
Y = [C, B, A] ;
X = [A, B, C, D],
Y = [D, C, B, A] . % and so on

但是,第二个查询留下了一个选择点,如果您尝试查看可能得到的其他解决方案(键入空格或
而不是Enter),程序不会终止。它是否说明了如何使用原始Prolog程序?

Haskell程序的参数太多。最后一个参数在prolog中通常被视为输出,因此在Haskell中它应该消失。此外,Haskell参数的所有名称必须为小写。由于Haskell具有不同的执行模型,因此无法轻松编写等效的Haskell程序。您可以编写一个Haskell程序,为Prolog程序的可能调用的子集提供相同的答案。由于对Prolog完全不熟悉,我猜测
:-
必须是一个旋转栅门符号,但它似乎走的方向相反。“奇怪!”德弗尔说,“是的<代码>a(X):-b(X,Y),c(X,Y)。的意思是“当
b(X,Y)
为真时,
a(X)
为真,并且
c(X,Y)
也为真”。在“漂亮的打印”代码中,它通常由左边的一个短箭头表示。仅供参考,Haskell中有一个用于逻辑编程的
logict
包,但我(还)一点也不理解它。@dfeuer显然,还有miniKanren。不久前,一位作者给出了一个很好的答案:非常感谢。这很有效。我的实现并没有像预期的那样逆转列表。另外谢谢你纠正我的语法。