You are on page 1of 21

Sistemas Expertos

Unidad I

Introducción a los Sistemas Expertos

Semana 3

Manipulación del control de un Lenguaje basado


en reglas
Objetivo General

Comprender el paradigma de
programación lógica, conceptos y
fundamentos de los sistemas expertos.
Objetivo Específico

Utilizar un lenguaje declarativo para


comprender el paradigma de la
programación logica.
Objetivo Instruccional

Describir el control en un lenguaje


basado en reglas
Contenidos
Técnicas de Programación

Control en prolog
• Las técnicas de programación de esta sección
explota la fuerza de prolog, que son el rastreo
inverso (backtracking) y la unificación.
Técnicas de Programación

 El rastreo inverso permite encontrar una


solución si es que existe alguna.
 La unificación permite usar variables como
lugares para acomodar datos, lugares que se
utilizaran después.

• El uso cuidadoso de las técnicas de esta sección


puede conducirnos a programas eficientes. En
esta sección, los programas se apoyan en la
evaluación de izquierda a derecha de las
submetas de prolog.
Propone y Verifica
Técnicas de Programación

Una consulta propone y verifica tiene la siguiente forma:

Existe una S tal que: propone(S) y verifica(S) ?

Donde propone(S) y verifica(S) son submetas.

Prolog responde a tal consulta generando soluciones a


propone(S) hasta que encuentre una solución que satisfaga
verifica(S).

De manera similar, una regla propone y verifica tiene la siguiente


forma:

conclusion(…) :- propone(..,S,..) , verifica(…,S,…).


Propone y Verifica
Ejemplo: (comunes1.pl) – Indica si dos listas tienen algún miembro en común.
Técnicas de Programación

En este ejemplo, la regla propone y verifica es la siguiente:


comunes(X,Y) :- miembro(M,X) , miembro(M,Y).

Dicho en palabras, las listas X e Y son comunes si existe al menos algún objeto M que sea
miembro de ambos. La primera meta miembro(M,X) propone una M de la lista X y la
segunda meta miembro(M,Y) verifica si M aparece también en la lista Y.

Las reglas para miembro son: miembro( M , [ M | _ ] ).


miembro( M , [ _ | T ] ) :- miembro(M,T).

• La primera regla dice que M es miembro de una lista con cabeza M.


• La segunda regla dice que M es miembro de una lista si M es miembro de su cola T.

Para ver porqué.

Si preguntamos: comunes([a,b,c],[1,2,c,d]).

Prolog responde:

Si
Técnicas de Programación
Propone y Verifica
Si se consulta:
miembro(M,[a,b,c]) , miembro(M,[1,2,c,d]).

La primera meta de esta consulta genera soluciones y la segunda las verifica para ver si son
aceptables.

Las soluciones generadas por la primera meta son:

miembro(M,[a,b,c])

M=a
M=b
M=c

miembro(a,[1,2,c,d,])
no
comunes2.pl
miembro(b,[1,2,c,d])
Muestra el primer miembro que tienen en común las listas.
no

miembro(c,[1,2,c,d]) comunes3.pl
si Muestra todos los miembros que tienen en común las listas.
Prolog tiene varios predicados y ordenes
incorporadas que lo hacen un lenguaje de
programación de propósito general en vez de
solo una implementación de la lógica.
Control en Prolog

Aquí se examina dos de las mas importantes


funciones de control de programas que están
disponibles en muchas implementaciones de
prolog:
• Fail
• !
Control de la vuelta atrás
La vuelta atrás es un elemento esencial del prolog. Cuando a un programa se le
ha pedido que satisfaga un objetivo, busca de arriba abajo y de izquierda a
derecha a través de las cláusulas hasta identificar el objetivo. Si llega al final, el
programa volverá atrás hasta encontrar otra bifurcación por la que pueda seguir
buscando.
Control en Prolog

Esta no es siempre la mejor forma de proceder. Algunos programas gastan


mucho tiempo buscando información que no se necesita para encontrar el
material que se ha pedido. Estos programas necesitan una ayuda del
programador para que corte el enorme espacio de búsqueda.

La computadora es vulnerable a la "explosión combinatoria", la cual puede


presentarse en prolog cuando existen unos cuantos niveles de objetivos y
subobjetivos.

Como programador usted puede ayudar. Primero puede escribir las cláusulas en
un orden tal que haga eficiente la búsqueda. Segundo, ya que como
programador es más inteligente que su computadora, puede decirle al prolog
cuando saltar parte de una búsqueda que no es necesaria. Para ello debe
insertar unas cuantas ordenes especiales en el programa. Estas pueden dirigir la
lógica y ahorrar tiempo de calculo.
! (Corte)
Prolog utiliza una búsqueda "primero en
profundidad" en un árbol. Procede desde el
objetivo principal al primer subobjetivo, luego al
Control de la vuelta atrás
Control en Prolog

