<commit_before>Antes que nada
--------------

El forall es un predicado, o sea, no conviene pensar qué "hace", sino qué relaciona, y/o cuándo se verifica.
El predicado forall conviene pensarlo por lo segundo, o sea cuándo se verifica.

Definición
----------

El forall recibe dos parámetros, los dos pueden verse como consultas. Las consultas se hacen sobre predicados, o sea que forall es un predicado de orden superior, porque puede manejar predicados entro de sus parámetros.

Hagámosnos la pregunta ... ¿cuándo se verifica?
Cuando a todos los que les pasa lo primero, les pasa lo segundo.
Dicho un poco más "en técnico", cuando todas las respuestas de la primer consulta son respuestas de la segunda.

Entonces, en las situaciones donde decimos "a todos los que ...blah... les pasa ...bleh..." es probable que el forall nos venga bien.

Un ejemplo
----------

partimos de estos hechos

    dulce(chocolate).
    dulce(caramelo).
    dulce(durazno).
    amargo(radicheta).
    amargo(cebada).

    leGusta(roque,chocolate).
    leGusta(roque,radicheta).
    leGusta(pepe,cebada).
    % ... y muchos hechos más que describen los gustos de un grupo de personas

    colorDePelo(roque,colorado).
    colorDePelo(pepe,castanio).
    % ... etc. con los colores de pelo

    vive(roque,buenosAires).
    vive(pepe,mendoza).
    vive(lucas,salliquelo).
    % ... y donde vive cada persona de la que queremos hablar

    ciudadGrande(buenosAires).
    ciudadGrande(mendoza).
    % ... y así todas las ciudades grandes

y queremos definir esTierno/1, donde decimos que una persona es tierna si todas las cosas que le gustan son dulces.

Estamos en un caso candidato a forall: "a todas las cosas que le gustan les tiene que pasar ser dulces". En Prolog:

`   esTierno(P):- forall(leGusta(P,Alim), dulce(Alim)).`

... P es tierno si ... todas las cosas que le gustan son dulces, exactamente lo que dijimos en castellano.

Ahora quiero definir el predicado alimentoCurioso/1, un alimento es curioso si solamente le gusta a gente de pelo colorado.
Para darme cuenta que el forall me puede servir, lo pienso en términos de "a todos los que ... les tiene que pasar ...". A veeer

-   a todas **las personas** que ... les gusta el alimento
-   les tiene que pasar ... ser coloradas

Queda

`   alimentoCurioso(A):- forall(leGusta(P,A), esColorado(P)).`

Tener claro lo que se quiere decir
----------------------------------

¿Está bien si defino esTierno así?

`   esTierno(P):- forall(dulce(Alim), leGusta(P,Alim)).`

Claramente no, porque estaría pidiendo que le gusten todos los alimentos dulces.

Si programar va a consistir en definir condiciones, es relevante entender la diferencia entre

  
todos los alimentos que le gustan son dulces

y

  
le gustan todos los alimentos dulces.

El forall en acción
-------------------

Supongamos que hacemos esta consulta:

`   ?- esTierno(roque).`

La P de esTierno se liga con roque ... entonces el forall se va a verificar (ver la defi técnica) cuando

-   todas las respuestas a la consulta
        leGusta(roque,Alim)

-   verifiquen la consulta
        dulce(Alim)

Para cada respuesta a la consulta leGusta(roque,Alim), la variable Alim se va a ligar, en el ejemplo hay dos respuestas, una con chocolate y otra con cebada.
La consulta correspondiente ya viene con esa variable ligada, o sea que las consultas que se tienen que verificar para que se verifique el forall son

`   esDulce(chocolate).`
`   esDulce(cebada).`

Volvamos a la definición: el forall se verifica si todas las respuestas a la primer consulta son respuestas de la segunda. Mirando el ejemplo de recién debería cerrar el esquema.

Forall e inversibilidad<commit_msg>Revision without comments imported from MediaWiki<commit_after>Antes que nada
--------------

El forall es un predicado, o sea, no conviene pensar qué "hace", sino qué relaciona, y/o cuándo se verifica.
El predicado forall conviene pensarlo por lo segundo, o sea cuándo se verifica.

Definición
----------

