UTNianos

Versión completa: [Prolog] Ayuda - Guia 1 Ejercicio 3
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Hola, agoté mis recursos, por lo que vengo a pedir un empujón con un ejercicio.

El enunciado dice:

Cita:Ejercicio 3
Escribir un programa Prolog que responda consultas acerca de cuáles son los rivales de una determinada selección en un campeonato mundial.
Una selección tiene como rivales todos los otros equipos de su mismo grupo (¡nunca contra sí misma!).
Incluir en el programa la siguiente información:

El grupo A está formado por Colombia, Camerún, Jamaica e Italia.
El grupo B está formado por Argentina, Nigeria, Japón y Escocia.

El programa debe ser capaz de responder, p.ej., a la siguiente consulta: ¿cuáles son los rivales de Argentina? otorgando como respuestas "Nigeria", "Japón" y "Escocia".

Yo hice esto:


grupo(colombia,a).
grupo(camerun,a).
grupo(jamaica,a).
grupo(italia,a).
grupo(argentina,b).
grupo(nigeria,b).
grupo(japon,b).
grupo(escocia,b).

esRival(Pais1,Pais2):-
grupo(Pais1,X),
grupo(Pais2,X),
Pais1 \= Pais2.


Mi duda es: hay alguna forma de hacer una regla "rivales" que reciba un solo argumento y devuelva todos sus rivales?


?- rivales(argentina).

> nigeria
> japon
> escocia


Gracias.
Hola.

Para que devuelva todos los rivales, se supone que deberías repasar los conceptos de inversibilidad. Para ello, debés asegurarte que cada predicado de la consulta lo sea.
Repasá estos ejemplos: http://uqbar-wiki.org/index.php?title=Pa...rsibilidad

La misma función te sirve, pero no te adelanto mucho así aprovechás el espíritu autodidacta =P


Saludos!
Intenté todo lo que se me ocurrió pero no hay caso, me devuelve siempre un valor booleano. Le agregué también como dice en la wiki una consulta individual antes para ligar la variable, pero nada Confused algo le estoy pifiando.

Igual no entiendo si el enunciado pide hacerlo con 1 argumento o con 2.
Se supone que el argumento debería ser de un parámetro, pensá que pregunta cuales son los rivales de Argentina, tendría que:

1. Buscar en la base de conocimiento a que grupo pertenece Argentina (p. ej.).
2. Devolver todos los que integren ese grupo, excepto Argentina (a cada uno le preguntará: "Sos Argentina?" -si, no-).
Acordate que en lógico lo único que devuelven los predicados es si matchearon o no...
Yo lo haría con 2 argumentos, utilizando el mismo predicado que hiciste:



?- esRival(argentina,X).
X = nigeria ;
X = japon ;
X = escocia.



Fuente: lo probé y funciona =P
Acordate de tocar el ";" para que te tire los resultados

Y tirate un esRival(X,Y) para ver la magia de Prolog
Spoiler: Mostrar
Como regla general, acordate que Prolog "se la banca" mientras definas predicados inversibles, el ejemplo tipico es, si vos haces una base de conocimiento que tenga:

predicado(a,b)


podes hacer 4 tipos de consultas:
a) la más basica, devuelve true o false

?- predicado(a,b)

b) una tipo "funcional", devuelve todos los X que unifican con b

?- predicado (X,b)

c) aca se nota que es mas "potente" que funcional, porque podes preguntar por cualquier argumento

?- predicado (a,X)

d) la mas grosa, devuelve todos los pares (a,b) que unifiquen

?- predicado (X,Y)


Esto hace que tengas que definir menos funciones (predicados) para hacer lo que tenes que hacer
No se puede con un solo argumento.

Los predicados no devuelven nada, sólo dicen si es verdadera o falsa una afirmación. En caso de ser verdadera con una variable, te dice qué valores hacen verdadera la afirmación.
A quien le tengo que creer? =P
Estamos más o menos diciéndote lo mismo, sólo que lo de sentey es un abuso de notación que roza con un error de concepto.

Los predicados sólo devuelven true o false indicando si matchean o no. El paradigma lo determina así, porque las cláusulas de horn lo determinan así.

La joda es que prolog, además, unifica tus variables libres con las respuestas que hacen cierta la condición. Entonces uno habla a lo bestia diciendo "te devuelve las respuestas que matchean", pero devolver está pésimamente dicho en esa frase.

