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].