2016-11-19 77 views
1

我搜索了奇怪的是没有找到太多的东西。我如何将未知长度的元组变成prolog中的列表?把一个元组变成一个列表

例如:

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

参见[这个问题](http://stackoverflow.com/q/2893766/1812457) – 2016-11-19 20:08:43

回答

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,使其适用于所有 方向作为练习

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

工作得非常好,你可以尝试把切为了得到它确定性,我已经按要求提供了条款...

1

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

然后,以一个长期的参数转换到一个列表,你使用“大学”运营商=..这样的:

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