Segregando listas en Prolog

Me está costando mucho trabajo entender cómo obtener mi código para mostrar mis listas segregadas que constan de números pares e impares. Ni siquiera estoy seguro de lo que me falta de comprensión. Soy nuevo en este lenguaje obviamente y debo usarlo para la escuela. Mi mente imperativa y funcional no me deja saber qué diablos está pasando con esta lol.

¡Ahora, no, no te estoy pidiendo que hagas mi tarea! Simplemente te pido que me ayudes a ver qué es mi falta de comprensión. También busqué respuestas similares, pero no puedo convertirlas a la forma en que se supone que debo escribir esta función.

Por favor, una vez más, no me critiquen por esto como solía ser criticado anteriormente. Por favor, solo ayúdame a ver lo que me falta de comprensión. No solo me proporciones respuestas y fragmentos de código sin explicarlo, por favor.

Aquí está:

is_even(H) :- 0 is mod(H, 2). segregate(List, Even, Odd) :- segregator(List, Even, Odd). segregator([], [], []). segregator([H|T], E, O) :- is_even(H), % I feel here is where I am supposed to build the list, % but I have no clue how since Even or Odd has not been unified. segregator(T, E, O), write('Even is '), write(E), nl. segregator([H|T], E, O) :- % Same here as above. segregator(T, E, O), write('Odd is '), write(O), nl. 

Una implementación lógicamente pura es muy directa, gracias a clpfd :

 :- use_module(library(clpfd)). list_evens_odds([],[],[]). list_evens_odds([X|Xs],[X|Es],Os) :- X mod 2 #= 0, list_evens_odds(Xs,Es,Os). list_evens_odds([X|Xs],Es,[X|Os]) :- X mod 2 #= 1, list_evens_odds(Xs,Es,Os). 

Algunas consultas de muestra que esperamos tener éxito (con una secuencia finita de respuestas):

 ?- Xs = [1,2,3,4,5,6,7], list_evens_odds(Xs,Es,Os). Xs = [1,2,3,4,5,6,7], Es = [ 2, 4, 6 ], Os = [1, 3, 5, 7] ; false. ?- list_evens_odds(Ls,[2,4],[1,3]). Ls = [2,4,1,3] ? ; Ls = [2,1,4,3] ? ; Ls = [2,1,3,4] ? ; Ls = [1,2,4,3] ? ; Ls = [1,2,3,4] ? ; Ls = [1,3,2,4] ? ; no 

¿Qué pasa con las consultas que esperamos fallar ?

 ?- list_evens_odds(Ls,[2,4,5],[1,3]). no ?- list_evens_odds(Ls,[2,4],[1,3,6]). no ?- list_evens_odds([_,_,_],[2,4],[1,3]). no 

Por fin, la consulta más general :

 ?- assert(clpfd:full_answer). yes ?- list_evens_odds(Ls,Es,Os). Ls = [], Es = [], Os = [] ? ; Ls = [_A], Es = [_A], Os = [], _A mod 2#=0, _A in inf..sup ? ... 

Editar 2015-05-06

¡Aquí hay otra manera de hacerlo con pureza lógica !

Use la tpartition/4 meta-predicado junto con zeven_t/2 o zodd_t/2 .

 bool01_t(1,true). bool01_t(0,false). zeven_t(Z,Truth) :- Z mod 2 #= 0 #< ==> B, bool01_t(B,Truth). %zodd_t(Z,Truth) :- Z mod 2 #= 1 #< ==> B, bool01_t(B,Truth). zodd_t(Z,Truth) :- Z mod 2 #= B, bool01_t(B,Truth). % tweaked 

zeven_t/2 reifica la uniformidad de un entero, zodd_t/2 la imparidad .

Con todo en su lugar, ¡ejecutemos algunas consultas!

 ? - tpartition (zeven_t, [1,2,3,4,5,6,7], Es , Os ).
 Es = [2,4,6], Os = [1,3,5,7].
 ? - tpartition (zodd_t, [1,2,3,4,5,6,7], Os , Es ).  El orden de% de los argumentos es diferente
 Es = [2,4,6], Os = [1,3,5,7].

Ambos tienen un resultado determinista . La consulta equivalente con list_evens_odds/3 no.