From: Markus Triska Date: Wed, 15 Apr 2020 15:49:01 +0000 (+0200) Subject: ADDED: list_to_set/2, using the first occurrence of each element X-Git-Tag: v0.8.123~150 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=16e257ea32621710a829c1e3b7ea6c8b04e76d2e;p=scryer-prolog.git ADDED: list_to_set/2, using the first occurrence of each element Example: ?- list_to_set([B,a,b,a,B,A,b,A], Ls). Ls = [B,a,b,A] ; false. --- diff --git a/src/prolog/lib/lists.pl b/src/prolog/lib/lists.pl index c373fb95..8561ab2a 100644 --- a/src/prolog/lib/lists.pl +++ b/src/prolog/lib/lists.pl @@ -2,7 +2,7 @@ memberchk/2, reverse/2, length/2, maplist/2, maplist/3, maplist/4, maplist/5, maplist/6, maplist/7, maplist/8, maplist/9, same_length/2, - sum_list/2, transpose/2]). + sum_list/2, transpose/2, list_to_set/2]). :- use_module(library(error)). @@ -149,3 +149,31 @@ transpose_(_, Fs, Lists0, Lists) :- maplist(list_first_rest, Lists0, Fs, Lists). list_first_rest([L|Ls], L, Ls). + + +list_to_set(Ls0, Ls) :- + maplist(with_var, Ls0, LVs0), + keysort(LVs0, LVs), + same_elements(LVs), + pick_firsts(LVs0, Ls). + +pick_firsts([], []). +pick_firsts([E-V|EVs], Fs0) :- + ( V == visited -> + Fs0 = Fs + ; V = visited, + Fs0 = [E|Fs] + ), + pick_firsts(EVs, Fs). + +with_var(E, E-_). + +same_elements([]). +same_elements([EV|EVs]) :- + foldl(unify_same, EVs, EV, _). + +unify_same(E-V, Prev-Var, E-V) :- + ( Prev == E -> + Var = V + ; true + ).