gpt4 book ai didi

haskell - 将列表理解翻译为 Prolog

转载 作者:行者123 更新时间:2023-12-04 00:47:04 24 4
gpt4 key购买 nike

我在 Haskell 中有一个列表理解,我想将其翻译为 Prolog。

列表理解的要点是旋转 4 x 4 网格:

rotate :: [Int] -> [Int]
rotate grid = [ grid !! (a + 4 * b) | a <- [0..3], b <- [0..3] ]

现在在 Prolog 中,我是这样翻译的:
rotateGrid([T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15],
[T0,T4,T8,T12,T1,T5,T9,T13,T2,T6,T10,T14,T3,T7,T11,T15]).

我们能做得更好吗?

最佳答案

我们可以使用findall/3对于列表推导(参见 SWI-Prolog Documentation)。例如。,

?- findall(X, between(1,10,X), Xs).
Xs = [1,2,3,4,5,6,7,8,9,10]
Xs是一个包含所有可以与 X 统一的值的列表当 X是一个介于 1 和 10 之间的数字。这大致相当于 Haskell 表达式 let Xs = [x | x <- [1..10]] (1)。您可以阅读 findall/3因此声明:“找到 [First Argument] 的所有值,使得 [Conditions in Second Argument] 成立,并将这些值放入列表 [Third Argument]”。

我用过 findall/3写谓词 rotate_grid(+Grid, ?RotatedGrid) .这是我在谓词中使用的近似 Haskell-Prolog 等价的列表;每行显示 Haskell 表达式将计算的值与具有相同值的 Prolog 变量之间的关系:
  • a <- [0..3] = Abetween(0, 3, A)
  • b <- [0..3] = Bbetween(0, 3, B)
  • (a + 4 * d) = XX is A + 4 * D
  • <Grid> !! <Index> = Elementnth0(Index, Grid, Element)

  • 然后我们只需要找到 Element的所有值:
    rotate_grid(Grid, RotatedGrid) :-
    findall( Element,

    ( between(0,3,A),
    between(0,3,B),
    Index is A + 4 * B,
    nth0(Index, Grid, Element) ),

    RotatedGrid
    ).

    为了验证这是否产生了正确的转换,我对问题中的 Prolog 代码进行了缩减,并提出了以下查询:
    ?- rotate_grid([t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15],
    [t0,t4,t8,t12,t1,t5,t9,t13,t2,t6,t10,t14,t3,t7,t11,t15]).
    | true.

    脚注:

    (1): between/3实际上不是 [m..n] 的类似物,因为后者从 m 返回值列表至 n在哪里 between(M,N,X)将在回溯时使用 M 和 N(包括)之间的每个值来实例化 X。要获取 SWI-Prolog 中的数字列表,我们可以使用 numlist(M,N,Ns) .所以更严格的类比 x <- [1.10]将是连词 member(X, Ns), numlist(1, 10, Ns) .

    关于haskell - 将列表理解翻译为 Prolog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23035186/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com