Hechos: Ordenados y no ordenados Los hechos se especifican siempre delimitados por paréntesis, sirviendo éstos de separadores, pudiendo contener uno o varios símbolos.
Recuerda evitar el uso de las tildes, prueba tecleando:
(assert (nombre José))
El primer símbolo de un hecho se emplea a menudo para indicar una relación entre los restantes símbolos del hecho, p.e.:
(padre_de Juan Sara)
Siendo en ese caso importante el orden de los mismos. Son hechos ordenados.
Hechos: Ordenados y no ordenados En otras ocasiones el orden no es importante, hablaremos de hechos no ordenados, siendo simplemente una relación de campos, donde cada campo tiene su nombre y valor.
(datos–persona (nombre Juan) (apellido Perez))
Para estos últimos CLIPS requiere la definición previa de su plantilla, por medio del constructor deftemplate, para especificar el modelo del hecho.
Para los primeros, los ordenados, la plantilla correspondiente se define de forma automática.
Hechos: Plantillas Para definir una plantilla con el constructor deftemplate se especifica el nombre de cada campo:
(deftemplate datos-persona (slot nombre) (multislot apellidos) (slot edad) (slot peso) (slot altura) (multislot presion-arterial ) )
Utilizando (list-deftemplates) listamos los nombres de las plantillas definidas, mostrando su contenido con (ppdeftemplate ). Finalmente (undeftemplate ) permite eliminar la definición, siempre que no existan hechos en la base de hechos que sigan esa plantilla.
Hechos: Plantillas Los hechos ordenados permiten enlazar trozos de información. Un ejemplo podría ser el estado de forma de una persona:
(edad Samuel 20) (peso Samuel 80) (altura Samuel 188) (presion-arterial Samuel 130 80)
(edad Eva 23) (peso Eva 50) (altura Eva 155) (presion-arterial Eva 120 60)
Son varios datos unidos por el nombre, es más cómodo utilizar la plantilla: (assert (datos-persona (nombre Samuel) (edad 20) (peso 80) (altura 188) (presion-arterial 130 80)) )
Hechos: Plantillas Una plantilla permite definir además del nombre, el tipo, los valores por defecto y el rango de sus slots o campos. Los tipos posibles son: SYMBOL, STRING, NUMBER, INTEGER y FLOAT.
(deftemplate datos-persona (slot nombre (type STRING) (default ?DERIVE)) (slot edad (type FLOAT) (default (* 2.0 3.4)) (range 0.0 100.0)) )
Si ahora añadimos un hecho, asignará valores por defecto
CLIPS> (assert (datos-persona))
CLIPS> (facts) f-0 (initial-fact) f-1 (datos-persona (nombre "") (edad 6.8)) For a total of 2 facts.
Hechos: Plantillas Con ?DERIVE el valor por defecto se obtiene de las restricciones del campo. Por el contrario si se utiliza ?NONE el valor debe indicarse de forma obligatoria al realizar un assert.
(deftemplate dato (slot w (default?NONE)) (slot x (default?DERIVE)) (slot y (default(gensym*) )) (slot z (default-dynamic(gensym*) )) )
Al añadir un hecho sin asignar valores a esos campos ocurre:
CLIPS> (clear) CLIPS> (assert (dato)) [TMPLTRHS1] Slot w requires a value because of its (default ?NONE) attribute.
Hechos: Plantillas Para la plantilla del ejemplo anterior, si añadimos un hecho indicando un valor para el campo o slot w
CLIPS> (assert (dato(w 3)))
CLIPS> (assert (dato(w 4)))
CLIPS> (facts) f-0 (dato (w 3) (x nil) (y gen1) (z gen2)) f-1 (dato (w 4) (x nil) (y gen1) (z gen3)) For a total of 2 facts. CLIPS>
Se genera de forma automática un símbolo para los campos y y z. Esto se consigue con la función gensym que permite de forma automática asignar un símbolo
Hechos: Plantillas La función gensym retorna un símbolo único. Múltiples llamadas proporcionan identificadores de la forma genX siendo X un entero positivo.
La primera llamada retorna gen1, setgen permite configurar el primer valor, incrementándose el valor entero en las siguientes
(assert (new-id (gensym) flag1 7))
Genera en la primera llamada el hecho
(new-id gen1 flag1 7)
gensym* es similar pero produce un símbolo único actualmente no en uso dentro del entorno CLIPS
Hechos: Plantillas También es posible especificar los valores permitidos para un slot de una plantilla:
(deftemplate ficha-personal (slot nombre (type STRING)) (slot genero (type SYMBOL)(allowed-symbol hombre mujer) )
Hay otras opciones al especificar las restricciones:
allowed-symbols rico pobre allowed-strings "Ricardo" "Juan" "Pedro" allowed-numbers 1 2 3 4.5 -2.01 1.3e-4 allowed-integers -100 53 allowed-floats -2.3 1.0 300.00056 allowed-values "Ricardo" rico 99 1.e9
Hechos: Plantillas El constructor deftemplate no crea un hecho sino la forma que los hechos pueden tener. Reutilizando la plantilla datos-persona:
(assert (datos-persona (nombre Samuel) (edad 20) (peso 80) (altura 188) (presion-arterial 130 80)) )
Un campo o slot no definido toma el valor NIL a menos que se especificara alguna regla para su valor por defecto, y que no sea requerido (?NONE). El orden empleado al introducir la información puede alterarse al ser hechos no ordenados:
(assert (datos-persona (peso 150) (edad 23) (nombre Eva)))
Hechos: Plantillas La función modify permite modificar un slot, sin tener que emplear retract y assert para ello, conociendo el identificador:
(modify (altura 200))
Mostrando posteriormente los hechos tecleando facts observaremos el resultado.
Para duplicar un hecho utilizamos duplicate que se diferencia del modify en no realizar el retract, por lo que al final tendremos dos hechos en la base
(duplicate (altura 100))
Hechos: Plantillas Ejercicios:
Crea una plantilla y define para ella al menos cuatro campos, que no sean todos unicampo, definiendo su tipo y valores por defecto Lista las plantillas existentes Inserta dos hechos no ordenados Muestra los hechos Inserta otros dos hechos no ordenados sin proporcionar todos los campos Activa el modo watch para los hechos Inserta dos nuevos hechos y elimina posteriormente uno. Muestra los hechos Modifica uno de los hechos, duplica otro Muestra los hechos Elimina la plantilla
Reglas Las reglas permiten operar con los hechos y consecuentemente realizar programas con alguna utilidad.
Una regla se define con el constructor defrule acompañado del nombre de la regla, siguiendo la sintaxis:
SI un patrón o combinación de varios se cumple ENTONCES realiza una o varias acciones.
(defrule nombre_de_regla (hecho1) => (assert (hecho2)) )
No puede haber dos reglas con el mismo nombre.
Reglas Una descripción más genérica:
(defrule [] [(declare (salience ))] (patrón 1) (patrón 2) … (patrón N) => (acción 1) (acción 2) … (acción N) )
Reglas Una vez introducida una o varias reglas, tecleando (rules) aparecen los nombres de las presentes en la base de conocimiento. El contenido de una regla se muestra con (ppdefrule ) y (undefrule ) la elimina (* las elimina todas):
CLIPS> (defrule r1 (tiempo nublado) => (assert (llevar paraguas))) CLIPS> (rules) r1 For a total of 1 defrule. CLIPS> (ppdefrule r1) (defrule MAIN::r1 (tiempo nublado) => (assert (llevar paraguas))) CLIPS> (undefrule r1) CLIPS> (rules)
Reglas El motor de inferencia intenta emparejar o encajar los hechos de la lista de hechos con los patrones de las reglas.
Si el encaje ocurre para todos los patrones de una regla, ésta se activa o dispara. Esta comprobación para una regla sólo se realiza al añadirse nuevos patrones o hechos, o tras eliminar un elemento y volverlo a añadir.
La agenda almacena la lista de reglas activadas siguiendo un orden de prioridad.
Existen distintas estrategias de resolución de conflictos que permiten establecer criterios a la hora de insertar una activación de regla en la agenda.
Reglas Retomemos tras teclear (clear) nuestro el ejemplo de los colores (assert (color rojo)), añadamos la siguiente regla:
(defrule cielo (color azul) => (assert (cielo-es despejado)))
Al lanzar la evaluación de las reglas en base a la lista de hechos, con el comando (run), si existiera el hecho (color azul), se añadiría un nuevo hecho a la lista (cielo-es despejado), circunstancia que podemos comprobar con (facts) que no sucede
CLIPS> (run) CLIPS> (facts) f-0 (initial-fact) f-1 (color rojo) For a total of 2 facts.
Reglas Añadamos ahora el hecho (color azul), necesario para activar la regla, y ejecutamos
CLIPS> (assert (color azul))
CLIPS> (run) CLIPS> (facts) f-0 (initial-fact) f-1 (color rojo) f-2 (color azul) f-3 (cielo-es despejado) For a total of 4 facts.
Acabamos de ejecutar nuestro primer programa en CLIPS que añade un nuevo hecho.
Reglas Activemos ahora la depuración con los mismos hechos y reglas:
CLIPS> (reset) CLIPS> (assert (color azul) (color rojo)) CLIPS> (defrule cielo (color azul) => (assert (cielo-es despejado))) CLIPS> (watch facts) CLIPS> (watch rules) CLIPS> (run) FIRE 1 cielo: f-1 ==> f-3 (cielo-es despejado)
Se nos indica la regla activada y el hecho añadido, siendo útil para seguir el proceso seguido por el motor de inferencia
Reglas Para depurar programas CLIPS son útiles los comandos relacionados con puntos de ruptura:
• (set-break ): Establece un punto de ruptura antes de la ejecución de la regla • (remove-break []): Elimina un punto de ruptura establecido previamente • (show-breaks): Visualiza los puntos de ruptura establecidos
Las reglas poseen refracción: una regla sólo se dispara una vez para un conjunto dado de hechos, con lo que se evitan bucles infinitos.
Página anterior | Volver al principio del trabajo | Página siguiente |