You can use clpfd for this. In this manner you get a pure relation:
:- use_module(library(clpfd)).
list_evens_odds([], [], []).
list_evens_odds([E|Zs], [E|Es], Os) :-
0 #= E mod 2,
list_evens_odds(Zs, Es, Os).
list_evens_odds([E|Zs], Es, [E|Os]) :-
1 #= E mod 2,
list_evens_odds(Zs, Es, Os).
You can use this not only to split a list into evens and odds. But you can go even further. The following interaction is with SWI, but you get similar in SICStus with asserta(clpfd:full_answer)
.
?- list_evens_odds([1,2,3,4,5,6], Es, Os).
Es = [2,4,6], Os = [1,3,5]
; false.
?- Zs = [A,B,C], list_evens_odds(Zs, Es, Os).
Zs = [A,B,C], Es = [A,B,C], Os = [], A mod 2#=0, B mod 2#=0, C mod 2#=0
; Zs = [A,B,C], Es = [A,B], Os = [C], A mod 2#=0, B mod 2#=0, C mod 2#=1
; Zs = [A,B,C], Es = [A,C], Os = [B], A mod 2#=0, B mod 2#=1, C mod 2#=0
; ... .
?- Es = [E], Os = [O], list_evens_odds(Zs, Es, Os).
Es = [E], Os = [O], Zs = [E, O], E mod 2#=0, O mod 2#=1
; Es = [E], Os = [O], Zs = [O, E], E mod 2#=0, O mod 2#=1
; false.
The next is probably most irritating: Here, we ask whether there is an integer EO
that is both even and odd. Certainly, such an integer cannot exist. But we still get two answers!
?- EOs=[EO], list_evens_odds(Zs, EOs, EOs).
EOs = [EO], Zs = [EO, EO], EO mod 2#=1, EO mod 2#=0
; EOs = [EO], Zs = [EO, EO], EO mod 2#=0, EO mod 2#=1
; false.
This illustrates the difference between answers and solutions. We get here two answers, but both do not contain a solution. Most of the time an answer contains one or more solutions, but it can also contain none as in this case. Such answers are sometimes called inconsistencies.
Inconsistencies are not necessarily considered a bug of an implementation. They are rather an engineering tradeoff: Ensuring consistency might be very costly compared to the actual benefits. And: Prolog does not produce an incorrect answer: For the condition that has to hold is shown. Even if that condition turns out to be false.