复杂列表操作

时间:2016-10-20 06:33:24

标签: list prolog

背景

我有以下代码,它将取出内部列表中的第一个列表元素。

实施例: getFirstElement([[1,data1],[[2,data2],[3,data3],[[4,data4],[5,data5]]]],O) O将以[2]返回。

getFirstElement([H | T], [X| Tn]) :-
  [[X, _] | _] = H.

getFirstElement([H | T], O) :-
  getFirstElement(H, O) ;
  getFirstElement(T, O).

问题:

如何扩展功能以便返回所有事件的列表,而不仅仅是第1个?

想要的输出示例:

getFirstElement([[1,data1],[[2,data2],[3,data3],[[4,data4],[5,data5]]]],O)。 O将以[2,4]返回。

2 个答案:

答案 0 :(得分:1)

我认为混淆的原因之一是您使用列表来表示对。如果您使用getFirstElement([1-data1, [2-data2, 3-data3, [4-data4, 5-data5]] ], O) 来表示对(在Prolog中是常规的),那么将会更清楚发生了什么。所以你的第一个例子是:

get_first_element(Xs, E) :- 
    inner_list(Xs, Y),
    Y = [E|_].

inner_list([X|_], Inner) :-
    is_list(X),
    X = Inner.
inner_list([X|_], Inner) :- 
    inner_list(X, Inner).
inner_list([_|Xs], Inner) :-
    inner_list(Xs, Inner).  

我从谓词的名称假设O应该绑定到任何深度的“内部”列表的第一个元素,并且不确定地返回所有解(即回溯)。

您可以通过提取这些“内部”列表然后返回其第一个元素来完成此操作。

?- get_first_element([1-data1, [2-data2, 3-data3, [4-data4, 5-data5]]], E).
E = 2-data2 ;
E = 4-data4 ;

例如:

chart.fromLatLonToPoint()

答案 1 :(得分:0)

getE([Num, Data], O) :-
    not(is_list(Num)),
    not(is_list(Data)).

getE([H | T], [X | Tn]) :-
  [[X, _] | _] = H,
  getE(T, Tn),
  getE(H, Tn).

getE([H | T], O) :-
    getE(T, O),
    getE(H, O).

getE([], O).

我错过的是:

  • 当它是一个内部列表时丢掉头部(缺少内部列表中的所有内部列表)
  • 在到达没有任何内部列表的列表时处理该案例,没有添加规则让Prolog继续搜索是否已达到。
  • 最后需要一个基本案例。

但代码有一个问题,它在prolog中运行以下时返回O = [2,4,5 | _G12383],而不是O = [2,4,5]。

trace,getE([[1,data1],[[2,data2],[3,data3],[[4,data4]],[[5,data5]]]],O)。