Subido por Roberto Galeano

Curso Clips

Anuncio
Prof. Rafael Martínez Tomás
Desarrollo de Sistemas
Basados en el
Conocimiento en Clips
Objetivos y resumen inicial
➤ Qué es lo diferente en este tipo de programación,
una estructura y una orientación
➤ SBC y Sistemas Expertos
➤ Programación basada en reglas (conocimiento en
general) versus programación procedimental
➤ Necesidad de explicación del conocimiento
➤ Flexibilidad de entradas, conocimiento disponible
parcial
➤ Para qué tipos de problemas
Conocimiento e Inferencia
CONOCIMIENTO
Una persona con un préstamo debe tener
al menos 18 años de edad
Una persona con un sueldo hasta $10,000
puede obtener un préstamo máximo
de $2,000
Una persona con un sueldo entre $10,000
y $20,000 puede tener un préstamo
máximo de $3,000
◆
INFORMACiÓN
Eduardo tiene un préstamo de $2,500
Juan tiene un préstamo de $1,750
INFORMACIÓN
Gina Smith tiene una comunicación
interauricular, 1 cm x 3,5 cm
◆
Si A entonces B
A
B
CONOCIMIENTO
El tabique auricular divide las cámaras
de la aurícula derecha e izquierda del
corazón humano.
Si A y B entonces C
A
B
Si A entonces B
Si B entonces C
A
C
B, C
Representación y búsqueda
Se dispone de dos cántaros de agua, uno de 4 litros y otro de 3 litros de capacidad, siendo ésta la única
información que se tiene de los mismos. Existe una bomba de agua con la que se pueden llenar los
cántaros. Se desea que el cántaro de 4 ls. de capacidad quede lleno por la mitad y el de 3 ls. vacío.
1. (x, y) --> (4, y) Llenar el cántaro de 4 ls.
si x < 4
2. (x, y) --> (x, 3) Llenar el cántaro de 3 ls.
si y < 3
3. (x, y) --> (0, y) Vaciar en el suelo el cántaro de 4 ls.
si x > 0
4. (x, y) --> (x, 0) Vaciar en el suelo el cántaro de 3 ls.
si y > 0
5. (x, y) --> (4, y − (4 − x)) Verter agua del cántaro de 3 ls. al de 4 hasta llenarlo.
si x + y ³ 4,
y>0y
x<4
6. (x, y) --> (x − (3 − y), 3) Verter agua del cántaro de 4 ls. al de 3 hasta llenarlo.
si x + y ³ 3,
x>0e
y<3
7. (x, y) --> (x + y, 0) Verter todo el agua del cántaro de 3 ls. al de 4.
si x + y £ 4 e
y>0
8. (x, y) --> (0, x + y) Verter todo el agua del cántaro de 4 ls. al de 3.
!4
Buscando la solución
!5
El problema de la búsqueda
Espacio del problema o
espacio de
representación
Conjunto de estados
+
Conjunto de
operadores
Instancia del problema
Espacio del problema
+
Estado inicial
+
Estado objetivo o meta
!6
Búsqueda en Árboles
ABIERTA = (inicial)
mientras NoVacia(ABIERTA) hacer
n=ExtraePrimero(ABIERTA);
si EsObjetivo(n) entonces
devolver Camino(inicial, n); {desde TABLA_A}
fin-si;
nodo anterior
S=Sucesores(n);
q
n
para cada q de S hacer
pone q en la TABLA_A con
Anterior(q)=n
Coste(inicial, q)= Coste (inicial, n)*Coste(n,q);
Inserta q en ABIERTA;
fin-para;
fin-mientras;
devolver “no encontrado”;
coste
desde
inicio
!7
Búsqueda en Grafos
• Parte de un grafo dirigido simple, definido implícitamente a partir de un nodo inicial y una serie de
operadores o reglas de producción.
• Cada regla tiene un coste, de tal forma que no existen caminos infinitos. Es localmente finito, cada
nodo tiene un nº finito de sucesores
ABIERTA = (inicial)
mientras NoVacia(ABIERTA) hacer
n=ExtraePrimero(ABIERTA);
si EsObjetivo(n) entonces
devolver Camino(inicial, n);
fin-si;
S=Sucesores(n);
Añade S a la entrada de n en la TABLA_A
para cada q de S hacer
si (q pertenece a TABLA_A) entonces
Rectificar(q, n, Coste(n,q));
Ordenar(ABIERTA); {si es preciso}
nodo
si no
pone q en la TABLA_A con
B
Anterior(q)=n
Coste(inicial, q)= Coste (inicial, n)*Coste(n,q);
ABIERTA=Mezclar (q, ABIERTA); genérica
fin-si
fin-para;
fin-mientras;
devolver “no encontrado”;
anterior
anterior
coste
desde
inicio
1
lista de
sucesores
c(2),d(2)
!8
Rectificación de nodos
Funcion Rectificar(n, p, costepn);
si (Coste(inicial, p) + costepn < Coste(inicial, n)) entonces
Modifica la entrada del nodo n en la TABLA_A con
Coste(inicial, n) = Coste(incial, p) + costepn;
Anterior(n) = p;
RectifcarLista(n);
fin-si
Funcion RectificarLista(n);
LISTA = Sucesores(n);
para cada q de LISTA hacer
Rectificar(q, n, Coste(n,q);
fin-para
!9
Un ejemplo en lógica
El cabo Romerales de la policía de Colmenarete se enfrenta a un nuevo caso de robo. El dueño de una joyería
denuncia a Paco Navaja, Pedro Boina y José el Melenas, porque dice que el o los ladrones de su
establecimiento debe estar entre ellos tres. Romerales conoce bien a los tres, de los que dispone de un gran
historial. De estos archivos se deduce que Paco Navaja trabaja siempre con un cómplice, pero solo uno. Los
otros dos rufianes nunca trabajarían ellos dos juntos sin un tercero. Estos dos han declarado dando sendas
coartadas el uno del otro. Si uno de ellos fuera inocente, no tendría por qué mentir y el otro, por tanto,
también sería inocente. ¿A qué conclusión llegó el cabo Romerales?
Paco es culpable: p
Pedro es culpable: q
José es culpable: r
Paco Navaja trabaja siempre con un cómplice, pero solo uno:
p -> (q xor r)
Los otros dos rufianes nunca trabajarían ellos dos juntos sin un tercero:
(q and r) -> p
Si uno de ellos fuera inocente, no tendría por qué mentir y el otro, por tanto, también sería inocente:
-q <-> -r
!10
Un ejemplo de tarea: Planificación
◆
Establecer una series de pasos que conduzcan
a la consecución de un objetivo.
◆
Se fundamenta en algoritmos de búsqueda en
un espacio de estados,
Depositar(x),
Precond: Agarrado(x)
Añadir: Sobre-la-mesa(x) ∧ Brazo-Libre
➤ estado inicial
Eliminar: Agarrado(x)
➤ operadores cuyos resultados se evalúan
➤ un estado que satisfaga las restricciones de
objetivo final
Apilar(x,y),
Precondición: Despejado(y) ∧ Agarrado(x)
Añadir: Brazo-Libre ∧ Sobre(x,y)
Eliminar: Despejado(y) ∧ Agarrado(x)
Desapilar(x,y),
Precond: Sobre(x,y) ∧ Despejado(x) ∧ Brazo-Libre
SOBRE(B,A) ∧ SOBRE-LA-MESA(A) ∧ SOBRE-LA-MESA(C) ∧
SOBRE-LA-MESA(D) ∧ BRAZO-LIBRE
Añadir: Agarrado(x) ∧ Despejado(y)
Eliminar: Sobre(x,y) ∧ Brazo-Libre
Coger(x),
Precond: Despejado(x) ∧ Sobre-la-mesa(x) ∧ Brazo-Libre
Añadir: Agarrado(x)
SOBRE(C,A) ∧ SOBRE(B,D) ∧ SOBRELA-MESA(A) ∧ SOBRE-LA-MESA(D)
Eliminar: Sobre-la-mesa(x) ∧ Brazo-Libre
!11
Representación en reglas
REGLAS:
IF
está disponible el recuento completo de células
sanguíneas y
el número de células blancas es menor
de 2500
THEN
las siguientes bacterias podría causar la
infección:
E.coli (0.75)
Pseudomonas-aeruiginosa (0.5)
Klebsiella-pneumoniae (0.5)
!12
Inferencia sobre reglas
• Encadenamiento hacia adelante:
regla 1: IF A entonces B
regla 2: IF B entonces C
Dado A podemos afirmar B, con lo que
llegamos a afirmar C
• Encadenamiento hacia atrás:
regla 1’: IF A y D entonces B
Planteamos C, lo que obliga a buscar B, lo que
obliga a buscar A y D
!13
Sistemas Basados en el Conocimiento (SBCs)
Representación explícita del conocimiento utilizado para
resolver el problema. Estructura:
conocimiento
If... Then...
motor de
inferencia
datos
resultados
➤ un componente declarativo,
denominado base de
conocimiento, que representa lo
que se supone conoce un agente
especializado en un determinado
tipo de problemas,
➤ un procedimiento diseñado para
simular un proceso de
razonamiento cuyas premisas son
los datos pregunta y que llega a
las posibles respuestas usando los
elementos de la base de
conocimiento
!14
Necesidad de modelado conceptual
Regla 1: If..Then..
Regla 2: If..Then..
Regla 3: If..Then..
Regla 4: If..Then..
Regla 5: If..Then..
Regla 6: If..Then..
Regla 7: If..Then..
..
Regla 2001: If..Then..
Base de conocimiento
única y plana
Hechos
Inferencia
A
Reglas inferencia A
Regla 1: If..Then..
Regla 7: If..Then..
Regla 23: If..Then..
Reglas inferencia B
Regla 31: If..Then..
Regla 57: If..Then..
Regla 96: If..Then..
Reglas asociadas a sus correspondientes
procesos de razonamiento.
Hechos
Inferencia
B
Hechos
!15
Diferenciación del conocimiento
◆ Conocimiento
del dominio (ontologías)
◆ Conocimiento inferencial
◆ Conocimiento de tareas
Diferentes PSM-Tareas infiriendo sobre un
mismo conocimiento del dominio
!16
Tipos de problemas
Tareas
Análisis
Identifica
Monitoriza
Clasifica
Síntesis
Modificación
Predice
Predice
Comportamiento
Repara
Predice
Valores
Supervisión
Control
Plan
Configura
Modela
Diseña
Diagnostica
!17
Tipos de diagnóstico
!
Diagnose
!!
!
Abstract
Match
!
!
!
Heuristic
Sugest-Confirm
!!
Refine
! !
Sistematic
!
Sugest
!!
Confirm
Diagen
!
! !
Cover-differentiate
-
!
...
!
...
Ejemplo de modelo de interpretación:
Diagnóstico Abductivo
alarma
hemorragia
Prueba de RumpellLeede = Negativa
reglas de dependencia
de alteraciones
recubre
hipótesis
Fragilidad
vascular alta
modelo causal
predice
obtiene
hallazgo
esperado
Prueba de Rumpellmodelo de manifestaciones Leede = Positiva
hallazgo
observado
compara
resultado
distinto
Diagnóstico Heurístico
Datos abstractos
match
abstract
refine
Datos
Portador
comprometido
Infección Gramnegativa
Inmunosuprimido
Abstracción por
generalización
Leucopenia
Abstracción
por definición
WBC bajo
Abstracción
cualitativa
Recuento de
células blancas
menor de 2500
Solución
Match causal
Abstracción por
generalización
Solutiones
abstractas
Refinamiento
(subtipo)
Infección E.coli
El ciclo del conocimiento
•
•
Externalización
Socialización
•
•
•
In (Patel et al, 2009) by Stefanelli
Internalización
Combinación
Adquisición del conocimiento: del texto al
modelo
!22
Aprendiaje automático
Wij$
Wjk$
Entradas$
Salidas$
Capa$
entradas$
deep
learning
Capa(,s)$
oculta$
RNA’s$
CLUSTERING(
APRENDIZAJE$
BAYESIANO$
SVM$
Capa$
salidas$
APRENDIZAJE$
POR$REFUERZO$
Presión(Arterial?(
APRENDIZAJE$
DE$CONCEPTOS$
ALGORITMOS$
EVOLUTIVOS$
A
lt
a(
Aplicaciones(
SI(
Gota?(
APRENDIZAJE$
DE$REGLAS$
APRENDIZAJE$
ESTADÍSTICO$
SI(
N
o
S
í
No
rm
al(
NO(
B
aj
a(
Hipo2roidismo?(
SI(
N
o
S
í
NO(
ÁRBOLES$DE$DECISIÓN$
Motores(de(búsqueda,(diagnós2co(médico,(detección(de(fraude(en(el(uso(de(
tarjetas(de(crédito,(análisis(del(mercado(de(valores,(clasificación(de(
secuencias(de(ADN,(reconocimiento(del(habla(y(del(lenguaje(escrito,(juegos(y(
robó2ca.(
!23
C Language Integrated Production System,
CLIPS
Desarrollada por Software Technology Branch de la NASA/Lyndon B. Johnson Space Center
Características:
- 3 paradigmas de programación:
* programación basada en reglas: reglas+ hechos (facts)
* programación procedural: funciones
* programación orientada a objetos: objetos+paso de mensajes
- CLIPS es una herramienta escrita en C
- Plena integración con otros lenguajes como C y ADA
- Desde un lenguaje procedural se puede llamar a un proceso CLIPS, éste realiza su función
y luego le devuelve el control al programa.
- Se puede incorporar código procedural como funciones externas en CLIPS
- Las reglas pueden hacer "pattern-matching" sobre objetos (COOL) y hechos formando así
un sistema integrado.
- Encadenamiento hacia adelante.
- CLIPS tiene una sintaxis estilo LISP que utiliza paréntesis como delimitadores.
- Tiene versión en java (Jess) y versión con lógica difusa fuzzy (FuzzyClips)
Componentes:
- Memoria Global o Base de Hechos (hechos + instancias de objetos)
- Base de Conocimientos o Reglas (reglas)
- Motor de Inferencia (control)
!24
Hechos (facts)
• Los hechos representan un conjunto de variables, propiedades y valores que
éstas pueden tomar.
• Número ilimitado de campos separados por blancos y encerrados entre
paréntesis balanceados. Los campos pueden tener o no un nombre asignado.
• Todos los hechos tienen un identificador por el que puede ser referenciado.
• CLIPS define por defecto un hecho inicial (initial-fact) cuando se carga la
aplicación.
• Todos los hechos se insertan en la lista fact-list. Se puede ver esta lista con el
comando (facts)
Ejemplos:
(Antonio 45678 conductor Barcelona)
(Empleado (nombre Antonio) (id 45678) (puesto conductor) (ubicacion Barcelona))
!25
Tipos de Hechos
Hechos ordenados:
• son básicamente listas
• los campos no tienen nombre asignado y pueden ser de cualquier tipo primitivo
de datos, excepto el primero, que debe ser un símbolo
• el orden de los campos es significativo
• tipos de los campos: float, integer, symbol, string, external-address, fact-address,
instance-name, instance-address
Ejemplo: (Antonio 45678CLZ conductor Barcelona)
!26
Tipos de Hechos
Hechos estructurados:
- Definen un grupo de campos o atributos en una estructura similar a un registro. No
importa el orden en el que se referencia el campo y/o el orden en el que aparezcan los
campos
- deftemplate que define una lista de campos con nombres que se denominan slots.
- Es solamente una estructura, por lo que hay que afirmar los hechos que se ajusten a
esa estructura.
(deftemplate <nombre> [<comentario>] <definición-slot>*)
(deftemplate vehiculo
(slot matricula)
(slot color)
(slot propietario)
(slot antiguedad)
(Probar el entorno)
(slot cilindrada)
(slot kilometraje))
(assert (vehiculo (matricula xyz) (color rojo...
!27
Funciones sobre hechos
assert: (assert <fact>*) inserta el hecho/s en la Base de Hechos
retract: (retract <fact-index>*) elimina el hecho/s en la Base de Hechos
modify: (modify <fact-index>* (slot new-value)) modifica el hecho
(Probar el entorno)
!28
Atributos de los Slots (facets)
- Son características que ayudan en el desarrollo y mantenimiento de un SE
proporcionando un fuerte tipado y comprobación de restricciones.
type
(type <especificación-tipo>)
- Define el tipo de datos que puede tener el slot.
- Los tipos válidos son: SYMBOL, STRING, LEXEME, INTEGER, FLOAT,
NUMBER. - Si se especifica ?VARIABLE, significa que el slot puede tomar
cualquier tipo de dato (por defecto, se supone este).
- LEXEME equivale a especificar SYMBOL y STRING conjuntamente,
- NUMBER equivale a INTEGER y FLOAT.
(deftemplate persona
(multislot nombre (type SYMBOL))
(slot edad (type INTEGER))
)
(Probar en el entorno)
!29
Restricciones de los Slots
allowedallowed-symbols, allowed-strings, allowed-lexemes, allowed-integers,
allowed-floats, allowed-numbers y allowed-values.
Los atributos allowed- no restringen el tipo del slot. En el ejemplo,
allowed-symbols no restringe el tipo del slot sexo a ser un símbolo. Sólo
indica que si el valor del slot es un símbolo, entonces debe ser el símbolo
hombre ó el símbolo mujer. En el ejemplo, cualquier string, entero o real sería
legal para el slot sexo si no se especificara (type SYMBOL).
(deftemplate persona
(multislot (nombre (type SYMBOL))
(slot edad (type INTEGER))
(slot sexo (type SYMBOL)( allowed-symbols hombre mujer))
)
range
cardinality
(range <valor-min> <valor-max>)
(cardinality <valor-min> <valor-max>)
!30
Valor inicial en los Slots
default
(default <especificación>)
Permite especificar un valor por defecto para un slot cuando no se le ha dado valor
en la afirmación del hecho.
(deftemplate ejemplo
(slot a)
;;; el tipo se supondrá SYMBOL
(slot b (type INTEGER))
(slot c (allowed-values rojo verde azul))
(multislot d) ;;; por defecto contendrá el valor ()
(multislot e (cardinality 2 2)
(type FLOAT)
(range 3.5 10.0)))
Al afirmar un hecho sin dar ningún valor a ninguno de sus slots, el hecho
realmente contendría lo siguiente:
(ejemplo (a nil) (b 0) (c rojo) (d) (e 3.5 3.5))
!31
Definición y afirmación del conocimiento
inicial
deffacts
(deffacts <nombre-colección-hechos> <hecho>*)
permite especificar un conjunto de hechos como conocimiento inicial.
(deffacts estudiante "Estudiantes al inicio del curso"
(estudiante (nombre Juan) (sexo varon) (fuma? no) (alojado no))
(estudiante (nombre Pepe) (sexo varon) (fuma? si) (alojado no))
(estudiante (nombre Luisa) (sexo mujer) (fuma? no) (alojado no))
(estudiante (nombre Pedro) (sexo varon) (fuma? no) (alojado no)))
El comando reset afirma los hechos iniciales (initial-fact) y los definidos con
deffacts
!32
Variables
• Variables locales
?variable permite el pattern-matching
$?variable, especial para multivalores
• Variables globales
Permiten almacenar valores accesibles en reglas y funciones, muy útiles para
resultados
(defglobal
?*num* = 3
?*suma* = (+ ?*num* 2)
?*cadena* = “hola”
?*lista* = (create$ a b c)
)
Pueden aparecer en la parte izquierda de las reglas si no son utilizadas para
asignar un valor y su cambio no activa las reglas, pero no pueden ser parámetros
de funciones ni métodos
!33
Comodines
• sencillo ?
• múltiple $?
Ejemplos:
(courses (numbers $?course_nums))
(printout t “Your courses are” $?course_nums crlf))
(list ? $? c ?)
encaja con:
(list a b f c e), (list a d c b)
pero no con:
(list c), (list c d), (list a c d b)
(do picnic on Sunday)
encaja con:
(do ? ? Sunday)
(do ? on ?)
(do ? on ?when)
(do $? )
(do $? Sunday)
(do ?chore $?when)
!34
Estructura de una regla Clips
defrule
(defrule <nombre-regla> [<comentario>]
<elemento-condición>* ; Parte izquierda (LHS)
=>
<acción>*) ; Parte dcha. (RHS) de la regla
(defrule evaluar-hallazgos-V1
(datos-paciente (id ?paciente) (edad ?edad&:(> ?edad 65)))
?hallazgos <- (hallazgos-paciente (id-paciente ?paciente)
(hallazgos $?lista-hallazgos))
=>
(modify ?hallazgos (hallazgos V1))
EC1
EC2
EC3
LHS
A1
RHS
)
Si una regla no tiene parte izquierda, entonces el hecho (initial-fact) actuará como el elemento
condicional para ese tipo de reglas, y la regla se activará cada vez que se ejecute un comando reset.
!35
Satisfacibilidad y ejecución de una
regla Clips
Se deben verificar cada una de los ECs. Para ello:
1. Para ello deben existir los hechos especificados en las ECs
2. Se deben verificar las expresiones sobre ellos.
Una regla se ejecuta cuando:
1. todos sus ECs son satisfechos por la base de hechos
2. el motor de inferencia la selecciona.
Ejecutar una regla supone ejecutar las acciones de la RHS
(defrule regla-ejemplo "Ejemplo de regla"
(frigorifico interruptor encendido)
(frigorifico puerta abierta)
=>
(assert (frigorifico comida estropeada)))
!36
Elementos Concionales (ECs)
Tipo pattern:
Con restricciones literales.
(temperatura 28 grados)
Con operadores lógicos.
(opcion-elegida 1|2|3)
(num-pacientes ~0)
Con comodines simples y multicampo.
(opcion-elegida ~1&~2&~3)
(temperatura ? grados)
(pacientes $? Lopez $?)
Con predicados o llamadas a funciones:
(temperatura (maximo ?tmax)
Con variables simples y multicampo.
(corporal ?t &:(> ?t ?tmax)))
(temperatura ?t grados)
(pacientes ?primero $?resto)
!37
Elementos Concionales (ECs)
Tipo test:
(test <llamada-a-función>)
(temp-max ?tmax)
(temp-corporal ?t)
(test (>= ?tmax ?t)
Tipo or:
(or <elemento-condicional>+)
(or (temperatura-corporal alta)
(presion-arterial baja))
Tipo and:
(and <elemento-condicional>+)
(or (and (presion-arterial baja) (temperatura-corporal baja))
(and (presion ?p&:(<?p 1500) (temperatura ?t&:(< ?t 35)
!38
EC que carga el índice del hecho
?<var-direccion> <- (<elemento-condicional>)
(defrule elimina-pacientes-fiebre
?fiebre <- (paciente (nombre ?n) (temp-ahora ?t &: (> ?t 37)))
=>
(printout t "El paciente: " ?n “ tiene fiebre” crlf)
(retract ?fiebre)
)
!39
Acciones de la RHS
Acciones para modificar la base de hechos:
assert: (assert <fact>*) inserta el hecho/s en la Base de Hechos
retract: (retract <fact-index>*) elimina el hecho/s en la Base de Hechos
modify: (modify <fact-index>* (slot new-value)) modifica el hecho
(problema del modify)
Acciones procedurales:
Asignación a una variable
(bind <variable> <expresión>*)
(sólo en la RHS)
Condicional:
(if <expresión> then <acción>+ [else <acción>+])
(switch <expresión-test> <sentencia-case><sentencia-case>+
[(default <acción>*)])
<sentencia-case> ::= (case <comparación> then <acción>*)
Iteraciones:
(while <expresión> [do] <acción>*)
(loop-for-count (<var> <inicio> <final>) [do] <acción>*)
(break)
!40
Acciones de la RHS
Comandos sobre la agenda: clear, halt, run
Funciones predefinidas
Funciones de entorno:
(load <nombre-de-fichero>)
(load-facts <nombre-de-fichero>)
(save <nombre-de-fichero>)
(save-facts <nombre-de-fichero>)
(exit) ; cierra el entorno Clips
Matemáticas: abs, div, mod, round..., sin, cos..
(<op> <expresión-numérica> <expresión-numérica>+)
E/S: (open <nombre-fichero> <nombre-lógico> [<modo>])
(close [<nombre-lógico>])
(read [<nombre-lógico>])
(printout <nombre-lógico> <expresión>*)
Strings: (str-cat <expresión>*)
(sym-cat <expresión>*)
(str-index <expresión-lexema> <expresión-lexema>)
(sub-string <inicio> <fin> <expresión-de-cadena>)
(str-length <expresión-simbólica-o-de-cadena>)
!41
Funciones para valores multicampo
Funciones predefinidas
Manipulación de valores multicampo:
(create$ <expresión>*)
(delete$ <expresión-multicampo> <posición-inicio><posición-final>)
(explode$ <expresión-string>)
(first$ <expresión-multicampo>)
(rest$ <expresión-multicampo>)
(implode$ <expresión-multicampo>)
(insert$ <expr-multicampo> <expr-entera><expresión-simple-o-multicampo>+)
(length$ <expresión-multicampo>)
(member$ <expresión-campo-simple> <expresión-multicampo>)
(nth$ <expresión-entera> <expresión-multicampo>)
(replace$ <expresión-multicampo> <inicio> <final><expresión-simple-o-multicampo>)
(subseq$ <expresión-multicampo> <inicio> <final>)
!42
Funciones definidas por el usuario
(deffunction <nombre> [<comentario>] (<parámetro>* [<parámetro-comodín>])
<acción>*
)
El valor devuelto por la función es la última acción o expresión evaluada dentro de
la función. Si una deffunction no tiene acciones, devolverá el símbolo FALSE. Si se
produce algún error mientras se ejecuta la función, cualquier otra acción de la
función aún no ejecutada se abortará, y la función devolverá el símbolo FALSE.
Ejemplo:
(deffunction respuesta_si_no (?pregunta)
(bind ?respuesta (preguntar ?pregunta si no s n))
(if (or (eq ?respuesta si)
(deffunction preguntar (?pregunta $?valores-permitidos)
(eq ?respuesta s))
(printout t crlf ?pregunta)
then TRUE
(bind ?respuesta (read))
else FALSE))
(if (lexemep ?respuesta) then
(bind ?respuesta (lowcase ?respuesta)))
(while (not (member ?respuesta ?valores-permitidos)) do
(printout t ?pregunta)
(bind ?respuesta (read))
(if (lexemep ?respuesta)
then (bind ?respuesta (lowcase ?respuesta))))
?respuesta)
!43
Otro ejemplo de entrada
(bind ?carroceria 0)
(while (or (< ?carroceria 1)(> ?carroceria 5))
(printout t crlf "Estado de la carroceria:")
(printout t crlf "1 - Muy bueno")
(printout t crlf "2 - Bueno")
(printout t crlf "3 - Regular")
(printout t crlf "4 - Malo")
(printout t crlf "5 - Muy malo")
(printout t crlf ": ")
(bind ?carroceria (read))
)
(defrule pide-datos-iniciales "Pide los datos de matricula y anio de matriculacion"
(initial-fact)
=>
(printout t crlf "Datos del vehiculo")
(printout t crlf "Matricula: ")
(bind ?matricula (read))
(printout t crlf "Anio de matriculacion: ")
(bind ?anio (read))
(assert (vehiculo (matricula ?matricula)(anio-matriculacion ?anio)))
)
!44
Ejemplo de Switch
Ejemplo:
(defrule precio_mecanico ""
?f2 <- (estado mecanico ?mec)
=>
(retract ?f2)
(if (or (eq ?mec leves) (eq ?mec graves)) then
(bind ?respuesta (preguntar_valor "Cuál es el precio de las reparaciones
mecánicas suministrado por los mecánicos (Pesetas): " )))
(switch ?mec
(case ninguna then (assert (estado mecanico ?mec 0)))
(case leves then (assert (estado mecanico ?mec ?respuesta)))
(case graves then (assert (estado mecanico ?mec ?respuesta)))
(case gravisimas then (assert (tasacion nula "Las reparaciones son
demasiado costosas")))))
!45
Ejemplos de funciones
(deffunction CalculaPorcentajeEntero(?Num ?Porcentaje)
(bind ?ParteEntera (div (* ?Num ?Porcentaje) 100))
(bind ?Resto (mod (* ?Num ?Porcentaje) 100))
(if (> ?Resto 0.5) then
(bind ?Resultado (+ ?ParteEntera 1))
else
(bind ?Resultado ?ParteEntera)
)
)
Otro ejemplo de captura:
(deffunction es-del-tipo (?respuesta ?tipo ?posibilidades)
;; Si es de tipo mutiple recorre las posibilidades y devuelve TRUE si alguna coincide.
;;;En caso contrario devuelve FALSE.
(if (eq ?tipo multiple) then
(progn$ (?item ?posibilidades)
; para cada elemento de la lista ?posibilidades
(if (eq ?respuesta ?item) then
;si coincide con la respuesta
(return TRUE)))
; devuelve TRUE
(return FALSE))
;; Si es de tipo numerico devuelve TRUE si la respuesta lo es y FALSE en
;; caso contrario.
(if (eq ?tipo numerico) then
(return (numberp ?respuesta)))
;; Para los demas casos devuelve TRUE si la respuesta tiene una longitud
;; mayor que 0 y FALSE en caso contrario.
(return (> (str-length ?respuesta) 0)))
!46
Ejemplo de llamada desde una regla
(deffunction factorial (?X)
(bind ?temp 1)
(loop-for-count (?i 1 ?X) do
(bind ?temp (* ?temp ?i))
)
(return ?temp)
)
(defrule ejemplo
=>
(printout t crlf crlf "Calcular factorial de: ")
(bind ?N (read))
(printout t "El resultado es " (factorial ?N) crlf)
)
!47
El mismo proceso en una regla
(defrule factorial
=>
(printout t crlf crlf "Enter a number: ")
(bind ?N (read))
(bind ?temp 1)
(loop-for-count (?i 1 ?N) do
(bind ?temp (* ?temp ?i))
)
(printout t "Factorial=" ?temp crlf)
)
!48
Un bucle implícito
(deffacts numbers
(number 56)
(number -32)
(number 7)
(number 96)
(number 24))
(defrule find-largest-number
(number ?x)
(not (number ?y &: (> ?y ?x)))
=>
(printout t “Largest number is “ ?x crlf))
!49
(deffacts initial-information ;datos de los rectangulos de cuyas areas se obtendra la media
(rectangle 10 6)
(rectangle 7 5)
(rectangle 6 8)
(rectangle 2 5)
(rectangle 9 4)
(sum 0)
(count 0))
Un bucle menos implícito
(defrule sum-rectangles
(declare (salience 30))
(rectangle ?height ?width)
=>
(assert (add-to-sum (* ?height ?width)))) ; crea un hecho add-to-sum por cada rectangulo
(defrule sum-areas
(declare (salience 20))
;;; regla que suma todas las areas
?sum-adr <- (sum ?total)
?new-area-adr <- (add-to-sum ?area)
?count-adr <- (count ?counter)
=>
(retract ?sum-adr ?new-area-adr ?count-adr)
(assert (sum (+ ?total ?area)))
(assert (count (+ ?counter 1))))
(defrule average
(declare (salience 10))
;;; regla que calcula e imprime la media
?sum-adr <- (sum ?total)
?count-adr <-(count ?counter)
=>
!50
(printout t crlf "Here is the average area" (/ ?total ?counter) crlf))
Funciones de E/S
(open <nombre-fichero> <nombre-lógico> [<modo>])
Abre un fichero con el modo especificado (“r”, “w”, “r+”, “a”) asociando el nombre
de fichero dado al nombre lógico especificado. Si no se especifica modo, se supone “r”
(close [<nombre-lógico>])
Cierra el fichero asociado con el nombre lógico especificado. Si no se especifica el
nombre lógico, se cierran todos los ficheros.
(printout <nombre-lógico> <expresión>*)
Evalúa e imprime como salida al nombre lógico 0 o más expresiones no formateadas.
(read [<nombre-lógico>])
Lee un campo simple (single field) desde el nombre lógico especificado. Si no se
especifica nombre lógico, se supondrá stdin (entrada estándar). Devuelve el elemento
leído (que será siempre de un tipo primitivo) si tiene éxito, o EOF si no hay entrada
disponible.
Ej.: (assert (habitación (número (read))))
(readline [<nombre-lógico>])
Lee una línea completa desde el nombre lógico especificado (supondrá stdin, si no se
especifica ninguno). Devuelve un string si tuvo éxito, o EOF si no había entrada
disponible.
(format <nombre-lógico> <string-control> <parámetros>*)
Envía al dispositivo asociado con el nombre lógico especificado un string formateado. El
string de control contiene unos flags de formato que indican cómo serán impresos los
parámetros. El funcionamiento es similar a la función printf del lenguaje C. La función
devuelve el string impreso.
!51
Motor de inferencia
• Ciclo Básico:
1. Si se ha alcanzado el número de ciclo de desencadenamiento expresados o no hay foco actual,
entonces PARAR.
• Si no, seleccionar para ejecutar (2) la regla tope de la agenda del módulo actual.
• Si no hay reglas en dicha agenda, entonces eliminar el foco actual de la pila de focos y
actualizar al siguiente de la pila.
• Si la pila de focos está vacía, entonces PARAR, si no ejecutar 1. de nuevo.
2. Se ejecutan las acciones de la parte derecha de la regla seleccionada. Incrementar el nº de reglas
desencadenadas.
• Si se usa return, entonces eliminar el foco actual de la pila de focos.
• Como resultado acciones se activan o desactivan nuevas reglas.
• Las reglas activadas se sitúan en la agenda del módulo en el que están definidas.
• La situación concreta depende de la prioridad de la regla (salience) y de la estrategia de
resolución de conflictos actual. Las reglas desactivadas salen de la agenda.
• Si se utiliza prioridad dinámica (dynamic salience), entonces se reevalúan los valores de
prioridad de las reglas de la agenda.
• Ir al paso 1.
declare (salience -100)
Permite al usuario asignar una prioridad a una regla, entre -10000 y +10000, por defecto 0.
!52
Instancias de una regla (Agenda)
• Se construye una instanciación de la regla para cada conjunto de elementos que
satisfacen la LHS.
<prioridad> <nombre-regla> : fact-index*
fact-index := f-<número-entero>
• Fases:
1: Se toman todos los elementos que satisfacen cada una de sus condiciones.
2: Se toman las combinaciones de elementos que satisfacen la restricción
impuesta por las variables que relacionan condiciones (aparecen los mismos
nombres de variables.
•La agenda es la lista de todas estas las reglas cuyas condiciones se satisfacen y
todavía no se han ejecutado.
!53
Resolucíón de conflictos en la agenda
• Cuando una regla se activa de nuevo, se sitúa en la agenda...:
a) por encima de todas las reglas de menor prioridad y por debajo de todas las
reglas de mayor prioridad y.
b) entre las reglas de igual prioridad, se utiliza la estrategia de resolución de
conflictos actual para determinar su situación relativa.
c) Si (a) y (b) no son suficientes para determinar el orden, las reglas se colocan
arbitrariamente en relación con las otras reglas. No aleatoriamente, sino que
depende de la implementación de las reglas.
• Estrategias: hay 7, las principales
• depth (estrategia por defecto): Las nuevas reglas se sitúan sobre todas las
de la misma prioridad.
• breadth: Las nuevas reglas se sitúan por debajo de todas las de la misma
prioridad.
• random: A cada activación se le asigna un número aleatorio que se utilizará
para determinar su lugar entre las activaciones de igual prioridad (este número
se mantiene entre cambios de estrategia).
(set-strategy <nombre-estrategia>)
!54
Algoritmo RETE
!55
Eficiencia de las reglas
➮ Los patrones más específicos, con más restricciones, deben de ir primero, ya que,
generalmente, producirán el número más pequeño de coincidencias y tendrán un
mayor número de variables asignadas. Lo que provocará una mayor restricción en los
otros patrones.
➮ Los patrones temporales deben de ir los ú́ltimos. Es decir, los correspondientes a
hechos que se añaden y borran frecuentemente de la lista de hechos. Esto provocará
un menor número de cambios en las coincidencias parciales.
➮ Los patrones más raros deben ser los primeros. Los patrones correspondientes a
hechos que se presentarán pocas veces en la lista de hechos, si se colocan al
principio reducirán el número de coincidencias parciales.
➮ La función test debe ponerse lo antes posible: ¿Así, cuál es mejor de R1 y R2?
(defrule R1
?p1 <- (valor ?x)
?p2 <- (valor ?y)
?p3 <- (valor ?z) ; comprueba que ningun valor es igual a otro
(test (and (neq ?p1 ?p2) (neq ?p2 ?p3) (neq ?p1 ?p3))
=> )
(defrule R2
?p1 <- (valor ?x)
?p2 <- (valor ?y)
(test (neq ?p1 ?p2))
?p3 <- (valor ?z)
(test (and (neq ?p2 ?p3) (neq ?p1 ?p3))
=> )
!56
;esencialmente
(deffacts myfact
(loop-fact))
(defrule simple-loop
?old-fact <- (loop-fact)
=>
(printout t “Looping!” crlf)
(retract ?oldfact)
(assert (loop-fact)))
Errores “garrafales”
; una variante
(deftemplate registro
(slot anda)
(slot ya))
(deffacts error
(registro (anda nil) (ya nil))
; el mismo caso
(defrule anda-que
(defrule sexo_usuario
?anda <- (registro (anda ?var))
?f2 <- (vehiculo (sexo_usuario ?sexo))
=>
=>
(printout t crlf "Sexo del usario: " crlf)
(modify ?anda (anda ?var) (ya bien)))
(bind ?sexo (read))
(modify ?f2 (sexo_usuario ?sexo)))
!57
Implementación siguiendo el modelo
alarma
el motor no arranca
indicador de gasolina = normal
reglas de dependencia de estados
recubre
modelo causal
obtiene
TASK-METHOD diagnóstico-a- través-sugiere-y-comprueba;
REALIZES: diagnóstico-vehículo;
hipótesis
hallazgo
DECOMPOSITION:
predice
esperado
INFERENCES: recubre, predice, compara;
tanque de gasolina
TRANSFER-FUNCTIONS: obtiene;
vacío
indicador de gasolina = cero/bajo
ROLES:
INTERMEDIATE:
modelo de efectos
hipótesis: “una posible solución”;
hallazgo-esperado: “un hallazgo que se debería observar si la hipótesis fuera cierta”;
hallazgo-observado : “el hallazgo realmente observado”;
resultado : “el resultado de la comparación”;
CONTROL-STRUCTURE:
WHILE NEW-SOLUTION recubre(aviso->hipótesis) DO
predice(hipótesis->hallazgo-esperado);
obtiene(hallazgo-esperado-> hallazgo-observado),
evidencia:=evidencia ADD hallazgo-observado);
compara(hallazgo-observado+ hallazgo-esperado -> resultado);
IF resultado == igual
THEN BREAK-LOOP
END IF;
ENDWHILE;
IF resultado == igual
THEN tipo-fallo:= hipótesis
ELSE “no se ha encontrado solución”
END IF;
END TASK-METHOD diagnóstico-a- través-sugiere-y-comprueba;
hallazgo
observado
compara
resultado
distinto
!58
Control sobre las inferencias
Para establecer una estructura de control de este tipo mediante reglas como las
que hemos visto, podemos utilizar uno de los siguientes métodos:
1. Incluir en cada regla una premisa que determine la fase (predice, obtiene, etc.) del proceso en que podrá
ser activada y la afirmación del hecho que sitúa al sistema en la siguiente fase (si ha lugar):
(defrule predice-...
?fase <- (fase predice)
...
=> ...
(retract ?fase)
(assert (fase obtiene)))
2. Otra opción es secuenciar a través de los niveles de prioridad, pero esto tiene el problema de que se
pueden mezclar las fases, en tanto que, si en la fase obtiene entra a la agenda una regla de las de apoyo al
predice, esta se activará antes que restantes correspondientes a obtiene. El ejemplo auto.clp (en el sitio
web de Clips) utiliza este sistema.
!59
Más opciones
3. La tercera opción (híbrida) es definir unas reglas específicamente para secuenciar las fases, que tienen
una prioridad más baja que las reglas que soportan el conocimiento experto propiamente dicho, y que
cambian el hecho de define las subtarea activa.
(defrule predecir-obtener
(declare (salience –100))
?subtarea <- (subtarea predecir)
=>
(retract ?subtarea)
(assert (subtarea obtener)))
(defrule obtener-comparar
(declare (salience –100))
(retract ?subtarea)
Así, cada regla “experta” comienza con una premisa que la
identifica como perteneciente al conocimiento de apoyo de una
subtarea:
(assert (subtarea comparar)))
(defrule predice-...
?subtarea <- (subtarea obtener)
=>
(defrule comparar-predecir
(subtarea predecir)
(declare (salience –100))
; premisas que determinan la hipótesis de una avería
?subtarea <- (subtarea comparar)
...
=>
=> ...
(retract ?subtarea)
(assert (subtarea predecir)))
)
4. Algo muy parecido es utilizar la pila de módulos con la secuencia: (focus modulo1) (return)(focus
modulo2)(return)...
!60
Alternativas
• Alternativamente a esta opción, podría escribirse una regla única de control que fuera lanzando las
sucesivas subtareas sin tener que aparecer explícitamente en la regla, de esta forma:
(defrule lanza-subtarea
(declare (salience –100))
?subtarea <- (subtarea ?subtarea-actual)
(subtarea-siguiente-a ?subtarea-actual ?subtarea-siguiente)
=> (retract ?subtarea)
(assert (subtarea ?subtarea-siguiente)))
Siempre y cuando se hayan definido estas fases como hechos sucesivos de un slot fase-posterior:
(deffacts secuencia-subtareas
(subtarea predecir)
(subtarea-siguiente-a predecir obtener)
(subtarea-siguiente-a obtener comparar)
(subtarea-siguiente-a comparar predecir))
• Algo totalmente equivalente sería utilizar una lista de subtareas y una regla que las secuenciara, es
decir:
(defrule lanza-subtarea
(declare (salience –100))
?subt <- (subtarea ?subt-actual)
?sec-subts <- (secuencia-subts ?subt-siguiente $?otras-subts)
=> (retract ?subt ?sec-subts)
(assert (subtarea ?subt-siguiente))
(assert (secuencia-subts ?otras-subts ?subt-siguiente)))
Con
(deffacts estructura-subtareas
(subtarea predecir)
(secuencia-subts obtener comparar predecir))
!61
El mantenimiento de la verdad
LOGICAL
• Este EC proporciona capacidad de mantenimiento de verdad para entidades (hechos o instancias)
creados por una regla que usa el EC logical.
• Permite establecer una dependencia lógica entre entidades creadas en las RHS (o como resultado de las
acciones realizadas en la RHS) y las entidades que matchearon los patrones contenidos en el EC logical de
la LHS de las reglas.
• Si una entidad que justifique a otra desaparece, esta última también se elimina.
Ej.
(defrule R1
(defrule R2
(defrule R3
(logical (G))
=>
(assert (F)))
(logical (F))
=>
(assert (H)))
(logical (H))
=>
(assert (I)))
Afirmar F lleva a incluir F, H y I en la BH
Si retiramos H con (retract H) automáticamente se retira I.
•Si se crea una entidad sin el EC logical, se dice que esta entidad tiene justificación incondicional. Si se
elimina una regla que apoya la justificación para una entidad, se elimina la justificación de tal entidad, pero
no se elimina la entidad misma.
•Si en el antecedente (LHS) de una regla aparece uno o varios EC logical, éstos deben aparecer los
primeros.
!62
Del control de las reglas y su tipología
• En principio tenemos dos niveles de prioridad, las reglas que hemos denominado
expertas y otro a las reglas de control.
• Podrían introducirse dos niveles más, también para el correcto control en la
evaluación de las reglas.
• El mayor nivel de prioridad deberían tenerlo aquellas reglas que detectan
situaciones que se han definido como ilegales del programa.
• Las reglas especificas para plantear preguntas al usuario deber deberían
tener un nivel intermedio de prioridad, entre las reglas de control y las reglas
expertas, de tal forma que solo se pregunte al usuario cuando no haya
conocimiento experto para inferir el valor que se cuestiona.
• Pero no deberían utilizarse muchos más niveles de prioridad, desde luego no
dentro de las reglas “expertas”, estas deben contener en sus premisas la
determinación exacta y explícita de la situación que las hacen activarse.
• Así, en un sistema algo grande, es preferible utilizar módulos contenedores
compactos de reglas, y por tanto más sistemas de reglas en sí más reducidos, que
se activan según una estructura de control procedimental.
!63
Ejercicios
• “Hagamos algún ejercicio con lo que ya sabemos...”
Ejercicio-24: Permutaciones de los colores.
Ejercicio-20: Pasar a código binario. Tratando con strings.
Ejercicio-3: Dada una fecha, evaluar su corrección.
Ejercicio-1: Poner notas literales desde dos exámenes y las faltas de asistencia.
Diferencia con la versión procedimental. Diferentes formas de resolver el
problema
Ejercicio-2: Asignar habitaciones
Ejercicio-15 y 16: Correo postal y viajes. Consulta de tablas.
Ejercicio-13: Diagnóstico de un motor (recorrido de un árbol binario)
Ejercicio-12: Fórmulas lógicas. Creando un árbol.
Ejercicio-5: Diagnóstico médico. Poniendo orden.
Ejercicio-10 : El mundo de bloques. También en: http://www.uco.es/~i82coory/
bloques.htm
Ejercicio-19: Un problema de búsqueda. Problema de los cántaros. También
solucionado en http://www.uco.es/~i82coory/jarras.htm.
!64
Árboles de decisión
•
- Un árbol compuesto por nodos intermedios, que representan afirmaciones (“El tiempo de tromboplastina
parcial activado es normal”), de los que salen enlaces, según la afirmación sea cierta o no (evaluación del
nodo), hacia dos nodos descendientes (binario).
•
- También pueden verse los nodos intermedios como preguntas que sólo tienen dos posibles respuestas Si
y No (“¿Es normal el tiempo de tromboplastina parcial activado?”) y los nodos hoja como afirmaciones
concluyentes (“Secuestro leucocitario”).
“test de Rumpell Leede
positivo”
Cierto
Falso
“Recuento de
plaquetas bajo”
”VASCULITIS”
Cierto
Falso
“No hay reducción o
ausencia de megacariocito”
Cierto
Falso
“APLASIA DE MÉDULA
ÓSEA ”
“Tamaño normal del
bazo”
Cierto
“SECUESTRO
LEUCOCITARIO”
“Tiempo de tromboplastina
parcial activado normal”
Falso
“CAUSAS
INMUNOLOGICAS”
Cierto
Falso
“Tiempo de
romboplastina parcial
activado bajo”
“Deficiencia del
FACTOR VII”
Cierto
“Deficiencia del
FACTOR XII, XI,
IX o VIII”
Falso
“Deficiencia del
FACTOR X, V,
Prothrombina o
Fibrinógeno”
!65
Algoritmo para el árbol binario
El algoritmo de recorrido de un árbol de decisión de este tipo es muy sencillo,
Comienzo
nodo-actual := nodo-raiz;
Mientras not(nodo-hoja(nodo-actual)) hacer
respuesta:= preguntar(nodo-actual); ;
Si respuesta =cierto entonces
nodo-actual := descendiente-cierto(nodo-actual);
Si respuesta =falso entonces
nodo-actual := descendiente-falso(nodo-actual);
Fin
Visualizar-afirmacion(nodo-actual)
Fin
!66
Estructuras para el árbol binario
(deftemplate nodo
(slot nombre)
(slot tipo (allowed-values intermedio hoja))
(slot afirmacion)
(slot sig-h-cierto)
(slot sig-h-falso))
;Definimos los nodos como hechos segun esa plantilla:
(deffacts arbol-diagnostico
(nodo
(nombre PRLP)
(tipo intermedio)
(afirmación "Prueba de Rumpell-Leede positiva")
(sig-h-cierto VAS)
(sig-h-falso RPB))
(nodo-actual PRLP)) ; el nodo raíz como nodo actual
;Así ya, el proceso de cada nodo depende de si es tipo intermedio. Si lo es hay que preguntar...
(defrule afirmacion
?nodo <- (nodo-actual ?nombre))
(nodo(nombre ?nombre)
(tipo intermedio)
(afirmacion ?afirmacion))
(not (respuesta ?))
=> (printout t "¿Es cierto lo siguiente (S/N)? " ?afirmacion)
(assert (respuesta (read))))
(defrule respuesta-incorrecta ; restringe los valores de la respuesta a la anterior pregunta
?respuesta <- (respuesta ~S&~N))
=> (retract ?respuesta)) ;Al eliminar el hecho se activa inmediatamente la regla afirmación.
!67
Recorriendo el árbol binario
Por el contrario, si la respuesta fue correcta, o bien se activa:
(defrule respuesta-afirmativa
?nodo <- (nodo-actual ?nombre))
(nodo(nombre ?nombre)
(tipo intermedio)
(sig-h-cierto ?descendiente-cierto))
(?respuesta <- (respuesta S))
=> (retract ?nodo ?respuesta)
(assert (nodo-actual ?descendiente-cierto))
O bien se activa:
(defrule respuesta-negativa
?nodo <- (nodo-actual ?nombre))
(nodo(nombre ?nombre)
(tipo intermedio)
(sig-h-falso ?descendiente-falso))
(?respuesta <- (respuesta N))
=> (retract ?nodo ?respuesta)
(assert (nodo-actual ?descendiente-falso))
Para los nodos hoja:
(defrule nodos-hoja
?nodo <- (nodo-actual ?nombre))
(nodo(nombre ?nombre)
(tipo hoja)
(afirmacion ?afirmacion))
(not (respuesta ?))
=> (retract ?nodo ?respuesta)
(printout t "Se deduce que... " ?afirmacion crlf)
(assert (nuevo-caso))) ; se afirma para determinar la repetición del proceso
!68
Vuelta a empezar
Se afirma el hecho nuevo-caso para determinar el lanzamiento de la siguiente regla que pregunta al
usuario si desea continuar con otro caso y esto requiere además otras dos reglas:
(defrule preguntar-por-nuevo-caso
(nuevo-caso)
(not (respuesta ?))
=> (printout t "¿Desea comenzar un nuevo caso (S/N)? ")
(assert (respuesta (read))))
(defrule nuevo-caso
?nuevo-caso <- (nuevo-caso)
?respuesta <- (respuesta S)
=> (retract ?nuevo-caso ?respuesta)
(assert (nodo-actual PRLP)))
(defrule terminar
?nuevo-caso <- (nuevo-caso)
?respuesta <- (respuesta N)
=> (retract ?nuevo-caso ?respuesta)
(printout t "FIN DE LA EJECUCION" crlf))
.
!69
Árboles n-arios
“Tiempo de
tromboplastina parcial
activado?”
normal
“Deficiencia del
FACTOR VII”
bajo
“Deficiencia del
FACTOR XII, XI,
IX o VIII”
alto
“Deficiencia del
FACTOR X, V,
Prothrombina o
Fibrinógeno”
Comienzo
nodo-actual := nodo-raiz;
Mientras not(nodo-hoja(nodo-actual))
Hacer
respuesta:= preguntar(nodo-actual);
i:=1;
Mientras existe-descendiente(nodo-actual, i) y
respuesta <> valor-descendiente(nodo-actual, i)
Hacer
i:= i+1;
Fin
Si existe-descendiente(nodo-actual, i) entonces
nodo-actual := descendiente(nodo-actual, i);
Fin
Visualizar-afirmacion(nodo-actual)
Fin
!70
Módulos
¿Qué ocurre si la memoria de producción (base de reglas) es grande?
• Los módulos permiten agrupar un conjunto de construcciones de modo que se
mantenga un control explícito sobre la restricción del acceso de otros módulos:
ámbito global estrictamente jerárquico en una sola dirección.
• Agrupando las reglas en módulos es posible controlar la ejecución de éstas.
(defmodule <nombre-módulo> [<comentario>] <especificación-acceso>*)
<especificación-acceso> ::= (export <ítem>) | (import <nombre-módulo> <ítem>)
<ítem> ::= ?ALL | ?NONE | <construcción> ?ALL | <construcción> ?NONE | <construcción> <nombreconstrucción>+
<construcción> ::= deftemplate | defclass | defglobal | deffunction | defgeneric
(defmodule MAIN)
(defmodule CAPTURAR-ENTRADAS)
(defmodule EVALUAR-DATOS)
(defmodule PRESENTAR-SOLUCIONES)
Referirse a una construcción externa: <nombre-modulo>::: <nombre-construccion>
Ej. CAPTURAR-ENTRADAS::datos-paciente
!71
Importación y exportación
• export se usa para indicar qué construcciones serán accesibles (visibles) a otros
módulos
• import se usa para indicar qué construcciones, que se referencián, serán de otros
módulos.
• Sólo se puede exportar e importar: deftemplate, defclass, defglobal, deffunction y
defgeneric.
• Es decir, no se pueden exportar ni importar las construcciones: deffacts, defrule y
definstances.
• Existen tres formas de importación/exportación
(defmodule A (export ?ALL))
(defmodule B (export deftemplate ?ALL))
(defmodule CAPTURA-DATOS (export deftemplate datos-paciente))
!72
Módulos y control
• Cada módulo tiene su propia agenda (y su conjunto conflicto).
• La ejecución puede controlarse seleccionando una agenda.
• De esta forma, se elige un conjunto determinado de reglas a ejecutar.
(focus <nombre-módulo>+)
• El foco actual es el valor tope de una estructura de datos similar a una pila,
denominada pila de focos.
•Cambiar el foco actual implica apilar el nuevo foco y abandonar el módulo
(return).
• Cuando se vacía la agenda de un módulo (foco actual), el foco actual se
elimina de la pila de focos, y el siguiente módulo en la pila de focos se
convierte en el foco actual.
• La ejecución de las reglas continúa hasta que:
- cambia el foco a otro módulo,
- no haya reglas en la agenda, ó
- se ejecute return en la RHS de una regla.
!73
Ejemplos con módulos
(defmodule A)
(deftemplate A::persona (slot x))
(defmodule B)
(defrule B::asigna
(persona (x 3))
=> )
-------------------------------------------------------------------(defmodule A (export deftemplate persona))
(deftemplate A::persona
(slot x))
(defmodule B (import A deftemplate persona))
(defrule B::asigna
(persona (x 3))
=> )
---------------------------------------------------------------------(defmodule A (export deftemplate ancho alto))
(deftemplate A::ancho (slot x))
(deftemplate A::alto (slot y))
(deffacts A::info (ancho (x 3))(alto (y 4)))
(defmodule B (import A deftemplate ancho))
(defmodule MAIN (export ?ALL))
(deftemplate MAIN::objetivo (slot nombre)(slot estado))
(defrule MAIN::ejemplo-foco
=>
(printout t "Disparo en el módulo MAIN."crlf)
(assert (objetivo (nombre principal)(estado resuelto)))
(focus A B))
(defmodule A
(export ?ALL)
(import MAIN deftemplate initial-fact objetivo))
(deftemplate A::subobjetivo-A (slot nombre)(slot estado))
(defrule A::regla-ejemplo
(objetivo (nombre principal) (estado resuelto))
=>
(assert (subobjetivo-A (estado resuelto)))
(printout t "Disparando la regla en el módulo A."crlf))
(defmodule B
(import A deftemplate subobjetivo-A)
(import MAIN deftemplate initial-fact))
(defrule B::regla-ejemplo
(subobjetivo-A (estado resuelto))
=>
(Ejercicio 26. Uso del Teorema de Pitágoras)
(printout t "Dispara la regla en el módulo B."crlf))
(Ejercicio 25. Cajas registradoras)
!74
(Ejemplo en: http://www.uco.es/~i82coory/diagnostico.htm)
Tratamiento de la incertidumbre en Clips
Clips no incluye ningún mecanismo para el tratamiento de la incertidumbre, por
tanto, si queremos emplear alguna técnica para ello, hay que codificar el
soporte y los mecanismos asociados.
Como ejemplo vamos a solucionar el tratamiento de la incertidumbre con
factores de certeza Mycin.
(deftemplate oav-fc
(multislot objeto (type SYMBOL))
(multislot atributo (type SYMBOL))
(multislot valor)
(slot fc (type FLOAT) (range –1.0 +1.0))) ;; rango de los factores de certeza
Ejemplo:
(oav-fc (objeto microorganismo)
(atributo morfologia)
(valor bacilo)
(fc 0.7))
!75
Reglas Mycin
FC(hipótesis) = max{0, FC(evidencia)} ⋅ FC(hipótesis, evidencia)
-1 ≤ FC ≤ 1
!76
Un ejemplo:
Sean las reglas:
R1: Si h2 o h3 entonces h6 (0’4)
R2: Si h6 y h7 entonces h1 (0’7)
R3: Si h4 o h5 entonces h1 (0’1)
FC(h2) =0,3, FC(h3)=0,6, FC(h4)=0,2, FC(h5)=0,8, FC(h7)=0,9
El atributo h1 es el atributo objetivo, empleándose encadenamiento hacia atrás. Calcular el factor de certeza que resulta
para el atributo h1.
Solución:
El conjunto conflicto inicial {R2, R3}. R2 es la regla más prioritaria, => necesario conocer el factor de certeza para h6 y
h7.
Se conoce este factor para h7, a partir de la evidencia inicial, pero no para h6. Este último valor puede calcularse
mediante la regla R1. En efecto,
FC(h2, e’) = 0’3, FC(h3, e’) = 0’6
FC(h2 o h3, e’) = max{0’3, 0’6} = 0’6
Por tanto, a partir de R1:
FC(h6, e1’) = max{0, FC(h2 o h3, e’)} . FC(h6, h2 o h3) } = 0’6 . 0’4 = 0’24 ; con e1’= (h2 o h3)
Luego,
FC(h6 y h7, e1’) = min{FC(h6, e1’), FC(h7, e1’)} = min{0’24, 0’9} = 0’24
FC(h1, e1’) = FC(h1, h6 y h7) ⋅ max{0, FC(h6 y h7, e1’)} = 0’7 ⋅ 0’24 = 0’168
Ahora habrá que considerar la otra regla que formaba parte del conjunto conflicto inicial: R3. Se tiene:
FC(h4, e2’) = 0’2, FC(h5, e2’) = 0’8 FC(h4 o h5, e2’) = max{0’2, 0’8} = 0’8
FC(h1, e2’) = FC(h1, h4 o h5) ⋅ max{0, FC(h4 o h5, e2’)} = 0’1 ⋅ 0’8 = 0’08
Combinando las dos reglas que producen evidencia sobre h1, se obtiene finalmente:
FC(h1, e1’ comb e2’) = FC(h1, e1’) + FC(h1, e2’)⋅(1 − FC(h1, e1’)) = 0’168 + 0’08 ⋅ 0’832 = 0’234
!77
Combinación de certidumbre
Una característica fundamental de Mycin (de las reglas Mycin) es que pueden llegarse a los mismos
hechos desde diferente reglas o inferencias (reglas) y esto afectará a su certeza. De tal forma que es
preciso combinar los diferentes factores de certeza obtenidos. Así, tenemos que decirle a Clips que
admita hechos duplicados:
(set-fact-duplication true)
La regla que combina los hechos duplicados y genera un nuevo hecho con el nuevo factor combinado,
anulando los hechos previos. (sólo para FCs positivos o nulos).
(defrule combina-oav-fc-positivas
(declare (auto-focus true)) ;garantiza que no se va a disparar otra regla antes
?hecho1 <- (oav-fc
(objeto $?obj)
(atributo $?atri)
(valor $?val)
(FC $?fc1&: (>= ?fc1 0)))
?hecho2 <- (oav-fc
(objeto $?obj)
;son hechos iguales
(atributo $?atri)
(valor $?val)
(FC $?fc2&: (>= ?fc2 0)))
(test (neq hecho1 hecho2))
; pero no son el mismo
=>
(retract ?hecho1)
(bind ?fc3 (- (+?fc1 ?fc2) (* ?fc1 ?fc2)))
(modify ?hecho2 (FC ?fc3)))
!78
Transmisión de la certidumbre
Las reglas de la base de conocimientos tienen que tener en cuenta un mecanismo de propagación de
la certeza de la premisa sobre la certeza de la conclusión.
En este ejemplo, solamente se afirmará el hecho conclusión cuando existan unos determinados hechos
y con factores superiores a 0.2:
(defrule combina-oav-FC-positivas
(oav-fc
(objeto microorganismo)
(atributo coloracion)
(valor gramnegativo)
(fc ?fc1))
(oav-fc
(objeto microorganismo)
(atributo morfologia)
(valor bacilo)
(fc ?fc2))
(oav-fc
(objeto paciente)
(atributo es-un)
(valor huesped-afectado)
(fc ?fc3))
(test (> (min ?fc1 ?fc2 ?fc3) 0.2))
=>
(bind ?fc4 (* (min ?fc1 ?fc2 ?fc3) 0.6))
(assert
(oav-fc
(objeto microorganismo)
(atributo identidad)
(valor seudomonas)
!79
(fc ?fc4))))
Orientación a Objetos
• Objeto:
Colección de información (los datos) que representa una entidad del mundo
real y la forma de manipularla (el código asociado). Los objetos vienen
descritos por:
• Propiedades:
Especificadas en términos de los atributos (slots) de la clase del
objeto.
• Conducta:
Especificada en términos de código procedural (gestores de mensajes)
asociado a la clase del objeto.
•Los objetos se manipulan mediante el paso (envío) de mensajes.
!80
Principios de la OOP
• Abstracción
Representación intuitiva de mayor nivel para un concepto complejo.
Definición de nuevas clases para describir las propiedades comunes y el
comportamiento de un grupo de objetos.
•Encapsulación:
Mecanismo que permite la ocultación de los detalles de implementación de
un objeto mediante el uso de un interfaz externo bien definido.
•Herencia:
Proceso por el cual una clase puede ser definida en términos de otra(s)
clase(s).
•Polimorfismo:
Capacidad de diferentes objetos para responder al mismo mensaje de una
forma especializada.
•Ligadura dinámica (dynamic binding):
Capacidad para seleccionar en tiempo de ejecución el gestor de mensajes
que corresponde a un mensaje concreto.
!81
Definición de clases
Construcción:
(defclass <nombre> [<comentario>]
(is-a <nombre-de-superclase>+) ;;; indica un orden de herencia
[(role concrete | abstract)];;; puede instanciarse o no
[(pattern-match reactive | non-reactive)];;; admite machting en una regla o no
<slot>* ;;; definición de los atributos de la clase
<documentación-handler>*
)
Herencia múltiple
COOL examina cada nueva clase utilizando la lista de precedencia de clases
(de superclases) para establecer un orden lineal y le hace heredar slots y
gestores (conducta) de cada una de las clases de esta lista en orden. Tiene
prioridad las primeras clases de la lista (las más específicas) para heredar si
hay conflicto (tienen el mismo nombre).
(describe-class <nombre-de-clase>)
En la cláusula is-a ya se establece una precedencia
!82
Definición de slots
(slot <nombre> <facet>*)
(single-slot <nombre> <facet>*)
(multislot <nombre> <facet>*)
facets: son las propiedades de los atributos, las cuales son ciertas para todos los
objetos que comparten dichos slots.
(default ?DERIVE | ?NONE | <expresión>*) ;;; se evalúa al crear la clase
(default-dynamic <expresión>*) ;;; se evalúa al instanciar
(storage local | shared) ;;; el valor se almacena en la instancia o en la clase
(access read-write | read-only | initialize-only) ;;; tipo de acceso permitido
(propagation inherit | no-inherit) ;;; heredable o no heredable
(visibility private | public) ;;; solo permite el acceso a los gestores propios (no heredados)
(source exclusive | composite) ;;; hereda la facet de la clase más espcífica o de las anteriores
(pattern-match reactive | non-reactive) ;;; cambios activan reglas o no
(create-accessor ?NONE | read | write | read-write) ;;; crea automáticamente los gestores
restricciones (type ...) (range ..) (cadinality ..)
!83
pattern-matching con objetos
Las modificaciones en atributos no reactivos o en instancias de clases no reactivas no
tendrán efecto alguno en las reglas.
(object <atributo-de-restricción>)
;;; donde
<atributo-de-restricción> ::=
(is-a <restricción>) |
(name <restricción>) |
;;; clase a la que pertenece
;;; nombre de instancia entre []
(<nombre-atributo> <restricción>*) ;;; igual que con templates
Ejemplo: "Apaga la caldera si la habitación está vacía"
(defrule UNIDAD-CONTROL::UC7
(object (is-a Termostato) (temperatura ?t)
(temperatura-seleccionada ?ts & :(>= ?t (- ?ts 3)))
(caldera ?c) (modo calor) (habitación ?h))
?inst <- (object (is-a Caldera) (name ?c)
(estado encendida))
(object (is-a Habitacion) (name ?h) (ocupación vacía))
=>
(send ?inst Apagar)
)
!84
Gestores de mensajes
• Los objetos se manipulan mediante el envío de mensajes utilizando la función send.
• La implementación de un mensaje consta de una serie de fragmentos de código procedural
llamados gestores de mensajes (message-handlers). El valor devuelto por un gestor de
mensajes es el resultado de la evaluación de la última acción.
• La construcción defmessage-handler se utiliza para especificar la conducta de los objetos
de una clase en respuesta a un mensaje particular.
• Dentro de una clase, los gestores para un mensaje particular pueden ser de diferentes
tipos diferentes: Primary (el proceso principal), Before, After.
(defmessage-handler <nombre-clase> <nombre-mensaje> [<tipo-handler>]
;;; que identifican al mensaje
[<comentario>]
(<parámetro>* [<parámetro-comodín>]) <acción>*)
(defmessage-handler rectángulo calcular-área ()
(* ?self:base ?self:altura)) ;;; Devuelve el area (base por altura).
(defmessage-handler rectangulo imprimir-area ()
(printout t (send ?self calcular-area) crlf))
!85
Demonios y mensajes predefinidos
• Demonios: Son fragmentos de código que se ejecutan implícitamente cuando se
realiza alguna acción básica sobre una instancia como son la inicialización,
borrado y la lectura y escritura de atributos, que han sido implementados como
gestores primarios asociados a la clase de la instancia.
• Gestores de mensajes predefinidos:
init: inicializa una instancia con sus valores por defecto después de crearla. makeinstance) e inicializar instancias (initialize-instance) envían automáticamente el
mensaje init.
delete: devuelve TRUE si logra borrar con éxito la instancia; devuelve FALSE en
caso contrario.
print: visualiza en pantalla los atributos y sus valores de una instancia dada.
...
Cuando un objeto recibe un mensaje mediante la función send, CLIPS examina la
lista de precedencia de clases para determinar el conjunto de gestores de
mensajes aplicables al mensaje.
Un gestor de mensajes es aplicable a un mensaje, si su nombre coincide con el
mensaje y el gestor está ligado (asociado) a alguna clase de la lista de
precedencia a la cual pertenezca la instancia que recibe el mensaje
!86
Manipulación de instancias
•Los objetos se manipulan mediante el envío de mensajes de unos a otros.
(send <expresión-de-objeto> <nombre-de-mensaje>
<expresión>*)
La función send devuelve el valor del último gestor (primary o around) ejecutado.
(make-instance [<nombre-instancia>] of <nombre-clase>
(<nombre-slot> <expresión>)*)
(definstances <nombre-colección-instancias>
[active] [<comentario>]
(<definición-de-instancia>)*)
get-<nombre-atributo>
put-<nombre-atributo>
delete
!87
Consultas sobre instancias
any-instancep Determina si uno o más conjuntos de instancias satisfacen una consulta.
(any-instacep ((?hombre HOMBRE)) (> ?hombre:edad 30))
find-instance Devuelve el primer conjunto de instancias que satisfaga una consulta.
(find-instance ((?h HOMBRE) (?m MUJER)) (= ?h:edad ?m:edad))
find-all-instances Agrupa y devuelve todos los conjuntos de instancias que satisfacen una consulta.
(find-all-instances ((?h HOMBRE) (?m MUJER)) (= ?h:edad ?m:edad))
do-for-instance Realiza una acción sobre el primer conjunto de instancias que satisfaga una consulta.
(do-for-instance ((?p1 PERSONA) (?p2 PERSONA) (?p3 PERSONA))
(and (= ?p1:edad ?p2:edad ?p3:edad)
(neq ?p1 ?p2) (neq ?p1 ?p3) (neq ?p2 ?p3))
(printout t ?p1 " " ?p2 " " ?p3 crlf))
do-for-all-instances Realiza una acción con cada conjunto de instancias que satisface una consulta
según se van encontrando.
(do-for-instance ((?p1 PERSONA) (?p2 PERSONA) (?p3 PERSONA))
(and (= ?p1:edad ?p2:edad ?p3:edad)
(neq ?p1 ?p2) (neq ?p1 ?p3) (neq ?p2 ?p3))
(printout t ?p1 " " ?p2 " " ?p3 crlf))
(Ejercicios 1, 8 y 11 de COOL)
!88
Encadenamiento hacia atrás en Clips
Es un ejercicio, más que algo práctico. Para inferir hacia atrás mejor utilizar otro tipo de
lenguaje y de motor de inferencia, por ejemplo Prolog (http://www.swi-prolog.org/).
Hay que definir un objetivo:
(deftemplate objetivo
(slot propiedad))
(deftemplate propiedad-valor
(slot propiedad)
(slot valor))
(deffacts objetivo-inicial
(objetivo (propiedad propiedad-objetivo-inicial))
(deftemplate rule
(multislot if)
(multislot then))
if:
<atributo-1> es <valor-1> y
...
<atributo-n> es <valor-n>
!89
Procedimientos (seudocódigo)
Procedimiento Obtener-objetivo(objetivo)
Si valor(objetivo)<> nil entonces
retornar(valor(objetivo));
; si no se conoce habra que buscar en la BC las reglas con el objetivo en la RHS
Para cada regla en Base-Conocimientos / contiene-rhs(propiedad, regla) hacer
Si Regla-con-exito(regla)=TRUE entonces
;se cumple la LHS
valor(objetivo):= valor-rhs(regla);
retornar(valor(objetivo))
Fin
Fin
valor(objetivo):= pedir-valor-usuario;
; si no existe esta regla, se pide al usuario
retornar(valor(objetivo);
Fin
;el siguiente procedimiento situa nuevos objetivos en la pila
Procedimiento Regla-con-exito(regla)
Para cada condición en LHS(regla) hacer
Si Obtener-objetivo(propiedad(condicion)) <> valor(condicion) entonces
retornar(FALSE);
;es decir, no se cumple la condicion
Fin
retornar(TRUE);
Fin
!90
Reglas que implementan los procedimientos
;;; regla que busca las rules cuya conclusión (then) incluya la asignación de un valor a
;;; diagnóstico y que afirme su antecedente (if) como nuevo objetivo, siempre y cuando no
;;; tenga ya un valor previo o ya sea un objetivo.
(defrule evaluar-regla
(objetivo (propiedad ?objetivo))
(rule (if ?propiedad $?) (then ?objetivo $?)) ; regla con el objetivo en el RHS
(not (propiedad-valor (propiedad ?propiedad))) ;no existe valor para esa propiedad
(not (objetivo (propiedad ?propiedad))) ; no se ha planteado ya como objetivo
=>
(assert (objetivo (propiedad ?propiedad)))
)
;;; Y otra que pregunte al usuario por el valor del antecedente cuando no haya rules que lo
;;; incluyan en su consecuente.
(defrule pedir-valor-propiedad
?hecho-objetivo <- (objetivo (propiedad ?objetivo))
(not (propiedad-valor (propiedad ?objetivo))) ; no existe valor para el objetivo
(not (rule (then ?objetivo $?)))
; no existe regla con el objetivo en la RHS
=>
(retract ?hecho-objetivo)
(printout t "Introduzca el valor de " ?objetivo ": ")
(assert (propiedad-valor (propiedad ?objetivo) (valor (read))))
)
!91
Implementando los procedimientos
;;; regla que elimina como objetivo aquél que ya se ha logrado, lo cual debe tener prioridad sobre
;;; la búsqueda de objetivos (las anteriores reglas):
(defrule retractar-objetivo-logrado
(declare (salience 10))
?hecho-objetivo <- (objetivo (propiedad ?objetivo))
(propiedad-valor (propiedad ?objetivo))
=>
(retract ?hecho-objetivo)
)
;;; También tiene que tener prevalencia la afirmación del consecuente de una rule cuando su
;;; antecedente, como anterior objetivo, se haya logrado. Lleva asociada la eliminación de esa rule.
(defrule afirmar-consecuente
(declare (salience 10))
(objetivo (propiedad ?objetivo))
(propiedad-valor (propiedad ?propiedad)
(valor ?valor))
?rule <- (rule (if ?propiedad es ?valor)
(then ?objetivo es ?valor-objetivo))
=>
(retract ?rule)
(assert (propiedad-valor (propiedad ?objetivo) (valor ?valor-objetivo)))
)
!92
Implementando los procedimientos
;;; Cuando se cumple la primera premisa del antecedente de una rule, esta misma premisa se
::: elimina de la rule, para no volverla a tener en cuenta:
(defrule eliminar-premisa-cumplida
(declare (salience 10))
(objetivo (propiedad ?objetivo))
(propiedad-valor (propiedad ?propiedad) (valor ?valor))
?rule <- (rule (if ?propiedad es ?valor y $?resto-if) (then ?objetivo es ?valor-objetivo)))
=>
(modify ?rule (if $?resto-if))
)
;;; Pero si no se cumple la premisa, y por tanto, todo el antecedente,
;;; toda la rule debe ser eliminada:
(defrule retractar-rule-fallida
(declare (salience 10))
(objetivo (propiedad ?objetivo))
(propiedad-valor (propiedad ?propiedad)
(valor ?valor))
?rule <- (rule (if ?propiedad es ~?valor)
(then ?objetivo es ?valor-objetivo)))
=>
(retract ?rule))
!93
Con valores posibles aceptables
;;; Si deseamos que en la pregunta al usuario se especifiquen los posibles valores aceptables,
;;; una forma muy sencilla de resolverlo sería modificar la regla pedir-valor-propiedad
;;; para que quede:
(defrule pedir-valor-propiedad
?hecho-objetivo <- (objetivo (propiedad ?objetivo))
(not (propiedad-valor (propiedad ?objetivo)))
(not (rule (then ?objetivo $?)))
(valores-posibles (propiedad ?objetivo) (valor-1 ?valor-1) (valor-2 ?valor-2))
=>
(retract ?hecho-objetivo)
(printout t "Introduzca el valor de " ?objetivo " (" ?valor-1 "/" ?valor-2 "): ")
(assert (propiedad-valor (propiedad ?objetivo) (valor (read))))
)
;;; Para lo que es preciso definir un nuevo template:
(deftemplate valores-posibles
(slot propiedad)
(slot valor-1)
(slot valor-2))
;;; Y los siguientes hechos complementarios:
(deffacts pruebas
(valores-posibles (propiedad rumpell-leede) (valor-1 positivo) (valor-2 negativo))
(valores-posibles (propiedad recuento-plaquetas) (valor-1 normal) (valor-2 bajo))
(valores-posibles (propiedad reduccion-megacariocitos) (valor-1 cierto) (valor-2 falso))
(valores-posibles (propiedad dimension-bazo) (valor-1 normal) (valor-2 anormal)))
!94
Un ejemplo
“test de Rumpell Leede
positivo”
Cierto
Falso
“Recuento de
plaquetas bajo”
”VASCULITIS”
Cierto
“No hay reducción o
ausencia de megacariocito”
Cierto
Falso
“APLASIA DE MÉDULA
ÓSEA ”
“Tamaño normal del
bazo”
Cierto
“SECUESTRO
LEUCOCITARIO”
Falso
“CAUSAS
INMUNOLOGICAS”
deffacts reglas-diagnostico
(rule (if rumpell-leede es positivo)
(then diagnostico es vasculitis))
(rule (if rumpell-leede es negativo y
recuento-plaquetas es normal)
(then diagnostico es deficiencia-factores-coagulacion))
(rule (if rumpell-leede es negativo y
recuento-plaquetas es bajo y
reduccion-megacariocitos es falso)
(then diagnostico es aplasia-medula-osea))
(rule (if rumpell-leede es negativo y
Falso
recuento-plaquetas es bajo y
reduccion-megacariocitos es cierto y
“Deficiencia de
factores de
dimension-bazo es normal)
coagulación”
(then diagnostico es secuestro-leucocitario))
(rule (if rumpell-leede es negativo y
recuento-plaquetas es bajo y
reduccion-megacariocitos es cierto y
dimension-bazo es anormal)
(then diagnostico es causas-inmunologicas))
)
(deffacts hechos
(objetivo (propiedad diagnostico))
(propiedad-valor (propiedad rumpell-leede))
(propiedad-valor (propiedad recuento-plaquetas))
(propiedad-valor (propiedad reduccion-megacariocitos))
(propiedad-valor (propiedad dimension-bazo))
)
!95
Otro ejemplo
Regla 1 INFECCION DE MENINGITIS
IF
El medico sabe que paciente tiene meningitis.
OR
Se sospecha de meningitis
THEN
Infección de meningitis.
AND
DESPLEGAR Infección
ELSE
DESPLEGAR No se encontró infección.
Regla 2 SE SOSPECHA DE MENINGITIS POR EL TEST O SINTOMAS
IF
Se sospecha de meningitis por el resultado del test.
OR
Se sospecha de meningitis por los síntomas del paciente.
THEN
Se sospecha de meningitis.
Regla 3 CULTIVOS PARECIDOS A LA MENINGITIS
IF
Donde el test esta corriendo.
AND Cultivos donde se observa.
AND Cultivos parecidas a la meningitis.
THEN
Se sospecha de meningitis por el resultado del test.
Regla 4 CULTIVOS PARECIDADAS A LA MENINGITIS
IF
La apariencia de la cultivo es coccus.
AND Las manchas de la cultivo son grampos.
THEN
Cultivos parecidas a la meningitis.
Regla 5 SE SOSPECHA DE MENINGITIS POR LOS SÍNTOMAS
IF
El paciente esta sufriendo persistentes dolores de cabeza.
AND El paciente esta sufriendo de vértigo.
AND El paciente esta letárgico.
THEN
Se sospecha de meningitis por los síntomas.
!96
Sitios interesantes relacionados con
SBC y Clips
Sitio de Clips: http://clipsrules.sourceforge.net/
Sitio de FuzzyClips: http://awesom.eu/~cygal/archives/2010/04/22/fuzzyclips_downloads/index.html
Sitio de Jess: http://www.jessrules.com/
Drools - The Business Logic integration Platform. http://www.jboss.org/drools
Sitio de Rusell y Norvig: Artificial Intelligence: A Modern Approach. http://aima.cs.berkeley.edu/
Un sitio con muchas cosas y ejemplos: http://www.csie.ntu.edu.tw/~sylee/courses/es/index.html#outline
Departamento de Inteligencia Artificial, UNED: http://www.ia.uned.es/
Grupo SIMDA, UNED: http://simda.uned.es/
!97
Referencias
• CLIPS User’s Guide: ofrece una introducción a CLIPS. Se compone de 2 vol úmenes:
Volume I: Rules, introducción a la programación basada en reglas usando CLIPS.
Volume II: Objects, introducción a la programación orientada a objetos usando COOL
• CLIPS Reference Manual: consta de 3 volúmenes, de los cuales se han utilizado el I y II.
Volume I: The Basic Programming Guide, descripción de la sintaxis de CLIPS y ejemplos de uso
Volume II: Advanced Programming Guide, describe en detalle las características más sofisticadas de
CLIPS para programación de aplicaciones avanzadas.
• Expert Systems: Principles and Programming.
Joseph Giarratano & Gary Riley. 2nd Edition. PWS Publishing
Company, 1994
• Jess in Action: Java Rule-Based Systems (In Action series). Ernest Friedman-Hil.Manning Publications (July
2003)
• Desarrollo de SBCs en Clips y FuzzyClips. Javier Carbó Rubiera, Jose M. Molina López, Rafael Martínez
Tomás. Editorial Sanz y Torres. 2005
• Sistemas Expertos y Redes Probabilistas. E. Castillo, J.M. Gutiérrez, and A.S. Hadi.
http://personales.unican.es/gutierjm/BookCGH.html. 1998.
• Apuntes, bastante completos, de Aitor San Juan Sánchez (UCM): http://www.fdi.ucm.es/profesor/belend/
ISBC/clips_archivos/clips.pdf
!98
Descargar