primer sub_subobjetivo y así sucesivamente hasta


que confirma el nivel inferior del subobjetivo o esta
seguro de que el subobjetivo falla. A continuación
se mueve hacia atrás un nivel del subobjetivo
(vuelta atrás) e intenta hacer coincidir el siguiente
subobjetivo al mismo nivel.

Si la primera serie de subobjetivos es parte de un


objetivo mayor que esta terminado, prolog no lo
sabe hasta que se ha trabajado con cada
subobjetivo.
! (Corte)
Para comprender este tipo de búsqueda de otra forma, piense en
un árbol familiar típico. Para simplificar la analogía, imagine que su
familia consta solo de hijas y que cada una tiene 2 hijas. Una
búsqueda primero en profundidad que comience con una de sus
Control de la vuelta atrás
Control en Prolog

bisabuelas iría al nivel de sus dos hijas, una de ellas su abuela. El


prolog trataría primero con ella. Luego, antes de continuar con su
hermana procedería un nivel “mas abajo” en el árbol y trabajaría
con una de sus hijas – su madre -. De nuevo, antes de moverse
hacia la hermana de su madre, el prolog procedería otro nivel
mas debajo de su generación.

Si usted es el ultimo nivel o generación disponible (esto es, si no hay


ninguna bifurcación a partir suya), el Prolog se movería entonces hacia su
hermana. En ese momento, habiendo llegado hasta la parte mas
baja del árbol en su subrama, el prolog debe volver atrás hacia la
generación de su madre y proceder con su tía. Recuerde de
nuevo que el prolog se movería ahora hacia abajo por los
descendientes de su tía y trabajaría con ellos antes de volver a su
tía y luego a su abuela.
! (Corte)
¿Pero que sucede si usted sabe que la única respuesta correcta
vendrá de su madre y su hija? Si no quiere ninguna información
que pueda venir de una búsqueda a través de las hermanas de su
madre o su abuela, ¿Porque dejar que el prolog gaste tiempo en
Control de la vuelta atrás
Control en Prolog

eso? Puede parar dicho gasto con el “corte”.

La orden ! (“corte”) impide la vuelta atrás, actuando como una


válvula en un sentido. La búsqueda puede llegar por la cláusula
mas a la izquierda pero no puede volver a tratarla de nuevo
viniendo de la derecha. Cuando se encuentra una !, se libera las
variables vinculadas de la búsqueda de un objetivo o subobjetivo
particular de sus valores actuales. Eso significa que puede trabajar
dentro de una regla simple o incluso entre reglas. Si posteriores
cláusulas búsquedas por el objetivo hacen que falle, el prolog no
puede volver al punto antes de ! dentro de la búsqueda del
objetivo y examina otros valores para esas variables – incluso
aunque esos otros valores puedan permitir que el objetivo se
cumpla.
! (Corte)
Si escribe una regla con múltiples cláusulas como: A :- B, C, !, D.

El ! para el prolog cuando encuentra valores múltiples para B y C.


Control de la vuelta atrás
Control en Prolog

Examinemos como funciona esto.

En la búsqueda de un objetivo, el prolog se mueve hacia abajo en la sección de


cláusulas hasta que llega a la cabeza (“A”) de esta regla. Para satisfacer “A”, debe
primero satisfacer la parte derecha de la regla. El prolog toma primero la "B" e intenta
satisfacerla. Si el prolog no puede encontrar una identificación, falla la regla entera
(esta es una regla “and”, en la cual deben verificarse todas las cláusulas de la parte
derecha). Si puede encontrar una identificación para “B”, vincula las variables de “B”
a aquellos valores que permiten dicha identificación y luego se mueve a “C”. Puede
haber muchas otras posibilidades en las cláusulas (tales como otros hechos y reglas)
que podrían satisfacer “B”. Pero eso no importa ahora, porque el prolog solo quiere
que se produzca ahora una satisfacción.

Después de llegar a la "C”, el prolog busca una identificación de la misma. De nuevo, si


no puede encontrar dicha satisfacción fallara la regla entera, incluyendo “A”. Si
encuentra una identificación, entonces vinculara las variables de “C” a los valores que
realizan la identificación y se mueve hacia la cláusula ! . Las variables de “B” y de “C”
están ahora vinculadas a los primeros valores encontrados que satisfacen las cláusulas
“B” y “C”.
! (Corte)
La cláusula “!” se cumple automáticamente. No tiene ningún argumento a considerar y
no hay que identificarla con nada. Automáticamente es verdad. Pero tiene otro
efecto: las variables vinculadas a “B” y “C” quedan ahora atrapadas en su estado
actual.
Control de la vuelta atrás
Control en Prolog

