На основании iwhen/2
,
сначала определите
уточненный тестовый предикат eveninteger_t/2
:
eveninteger_t(I, T) :-
iwhen(nonvar(I), ( 0 is I mod 2 -> T = true ; T = false )).
oddinteger_t(I, T) :- % defined for the sake of completeness
iwhen(nonvar(I), ( 1 is I mod 2 -> T = true ; T = false )).
Затем в сочетании с if_/3
определить integers_evendups/2
следующим образом:
integers_evendups([], []).
integers_evendups([X|Xs], [X|Zs1]) :-
if_(evenintegers_t(X), Zs1 = [X|Zs0], Zs1 = Zs0),
integers_evendups(Xs, Zs0).
Вот вопрос, который вы задали в своем вопросе:
?- Xs = [1,2,3,5,4], integers_evendups(Xs,Zs).
Xs = [1, <b>2</b>, 3,5, <b>4</b> ],
Zs = [1,<b>2</b>,<b>2</b>,3,5,<b>4</b>,<b>4</b>].
Альтернатива # 1
На основе if_//3
определить dcg evenintegerdups//1
:
evenintegerdups([]) -->
[].
evenintegerdups([X|Xs]) -->
if_(eveninteger_t(X), [X,X], [X]),
evenintegerdups(Xs).
Альтернатива # 2
При использовании мета-предиката foldl/4
и lambdas код становится еще короче:
:- use_module(library(lambda)).
evenintegerdups(Xs) -->
foldl(\X^if_(eveninteger_t(X),[X,X],[X]),Xs).