如何提取数据以在Prolog中列出?

时间:2018-06-23 14:57:39

标签: list prolog

我有某种类型的数组L,我正在尝试将数据提取到数组中,例如:

L=[day(sunday),day(monday)]

Target=[sunday,monday]

使用forall进行了尝试,并在Prolog列表中搜索了相关问题。

extract_data_to_list(L,Target) :-
    member(day(Day),L),
    length(L, L1),
    length(Target, L1),
    member(Day,Target).

当前输出:

?- extract_data_to_list([day(sunday),day(monday)],Target).
Target = [sunday, _5448] ;
Target = [_5442, sunday] ;
Target = [monday, _5448] ;
Target = [_5442, monday].

所需的输出:

?- extract_data_to_list([day(sunday),day(monday)],Target).
Target=[sunday,monday]

3 个答案:

答案 0 :(得分:4)

这是maplist的理想问题:

day_name(day(DayName), DayName).

dates_daylist(Dates, DayList) :-
    maplist(day_name, Dates, DayList).

Maplist将day_name应用于DatesDayList中的每个对应的元素对。

答案 1 :(得分:3)

对于SICStus | SWIlibrary(lambda)是一个理想的问题:

maplist(\day(N)^N^true, Dates, Daylist).

答案 2 :(得分:1)

为了防万一,我还有其他几种方法可以做到这一点。

?- findall(D, member(day(D), [day(monday), day(tuesday)]), Days).
Days = [monday, tuesday].

这里的技巧是,如果findall/3(参数2)使用Goal,则可以使用member/2来驱动一个简单的循环。在这种情况下,我们将day(D)与列表中的每个项目统一;除了统一之外,实际上不需要进行任何其他工作,因此我们仅用member/2就可以“拆开包装”,但是您可以在括号中加上参数来驱动更复杂的循环。假设您要将day更改为day-of-week,例如:

?- findall(DoW, (member(day(D), 
                 [day(monday), day(tuesday)]), DoW=day_of_week(D)), 
           Days).
Days = [day_of_week(monday), day_of_week(tuesday)].

只要将目标括起来,就可以使目标更复杂。

第二个技巧是针对SWI-Prolog(或Logtalk,如果可以使用的话)的,它是新的library(yall)

?- maplist([Wrapped,Day]>>(Wrapped=day(Day)),
          [day(monday),day(tuesday)], X).
X = [monday, tuesday].

library(yall)使您可以编写匿名谓词。 [Wrapped,Day]>>(Wrapped=day(Day))有点像内联谓词,在这里完全执行@lurker的day_name/2谓词所做的事情,只是在maplist/3调用本身内部,而不必是一个单独的谓词。通用语法类似于[Variables...]>>Goal。这种东西以前以library(lambda)的形式提供,并且已经成为Logtalk的功能很多年了。