haskell - 将列表理解翻译为 Prolog

标签 haskell prolog list-comprehension

我在 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/

    相关文章:

    prolog - SWI-Prolog 中正确的 unify_with_occurs_check/2?

    python - 为什么使用 zip 对象的列表理解会导致空列表?

    Haskell - 使用 Reader monad 的二叉树中每个节点的深度

    list - 综合列表上的动态函数 (Haskell)

    prolog - 如何在序言中使用repeat/0打印一组数字?

    prolog - Prolog:不等式运算符

    haskell - 每种类型都有独特的变质吗?

    list - 在 Haskell 中将内部列表切割成相等的长度

    python - 使用 python 在句子列表中形成单词的二元组并计算二元组

    python - 如何根据字典列表中的特定值在单独的 Dataframe 列中创建列表?