El forall recibe dos parámetros, los dos pueden verse como consultas. Las consultas se hacen sobre predicados, o sea que forall es un predicado de orden superior, porque puede manejar predicados entro de sus parámetros.

Hagámosnos la pregunta ... ¿cuándo se verifica?
Cuando a todos los que les pasa lo primero, les pasa lo segundo.
Dicho un poco más "en técnico", cuando todas las respuestas de la primer consulta son respuestas de la segunda.

Entonces, en las situaciones donde decimos "a todos los que ...blah... les pasa ...bleh..." es probable que el forall nos venga bien.

Un ejemplo
----------

partimos de estos hechos

    dulce(chocolate).
    dulce(caramelo).
    dulce(durazno).
    amargo(radicheta).
    amargo(cebada).

    leGusta(roque,chocolate).
    leGusta(roque,radicheta).
    leGusta(pepe,cebada).
    % ... y muchos hechos más que describen los gustos de un grupo de personas

    colorDePelo(roque,colorado).
    colorDePelo(pepe,castanio).
    % ... etc. con los colores de pelo

    vive(roque,buenosAires).
    vive(pepe,mendoza).
    vive(lucas,salliquelo).
    % ... y donde vive cada persona de la que queremos hablar

    ciudadGrande(buenosAires).
    ciudadGrande(mendoza).
    % ... y así todas las ciudades grandes

y queremos definir esTierno/1, donde decimos que una persona es tierna si todas las cosas que le gustan son dulces.

Estamos en un caso candidato a forall: "a todas las cosas que le gustan les tiene que pasar ser dulces". En Prolog:

`   esTierno(P):- forall(leGusta(P,Alim), dulce(Alim)).`

... P es tierno si ... todas las cosas que le gustan son dulces, exactamente lo que dijimos en castellano.

Ahora quiero definir el predicado alimentoCurioso/1, un alimento es curioso si solamente le gusta a gente de pelo colorado.
Para darme cuenta que el forall me puede servir, lo pienso en términos de "a todos los que ... les tiene que pasar ...". A veeer

-   a todas **las personas** que ... les gusta el alimento
-   les tiene que pasar ... ser coloradas

Queda

`   alimentoCurioso(A):- forall(leGusta(P,A), esColorado(P)).`

Tener claro lo que se quiere decir
----------------------------------

¿Está bien si defino esTierno así?

`   esTierno(P):- forall(dulce(Alim), leGusta(P,Alim)).`

Claramente no, porque estaría pidiendo que le gusten todos los alimentos dulces.

Si programar va a consistir en definir condiciones, es relevante entender la diferencia entre

  
todos los alimentos que le gustan son dulces

y

  
le gustan todos los alimentos dulces.

El forall en acción
-------------------

Supongamos que hacemos esta consulta:

`   ?- esTierno(roque).`

La P de esTierno se liga con roque ... entonces el forall se va a verificar (ver la defi técnica) cuando

-   todas las respuestas a la consulta
        leGusta(roque,Alim)

-   verifiquen la consulta
        dulce(Alim)

Para cada respuesta a la consulta leGusta(roque,Alim), la variable Alim se va a ligar, en el ejemplo hay dos respuestas, una con chocolate y otra con cebada.
La consulta correspondiente ya viene con esa variable ligada, o sea que las consultas que se tienen que verificar para que se verifique el forall son

`   esDulce(chocolate).`
`   esDulce(cebada).`

Volvamos a la definición: el forall se verifica si todas las respuestas a la primer consulta son respuestas de la segunda. Mirando el ejemplo de recién debería cerrar el esquema.

Qué pasa si no hay soluciones para el primer parámetro de forall?
-----------------------------------------------------------------

Qué pasa si consultamos si lucas es tierno y en nuestra base de conocimientos no hay nada que le guste?

`   ?- esTierno(lucas).`

Esta consulta va a ser cierta, porque si no le gusta nada, es cierto que todas las cosas que le gustan son dulces. Si nos interesa que sólo diga verdadero para las personas que les gusta algo, debemos agregar otra condición fuera del forall que lo asegure.

Forall e inversibilidad
{'fraction_non_alphanumeric': 0.09466632962588473, 'fraction_numerical': 0.0005055611729019212, 'mean_word_length': 3.1559873949579833, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1780721', 'n_tokens_mistral': 2720, 'n_tokens_neox': 2674, 'n_words': 1080}