将元组转换为列表

时间:2016-11-19 15:54:24

标签: list prolog tuples

我搜索过,奇怪的是没有找到太多。如何将未知长度的元组转换为prolog中的列表?

例如:

List=[1,2,3,4], Tuple=(1,2,3,4).

3 个答案:

答案 0 :(得分:2)

当您遇到术语转换时,了解术语实际表示的内容通常是个好主意。

您可以使用 write_canonical/1 来获取术语的规范形式。

在你的情况下:

?- Tuple = (1,2,3,4), write_canonical(Tuple).
','(1,','(2,','(3,4)))
Tuple =  (1, 2, 3, 4).

这清楚地表明我们实际上是在谈论(A,B)形式的复合术语 - 以前缀表示法编写为','(A,B) - 其参数为整数或再次出现这样的复合词。这些术语在Prolog中也称为“和列表”,而Prolog 目标也具有这样的形状。特别要注意的是,这些并不是真正的“元组”,当然不是“一等公民”意义上的,只有复合词与任何其他复合词一样。

因此,我们只需要推理这些 2种可能的情况

  • 整数
  • 表格(A,B)的字词。

此外,在描述列表时,为方便起见,请始终考虑使用表示法。

例如:

tuple_list(I)     --> { integer(I) }, [I].
tuple_list((A,B)) --> tuple_list(A), tuple_list(B).

现在我们有:

?- Tuple = (1,2,3,4), phrase(tuple_list(Tuple), Ls).
Tuple =  (1, 2, 3, 4),
Ls = [1, 2, 3, 4].

这解决了从这些术语转换为列表的任务。

但是,最常见的查询不会产生答案:

?- phrase(tuple_list(Tuple), Ls).
ERROR: Out of local stack

我将tuples_list//1一般化,以便它可以在所有方向 作为练习。

答案 1 :(得分:1)

你已经有了两个有用的答案。如上所述,您通常不在符号(1, 2, 3, 4)中使用“元组”:这不是像Haskell那样的平面数据结构,它是嵌套的数据结构。 Prolog方式是使用带有arity 4的术语,例如quadruple(1, 2, 3, 4)。当然,名称无关紧要,但通常使用某种描述性名称。

然后,要将术语的参数转换为列表,请使用“univ”运算符=..,如下所示:

Term =.. [Name|Arguments]

这样:

?- foo(1, 2, 3, 4) =.. [foo|Args].
Args = [1, 2, 3, 4].

在具有两个元素(对)的元组的特殊情况下,通常使用仿函数-/2。短划线也是一个中缀运算符,因此您可以编写1-a而不是-(1, a)。很多用于对的库谓词期望它们为-/2,例如:

?- keysort([1-c, 2-a, -(0, b), 1-a], S).
S = [0-b, 1-c, 1-a, 2-a].

答案 2 :(得分:0)

Prolog中的元组很少使用,但快速转换可能是

list_tuple([A,B|L], (A,R)) :- list_tuple([B|L], R).
list_tuple([A,B], (A,B)). % I don't think unary tuples make sense...

?- list_tuple([1,2,3,4],T).
T =  (1, 2, 3, 4) ;
false.

这在后退模式'

上效果不佳
?- list_tuple(L,(1,2,3,4)).
L = [1, 2, 3, 4] ;
L = [1, 2,  (3, 4)] ....

您可以尝试进行裁剪以确定其确定性,我已按要求按顺序提供了条款......