es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo asigno una variable de retorno en Prolog?

Soy completamente nuevo en Prolog, así que puede que esté muy equivocado aquí.
Llevo intentando resolver el siguiente problema durante la última semana:

tweeted(anne, tweet1).
tweeted(anne, tweet5).
tweeted(fred, tweet2).
tweeted(fred, tweet7).
tweeted(fred, tweet8).

findTweets(Nombre, TweetsPorNombre) :- findall(X, tweeted(Nombre, X), TweetsPorNombre).

tweets([], _).
tweets([Nombre|Nombres], Resultado) :-
findTweets(Nombre, Resultado),
/* ¿Cómo concateno el Resultado con Resultado?*/
tweets(Nombres, Resultado).

Si llamo con una sola variable, sólo hay una llamada recursiva y obtengo el resultado:

?- tweets([fred], R).
R = [tweet2, tweet7, tweet8].

Pero tengo dificultades para entender cómo puedo concatenar el valor del Resultado de la llamada a findTweets con el Resultado para devolver un resultado acumulativo.
Intenté usar la función ‘append’ pero no tuve suerte…
Por ejemplo:

tweets([], _).
tweets([Nombre|Nombres], Resultado) :- 
    findTweets(Nombre, Tweets),
    append(Tweets, Resultado, Temp),
    Resultado is Temp,
    tweets(Nombres, Resultado).

Pero obtengo este error:

?- tweets([fred], R).
ERROR: Type error: 'character' expected, found 'tweet2' (an atom)
ERROR: In:
ERROR:   [11] _25712 is [tweet2,tweet7|...]
ERROR:   [10] tweets([fred],_25752) at /home/kimchi/git-repos/bbk/Programming-Language-Paradigms/logic-programming-Pavel-Durov/relationships.pl:33
ERROR:    [9] toplevel_call(user:user: ...) at /snap/swi-prolog/43/usr/lib/swipl/boot/toplevel.pl:1117

Gracias anticipadas 🙂

Tags:  

Answer

  1. Avatar for davy.ai

    Para agregar una lista a otra en Prolog, puedes usar el predicado append/3. El predicado toma dos listas como entrada y devuelve una tercera lista que es el resultado de concatenar las dos listas de entrada juntas. En tu código, puedes usar append(Tweets, Result, Temp) para agregar la lista de Tweets a la lista de Result y almacenar el resultado en la variable Temp.

    Sin embargo, en lugar de usar Result is Temp para asignar el valor de Temp a Result, debes usar la unificación con el operador =, así: Result = Temp. Esto se debe a que en Prolog, el operador = se utiliza para la unificación, lo que significa que intenta hacer que los lados izquierdo y derecho del operador sean iguales. En otras palabras, une las variables a ambos lados con el mismo valor.

    Aquí está el código actualizado:

    tweeted(anne, tweet1).
    tweeted(anne, tweet5).
    tweeted(fred, tweet2).
    tweeted(fred, tweet7).
    tweeted(fred, tweet8).
    
    findTweets(Name, TweetsByName) :- findall(X, tweeted(Name, X), TweetsByName).
    
    tweets([], []) :- !. % caso base: una lista vacía retorna una lista vacía
    tweets([Name|Names], Result) :- 
        findTweets(Name, Tweets),     
        append(Tweets, Temp, Result),
        tweets(Names, Temp).
    

    En este código actualizado, agregué un caso base para el predicado tweets/2 donde una lista vacía pasada como entrada retorna una lista vacía como salida. Luego, en el caso recursivo, se utiliza el predicado append/3 para agregar la lista de Tweets a la variable Temp, que luego se utiliza como entrada para la siguiente llamada recursiva a tweets/2. Finalmente, la lista Result se unifica con la variable Temp para devolver el resultado acumulado.

    Con estos cambios, tu consulta original debería funcionar correctamente:

    ?- tweets([fred], R).
    R = [tweet2, tweet7, tweet8].
    

Comments are closed.