我搜索过,奇怪的是没有找到太多。如何将未知长度的元组转换为prolog中的列表?
例如:
List=[1,2,3,4], Tuple=(1,2,3,4).
答案 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)
的字词。此外,在描述列表时,为方便起见,请始终考虑使用dcg表示法。
例如:
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)
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)] ....
您可以尝试进行裁剪以确定其确定性,我已按要求按顺序提供了条款......