Polimorfismo, functores, forall
01 de Julio, 2024
Tarea:
- Comenzar a hacer el TP grupal de lógico Rebelde güey
¿Qué vimos hoy?
- Forall
- Functores
- Pattern Matching
- Polimorfismo
Forall
Hasta ahora, estuvimos trabajando con cuantificadores existenciales, es decir, todas nuestras consultas eran del tipo:
∃x / p(x) => q(x)
Pero, sabemos que hay otro cuantificador, el universal. ¿Y cómo podemos trabajar con este cuantificador? 👀
Vamos a utilizar el predicado de orden superior forall/2
:
forall(antecedente, consecuente).
Para que el forall
responda verdadero, tiene que ocurrir que para todo antecedente que ocurra, su consecuente ocurre.
Por ejemplo, al definir el predicado escribioSoloComics/1
nos responde si todas las obras que alguien escribió son cómics.
escribioSoloComics(AutorOAutora) :-
escribio(AutorOAutora, _),
forall(escribio(AutorOAutora, UnaObra), esComic(UnaObra)).
Cuidado, ya que forall no es conmutativo, si por ejemplo hiciésemos:
forall(esComic(Obra), escribio(AutorOAutora, Obra)).
Esto, a diferencia de lo que hicimos en escribioSoloComics
, significa que para todo cómic que existe lo escribió ese AutorOAutora
.
Al igual que not
, el forall
es un predicado de orden superior ya que recibe predicados por parámetro. ¿Y por qué ligamos al AutorOAutora
antes de entrar al forall
? Porque, siguiendo con las similitudes con el not
, forall
no liga variables. Es por este motivo que tenemos que “generar” al AutorOAutora
antes de entrar al forall
pero teniendo la precaución de no ligar la Obra
, ya que queremos todas las obras de un/a artista.
Functores
Hasta ahora, en lógico siempre hicimos consultas en las cuales nuestros individuos eran simples. Pero además de los individuos simples, también existen los individuos compuestos. 🧐 Los functores son individuos complejos y tienen:
- Un nombre, o etiqueta, que los identifica.
- Una aridad.
En nuestra base de conocimientos teníamos obras, ahora conocemos los tipos de obras, que pueden ser:
novela(Tema, CantidadDeCapitulos)
libroDeCuentos(CantidadDeCuentos)
cientifico(Disciplina)
bestSeller(Precio, CantidadDePaginas)
Además contamos con un predicado esDeGenero/2
que relaciona a cada obras con su género (no confundir con el género de la novela).
Ahora queremos saber si una obra está buena, esto se cumple cuando:
- Es una novela policial y tiene menos de 12 capítulos.
- Es una novela de terror.
- Los libros con más de 10 cuentos siempre son buenos.
- Es un libro científico de fisicaCuantica.
- Es un best seller y el precio por página es menor a $50.
estaBuena(Obra):-
esDeGenero(Obra, novela(policial, Capitulos)),
Capitulos < 12.
estaBuena(Obra):-
esDeGenero(Obra, novela(terror, _)).
estaBuena(Obra):-
esDeGenero(Obra, libroDeCuentos(CantidadDeCuentos)),
CantidadDeCuentos > 10.
estaBuena(Obra):-
esDeGenero(Obra, cientifico(fisicaCuantica)).
estaBuena(Obra):-
esDeGenero(Obra, bestSeller(Precio, Paginas)),
Precio / Paginas < 50.
Si bien los functores se escriben como un predicado, NO son un predicado. Como ven, los estamos usando como parámetro en nuestras consultas.
Ahora, mirando 🔭 un poco a nuestro código anterior, podemos ver lógica repetida y eso no nos gusta mucho. 👎
Veamos cómo podríamos cambiar esto…
estaBuena(Obra):-
esDeGenero(Obra, Tipo),
esBuenGenero(Tipo).
esBuenGenero(novela(policial, Capitulos)):-
Capitulos < 12.
esBuenGenero(novela(terror, _)).
esBuenGenero(libroDeCuentos(CantidadDeCuentos)):-
CantidadDeCuentos > 10.
esBuenGenero(cientifico(fisicaCuantica)).
esBuenGenero(bestSeller(Precio, Paginas)):-
Precio / Paginas < 50.
Tenemos un par de cosas interesantes acá. 🤔
Primero, si prestamos atención a cómo definimos el predicado esBuenGenero
, podemos ver que estamos deconstruyendo (o abriendo) a los functores que representan el tipo de las obras.
Por ejemplo, en esta claúsula, el tipo va a unificar sólo con aquellas novelas que sean policiales.
esBuenGenero(novela(policial, Capitulos)):-
Capitulos < 12.
% además la variable Capitulos va a unificar
% con la cantidad de capítulos de esa novela
Además, cada functor va a “saber” con qué claúsula del predicado quedarse.
Todo esto gracias a que tenemos Pattern Matching. 🎉
En segundo lugar, podemos ver como al predicado esBuenGenero
no le importa para nada que forma puede llegar a tener el functor del tipo de la obra.
Al hecho de tratar variables indistintamente de su forma lo llamamos polimorfismo 💗 y va a ser un concepto muy importante y útil desde ahora hasta siempre. 😱
Links útiles:
Y saber mas sobre nosotros acá