CLIPS: patrones y variables

En esta entrada, como continuación a la anterior, vamos a profundizar un poco más en las posibilidades de CLIPS.

Antes de nada recordemos la regla que definimos en la última entrada:


(defrule si-llueve-te-mojas
    (llueve)
    (no-tiene carlos paraguas)
    =>
    (assert (se-moja carlos))
)

La regla nos dice que si está lloviendo y Carlos no tiene paraguas, éste se moja, sin embargo la regla peca de poco general. Es decir, ¿que ocurre si Juan no tiene paraguas y está lloviendo? ¿no se moja?, pues a no ser que contemos con otras reglas en el sistema que así lo especifiquen, Juan sería «inmune» a la lluvia. Sin saber nada más de CLIPS que lo explicado hasta ahora, una solución sería añadir una nueva regla similar pero sustituyendo el nombre de Carlos por el de Juan. No obstante, todo buen programador sabe que repetir código no es una buena práctica. Para subsanar este problema haremos uso de lo que se conoce como patrón.

Como explicamos cuando vimos la sintaxis de defrule, una regla se activa cuando existe algún hecho o conjunto de estos que cumpla los precedentes de la regla (parte de la regla anterior a «=>»). Hasta ahora, hemos interpretado «cumplir los precedentes» como que existan esos mismos hechos, es decir, para que se cumpla (no-tiene carlos paraguas) tiene que existir el hecho (no-tiene carlos paraguas); sin embargo, existe una forma de expresar los precedentes de la regla de forma menos especifica (más general). Lo mejor es empezar viendo un ejemplo:


(defrule si-llueve-te-mojas
    (llueve)
    (no-tiene ? paraguas)
    =>
    (assert (alguien-se-moja))
)

Fíjate en el segundo precedente de la regla, hemos sustituido carlos por «?», esto quiere decir que si existe el hecho (no-tiene fulanito paraguas), la regla se activará igual que para Carlos, Juan, o lo que sea. «?» es el carácter comodín e indica que puede haber cualquier símbolo en su lugar (pero sólo uno). A partir de ahora podemos decir que «cumplir los precedentes» significa que existan hechos que cumplan los patrones. Un patrón puede cumplirlo más de un hecho y un hecho puede cumplir varios patrones diferentes.

La pega de esto es que no sabemos quien se moja, por lo que no podemos insertar el hecho (se-moja fulanito). Para solucionar esto, daremos nombre al comodín:


(defrule si-llueve-te-mojas
    (llueve)
    (no-tiene ?x paraguas)
    =>
    (assert (se-moja ?x))
)

Ya está, con esta regla se insertara el hecho se-moja para cualquiera que no tenga paraguas.

Para terminar veamos algunos ejemplos un poco más interesantes:

(defrule numeros
    (mas-grande ?x dos)
    (mas-pequeño ?x cuatro)
    =>
    (assert (es-el-numero tres))
)

(defrule ave
    (tiene-alas ?objeto)
    (pone-huevos ?objeto)
    (es-animal ?objeto)
    =>
    (assert (es-ave ?objeto))
)

Cuando un símbolo queda ligado a una variable (?x, ?objeto), es obligatorio que en las próximas apariciones de la variable aparezca el mismo símbolo, es decir, si tenemos los hechos (tiene-alas avion), (pone-huevos serpiente) y (es-animal mono), la regla ave no se activará a pesar de que existe un hecho que cumple el patrón 1, otro que cumple el patrón 2 y otro que cumple el tercero. La razón de que esto sea así es que al comprobarse el primer patrón (tiene-alas ?objeto) con (tiene-alas avion), avion queda ligado a la variable ?objeto, con lo que para cumplirse los dos patrones siguientes, deberían existir los hechos (pone-huevos avion) y (es-animal avion).

Por tanto, debemos tener presente que una variable sólo puede estar ligada a un símbolo a la vez. Sin embargo, puede haber dos variables ligadas a un mismo símbolo, por ejemplo, la siguiente regla sería incorrecta semánticamente:


(defrule distintos
    (numero ?x)
    (numero ?y)
    =>
    (assert (son-distintos ?x ?y))
)

Las variables ?x e ?y pueden estar ligadas a un mismo símbolo, por ejemplo el 2, de modo que si tenemos el hecho (numero 2) la regla se activaría insertando el nuevo hecho (son-distintos 2 2).

Bueno, con esto y un poquito de imaginación ya se pueden hacer muchas cositas. En próximas entradas veremos más sintaxis en torno a los patrones para elavorar condiciones más complejas y empezaremos a utilizar listas.

1 Responses to CLIPS: patrones y variables

Deja un comentario