una programacion predicados listas lista insertar genealogico fuente explicados elemento ejercicios ejemplo conocimiento codigo arbol list prolog

programacion - ¿Elementos dobles en la lista usando Prolog?



predicados en prolog (2)

¿Cómo puedo duplicar los números pares en una lista en Prolog? Por ejemplo:

X = [1,2,3,5,4]

El resultado debería ser:

X = [1,2,2,3,5,4,4]

¡Gracias!


Incluso el control probablemente se puede hacer mejor, pero funciona.

even(N) :- N mod 2 =:= 0. doubleeven([],[]). doubleeven([H|T], [H,H|Z]) :- even(H), !, doubleeven(T,Z). doubleeven([H|T], [H|Z]) :- doubleeven(T,Z).


El código que se muestra en esta respuesta se basa en el predicado de prueba reificado eveninteger_truth/2 :

eveninteger_truth(I,Truth) :- ( var(I) -> throw(error(instantiation_error ,eveninteger_truth/2)) ; /+integer(I) -> throw(error(type_error(integer,I),eveninteger_truth/2)) ; 0 is I mod 2 -> Truth = true ; Truth = false ).

Solo para completar, vamos a definir análogamente oddinteger_truth/2 aquí también:

oddinteger_truth(I,Truth) :- ( var(I) -> throw(error(instantiation_error ,oddinteger_truth/2)) ; /+integer(I) -> throw(error(type_error(integer,I),oddinteger_truth/2)) ; 1 is I mod 2 -> Truth = true ; Truth = false ).

En if_/3 de if_/3 y eveninteger_truth/2 , definimos integers_evendups/2 :

integers_evendups([],[]). integers_evendups([X|Xs],[X|Zs1]) :- if_(evenintegers_truth(X), Zs1 = [X|Zs0], Zs1 = Zs0), integers_evendups(Xs,Zs0).

Veamos la consulta que hiciste en tu pregunta:

?- Xs = [1,2,3,5,4], integers_evendups(Xs,Zs). Xs = [1, 2, 3,5, 4 ], Zs = [1,2,2,3,5,4,4].

Como alternativa, ¿qué hay de usar dcg ? En función de if_//3 , definimos evenintegerdups//1 :

evenintegerdups([]) --> []. evenintegerdups([X|Xs]) --> if_(eveninteger_truth(X), [X,X], [X]), evenintegerdups(Xs).

Si usamos el meta-predicado foldl/4 y lambdas , el código puede ser aún más conciso:

:- use_module(library(lambda)). evenintegerdupsB(Xs) --> foldl(/X^if_(eveninteger_truth(X),[X,X],[X]),Xs).

Veamos estas dos variantes de dcg en acción:

?- Xs = [1,2,3,5,4], phrase(evenintegerdups(Xs),Zs). Xs = [1, 2, 3,5, 4 ], Zs = [1,2,2,3,5,4,4]. ?- Xs = [1,2,3,5,4], phrase(evenintegerdupsB(Xs),Zs). Xs = [1, 2, 3,5, 4 ], Zs = [1,2,2,3,5,4,4].