如何在Swi-Prolog中订购元组列表

时间:2018-05-05 12:40:39

标签: prolog prolog-setof

我在swi-prolog中有一个列表:

[(5,4), (1,4), (3,12), (4,2), (5,4)]

我需要按照每个" tuple"的第二个元素组织列表,删除任何重复的元素,所以这个列表看起来像这样:

[(4,2), (1,4), (5,4), (3,12)]

使用谓词sort / 2,它可以完成我想要的一切,除非它根据每个元组的第一个元素进行组织,这是我不想要的。

我该怎么办?

2 个答案:

答案 0 :(得分:1)

如果您不想编写自己的排序例程(您的Prolog排序可能比您的更优化),可能会有一些特定于实现的谓词,您可以使用它们来比较您的选择。

例如,SWI-Prolog有predsort/3,它使用谓词进行排序。您可以将它与谓词一起使用,该谓词首先比较对的第二个元素:

compare_by_second(<, (A, B), (C, D)) :-
    (   B @< D
    ;   B == D,
        A @< C ).
compare_by_second(=, (A, B), (C, D)) :-
    A == C,
    B == D.
compare_by_second(>, (A, B), (C, D)) :-
    (   B @> D
    ;   B == D,
        A @> C ).

% ?- predsort(compare_by_second, [(5,4), (1,4), (3,12), (4,2), (5,4)], Sorted).
%@ Sorted = [ (4, 2), (1, 4), (5, 4), (3, 12)] ;
%@ false.

答案 1 :(得分:0)

http://kti.mff.cuni.cz/~bartak/prolog/sorting.html的启发,我修改了数据透视算法以满足您的需求。我在Sicstus Prolog上进行了测试,结果很有效。

revPredict <- function(preproc, data,digits=0,range = F) {
   if (range == T){
     data<-data %>%
       select(one_of(dimnames(preproc$ranges)[[2]])) %>%
       map2_df(preproc$ranges[2,]-preproc$ranges[1,], ., function(min_max, dat) min_max* dat)  %>%
       map2_df(preproc$ranges[1,], ., function(min, dat) min + dat) %>%
      mutate_if(is.numeric,funs(round(.,digits = digits)))
    return(data)
    }
  data<- data %>%
    select(one_of(names(preproc$mean))) %>%
    map2_df(preproc$std, ., function(sig, dat) dat * sig)  %>%
    map2_df(preproc$mean, ., function(mu, dat) dat + mu) %>%
    mutate_if(is.numeric,funs(round(.,digits = digits)))
  return(data)
}