Si tenés en cuenta lo que de verdad debería decir cuando escribió "devuelve", lo que puso es cierto.

Con un único parámetro no podés conocer los rivales de un equipo. Acordate que el predicado es una relación. unEquipo es rival de otroEquipo. esRival(unEquipo, otroEquipo).

Decir esRival(unEquipo) no relaciona mucho. "unEquipo es rival". OK, sí, podríamos decir que un equipo es rival si pertenece a algún grupo (digamos, polonia no figura en tu base de conocimientos, por lo que polonia no es un rival - esRival(polonia) devuelve false). La relación que vos estás buscando es entre dos participantes. "el rival de un equipo" involucra a dos participantes: al equipo, y a su rival. Por eso **necesitás** dos parámetros.


"¿A quién le tengo que creer?" es una pregunta super jodida de hacer. Digamos, en general, deberías ser vos el que decida a quién creerle. Es bastante heavy delegar esa responsabilidad a un tercero ;-)
(07-05-2014 02:41)Desert69 escribió: [ -> ]La joda es que prolog, además, unifica tus variables libres con las respuestas que hacen cierta la condición. Entonces uno habla a lo bestia diciendo "te devuelve las respuestas que matchean", pero devolver está pésimamente dicho en esa frase.

Si tenés en cuenta lo que de verdad debería decir cuando escribió "devuelve", lo que puso es cierto.
Aflojá un cacho, que sepas más no te da derecho a bardear.
Además, yo escribo esRival(argentina,X) y en la pantalla me aparecen equipos. Para mi, eso es devolver, mas allá de que sea o no el término o el concepto correcto del paradigma, la idea se entiende creo...
No, no es bardeo. Bah, no era la idea, no me malinterpretes. Digamos, no era un ataque personal.


Está mal dicho, es incorrecto _pensar_ que los predicados devuelven algo que no sea true o false, porque se te cae toda la joda del paradigma. Decir que un predicado devuelve cosas es algo que todos decimos, pero está mal. Es incorrecto. Decirlo es un abuso del lenguaje, pensarlo es pensar mal el paradigma.
(07-05-2014 13:46)Desert69 escribió: [ -> ]No, no es bardeo. Bah, no era la idea, no me malinterpretes. Digamos, no era un ataque personal.


Está mal dicho, es incorrecto _pensar_ que los predicados devuelven algo que no sea true o false, porque se te cae toda la joda del paradigma. Decir que un predicado devuelve cosas es algo que todos decimos, pero está mal. Es incorrecto. Decirlo es un abuso del lenguaje, pensarlo es pensar mal el paradigma.

Ok, todo bien entonces, entendí otra cosa. thumbup3
(07-05-2014 02:41)Desert69 escribió: [ -> ]Decir esRival(unEquipo) no relaciona mucho. "unEquipo es rival". OK, sí, podríamos decir que un equipo es rival si pertenece a algún grupo (digamos, polonia no figura en tu base de conocimientos, por lo que polonia no es un rival - esRival(polonia) devuelve false). La relación que vos estás buscando es entre dos participantes. "el rival de un equipo" involucra a dos participantes: al equipo, y a su rival. Por eso **necesitás** dos parámetros.

Con esto me quedó claro, gracias.
Hola gan, te dejo una posible resolucion.

Spoiler: Mostrar
% EJERCICIO 3
% -----------
% Escribir un programa Prolog que responda consultas acerca de cuáles son los rivales de una determinada
% selección en un campeonato mundial.
% Una selección tiene como rivales todos los otros equipos de su mismo grupo (¡nunca contra sí misma!).
% Incluir en el programa la siguiente información:
% El grupo A está formado por Colombia, Camerún, Jamaica e Italia.
% El grupo B está formado por Argentina, Nigeria, Japón y Escocia.
% El programa debe ser capaz de responder, p.ej., a la siguiente consulta:
% ¿cuáles son los rivales de Argentina? otorgando como respuestas "Nigeria", "Japón" y "Escocia".

pertenece(colombia,grupoA).
pertenece(camerun,grupoA).
pertenece(jamaica,grupoA).
pertenece(italia,grupoA).

pertenece(argentina,grupoB).
pertenece(nigeria,grupoB).
pertenece(japon,grupoB).
pertenece(escocia,grupoB).

proximosRivales(Equipo,Rivales):- pertenece(Equipo,Grupo), pertenece(Rivales,Grupo), Equipo\=Rivales.

Saludos,
Emilio.
URLs de referencia