Prolog procede con la “D”. Ahora buscara todas las posibilidades para “D”, intentando
encontrar algo en la base de datos que verifique a “D”. Si lo encuentra, la regla se
cumplirá porque todas las cláusulas a las que se ha llegado antes (“B”,”C” y “!”) se han
cumplido. Si no se encuentra una solución para “D”, fallara la regla entera, porque el
”!” detiene la vuelta atrás que se produciría para encontrar otros valores de “B” y “C”.

Recuerde que con la vuelta atrás normal, el prolog podría examinar el siguiente valor
de “C” y luego volver a encontrar un valor que verifique “D”. Puede encontrar tal valor
para “D” una vez que el valor de “C” sea diferente. Pero la “!” no permite dicha
posibilidad. Esta regla debe parar con la primera solución que encuentre para “B” y
“C”.
! (Corte)
Si se considera el siguiente ejemplo: (animales.pl)

DOMAINS
animal = symbol
Control de la vuelta atrás
Control en Prolog

PREDICATES
es_un_pato(animal)
suena_como_un_pato(animal)
parece_un_pato(animal)
anda_como_un_pato(animal)
CLAUSES
es_un_pato(X) :- suena_como_un_pato(X), parece_un_pato(X), anda_como_un_pato(X).
suena_como_un_pato(donald).
suena_como_un_pato(daysi).
parece_un_pato(donald).
parece_un_pato(daysi).
anda_como_un_pato(donald).
anda_como_un_pato(daysi).

Si consultamos: es_un_pato(X)

prolog responderá:

X = donald
X = daysi

2 soluciones
! (Corte)
Sin embargo si añadimos un corte como se muestra a continuación: (animales2.pl)

DOMAINS
animal = symbol
Control de la vuelta atrás
Control en Prolog

PREDICATES
es_un_pato(animal)
suena_como_un_pato(animal)
parece_un_pato(animal)
anda_como_un_pato(animal)
CLAUSES
es_un_pato(X) :- suena_como_un_pato(X), parece_un_pato(X), anda_como_un_pato(X), !.
suena_como_un_pato(donald).
suena_como_un_pato(daysi).
parece_un_pato(donald).
parece_un_pato(daysi).
anda_como_un_pato(donald).
anda_como_un_pato(daysi).

Y hacemos la misma consulta:

es_un_pato(X)
Es decir se obtendrá el primer nombre de
Prolog responderá: pato. La regla no permitirá volver atrás al
primer subobjetivo (“suena_como_un_pato”)
X = donald después de que se haya llegado al “corte”.
fail (fallo)
Otra orden incorporada para controlar la vuelta atrás, “fail”, es un predicado sin argumentos que
automáticamente falla y fuerza la vuelta atrás. En cierto sentido es opuesto al “corte”, el cual
elimina la vuelta atrás.
Control en Prolog

Un nuevo tipo de predicado.

Suponga por ahora que el prolog tiene un predicado incorporado que imprime la información
sobre la pantalla. Al igual que con cualquier predicado, el prolog intentaría hacer que esto se
cumpliera. Pero en este caso, en vez de mirar donde existe material para la identificación, el
prolog sabe todo lo que tiene que hacer para satisfacer el predicado es ejecutar alguna función.
Tales predicados son muy “procedurales” y evitan que el prolog sea solo un lenguaje de
programación declarativo estrictamente lógico. También hacen útil al prolog para las tareas de
programación corrientes.

Predicado “write” : Si se tiene: A :- write(“Hola a todos”).

Prolog sabe que tiene que satisfacer la parte derecha para satisfacer a “A”. La única acción
necesaria para satisfacer la parte derecha es escribir la frase: Hola a todos en la pantalla en la
posición actual del cursor. El predicado - write("Hola a todos") – puede suponerse que es verdad y
a su vez puede suponerse que es verdad el saludo.
Ejemplo: (pais.pl) Ejemplo añadiendo fail: (pais2.pl)

DOMAINS DOMAINS
lugar = symbol lugar = symbol
PREDICATES PREDICATES
saludar saludar
prolog_pais(lugar) prolog_pais(lugar)
Control en Prolog

CLAUSES CLAUSES
saludar:- saludar:-
prolog_pais(Pais),write(“Hola ”),write(Pais),nl. prolog_pais(Pais),write(“Hola ”),write(Pais),nl,fail.
fail (fallo)

prolog_pais(usa). prolog_pais(usa).
prolog_pais(peru). prolog_pais(peru).
prolog_pais(japon). prolog_pais(japon).

Si consultamos: Si consultamos:

saludar saludar

prolog responderá: prolog responderá:

Hola usa Hola usa


Hola peru
Hola japon
Sistemas Expertos

Unidad I

Introducción a los Sistemas Expertos

Semana 3

Manipulación del control de un Lenguaje basado


en reglas

You might also like