1. máquinas de estados finitos - unslsel.unsl.edu.ar/licenciatura/ingsoft1/apuntes/2009/t3.pdf ·...
TRANSCRIPT
1
1. Máquinas de estados finitos
Cuando describimos sistemas de información, el énfasis está en la organización
de los datos y las operaciones relacionadas. Vemos, sin embargo, que para lograr que
las especificaciones sean más precisas, debemos prestar alguna atención también a los
aspectos de control. Por ejemplo, antes o después, uno debe especificar en un DFD si la
ejecución de una función debe esperar todas las entradas o puede comenzar tan pronto
como alguna de ellas se encuentre disponible. De forma similar, los lenguajes de
programación cuentan con construcciones para describir la organización de los datos y
con construcciones para describir el flujo de control.
En la especificación de diferentes sistemas, el balance entre datos y flujo de
control puede ser distinto. Por ejemplo, en un sistema de comunicaciones uno podría
primero querer establecer requisitos tales como:
� No se debe escribir en un buffer lleno o leer de un buffer vacío.
� No se debería acceder a un buffer mientras otro proceso está escribiendo en él.
� La lectura desde un buffer debe tener una prioridad mayor que la escritura.
� Todo mensaje debe ser pasado a través de algún canal dentro de 2 milisegundos.
Uno podría también prestar atención a aspectos funcionales tales como los
siguientes:
� Se debe controlar la paridad por cada mensaje recibido.
� Por cada 10 mensajes recibidos, un nuevo mensaje es producido el cual consiste
de la concatenación de los 10 mensajes, precedida por un encabezado que
especifica la dirección de la estación de recepción.
Así, tanto los sistemas de información, los de control como también otros tipos
de sistemas cuentan con aspectos funcionales y de datos así como aspectos de control.
Las herramientas de modelado usadas, sin embargo, podrían poner el énfasis en cada
uno de ellos de acuerdo a la naturaleza del sistema.
Las máquinas de estados finitos (MEF) son una herramienta de modelado
simple, ampliamente conocida e importante para describir aspectos de control. Una
MEF consiste de
1. Un conjunto finito de estados, Q;
2. Un conjunto finito de entradas, I;
3. Una función de transición δ: Q × I → Q. δ puede ser una función parcial, es
decir, puede estar indefinida para algunos de los valores del dominio.
Gráficamente, una MEF se muestra como un grafo cuyos nodos representan los
estados; un arco rotulado i va del estado q1 a q2 si y sólo si δ(q1, i) = q2. La Figura 1
muestra una máquina de estado finito muy simple donde Q = {q0, q1, q2, q3}; I ={a, b,
c}; δ(q0, a) = q1; δ(q1, a) = q2; δ(q1, b) = q3; δ(q2, b) = q; δ(q3, c) = q0.
2
Figura 1. Una máquina de estado finita
Como el término lo sugiere, las MEF son adecuadas para describir sistemas que
pueden encontrarse en un conjunto finito de estados y que pueden pasar de un estado a
otro como consecuencia de algún evento, modelado por algún símbolo de entrada. Por
ejemplo, una lámpara puede estar encendida o apagada y puede pasar de encendida a
apagada como consecuencia de una acción externa que consiste de pulsar una tecla.
Pulsar nuevamente la tecla causa la transición opuesta. Este sistema simple es descrito
por la MEF de la Figura 2.
Figura 2. Una máquina de estado finito que describe el funcionamiento de una tecla de una
lámpara.
Otro ejemplo simple del uso de una MEF es dado a continuación.
Ejemplo 1. Consideremos el control de una pequeña parte de una planta química. Los
niveles de temperatura y de presión deben ser monitoreados por razones de seguridad.
Se han instalado sensores para generar señales adecuadas cuando alguno de dichos
niveles excede un valor predefinido. Una política trivial para manejar la planta es la
siguiente: cuando alguna de las señales es originada por el correspondiente sensor, el
sistema de control apaga la planta y emite una señal de alarma; el sistema es re-iniciado
manualmente cuando la causa de la falla ha sido corregida. Todo esto se describe por la
MEF de la Figura 3.
Figura 3. Una MEF que describe el control de una planta química.
Esta política simple es obviamente inadecuada. Una mejor forma de manejar la
planta es la siguiente. Cuando se origina alguna de las dos señales, se invoca
automáticamente una acción de recuperación (existe una “acción de temperatura” y una
“acción de presión”). Si, después de un rato, la acción de recuperación tiene éxito, el
sistema es automáticamente re-inicializado al estado “normal” y un mensaje de “todo
3
OK” es emitido. En caso contrario, la señal de alarma debe ser lanzada y la planta debe
ser apagada. El sistema debe también ser apagado si se está tratando de recuperar de
algún tipo de anormalidad (de temperatura o presión) y la otra señal aparece. Se asume
que las dos señales no pueden ocurrir simultáneamente. Esta nueva política es descrita
por la Figura 4.
Figura 4. Una política refinada para el control de una planta química descrita por una MEF.
Las MEF son comúnmente usadas para especificar conjuntos de cadenas de
caracteres aceptadas, por ejemplo en un lenguaje. En tal caso, las MEF son aumentadas
definiendo un estado inicial q0 ∈ Q y un subconjunto F ⊆ Q de estados finales o de
aceptación, denotados gráficamente por nodos con dos círculos concéntricos. En este
caso el conjunto I denota el conjunto de caracteres usado para formar las cadenas de
entrada.
Las MEF son una notación simple y muy usada. Sus aplicaciones van desde la
especificación de sistemas de control a analizadores lexicográficos, reconocimiento de
patrones, diseño de hardware, e incluso aplicaciones por afuera de la computación. La
simplicidad, sin embargo, puede volverse una debilidad en algunos casos más
intrincados. Discutiremos los más relevantes desde el punto de vista de la especificación
de sistemas, con principal énfasis en la especificación de los sistemas de control, el cual
es uno de los principales campos de aplicación.
En primer lugar, las MEF son un dispositivo de memoria finita, como su nombre
lo sugiere. Esto implica que en muchos casos su “poder computacional” es limitado. Por
ejemplo, en el Ejemplo 1, supongamos que la respuesta a una temperatura anormal es
“Intentar un esfuerzo de enfriamiento es decir 2 * (temperatura_actual – valor_estandar)”.
El esfuerzo de enfriamiento en este caso no puede ser modelado por un dispositivo de
estados finitos porque sus posibles valores son infinitos.
Aun cuando el rango de posibles valores sea finito, que sería el caso de muchas
cantidades físicas de interés práctico, la descripción de las respuestas puede volverse
extremadamente compleja. La frase anterior es una especificación mucho mejor que una
MEF que usa un arco diferente por cada valor de temperatura entero, digamos, por
ejemplo, en un rango de 50 grados. Similarmente, aunque la memoria de una máquina
4
es siempre finita, consiste de un número de estados inmanejables: describir un registro
de 16 bits por medio de una MEF requiere 216 estados diferentes.
Cuando ocurren este tipo de situaciones, podemos tratarlas de diversas maneras:
� Podemos decidir no describir todos los detalles del sistema y conformarnos con
una aproximación que ignore los requisitos del tipo del de arriba. Después de
todo, la Figura 3 provee algún tipo de información aunque no se especifique la
“cantidad de un esfuerzo de enfriamiento”.
� Podemos cambiar de herramienta de modelado. Realmente, una gran variedad de
otras herramientas de modelado ha sido propuesta para solucionar este y otros
problemas. Algunas son modificaciones de las MEF originales; otras son
completamente diferentes.
� Podemos enriquecer la notación agregándole nuevos aspectos a las
descripciones para cubrir los nuevos requisitos. Por ejemplo, en el sistema del
Ejemplo 1, podríamos establecer, ya sea formalmente o informalmente, que la
transición desde el estado “normal” a un estado “recuperando_temperatura” debe
estar acompañado por una acción descrita como
esfuerzo_enfriamiento := 2 * (temperatura_actual – valor_estandar)
También, uno podría agregar predicados más complejos para llevar a cabo las
transiciones de estado, como en la siguiente descripción:
ifififif temp ≤ valor_muy_peligroso thenthenthenthen aplicar transición a estado “acción de temperatura” elseelseelseelse aplicar transición a estado “apagado” endendendend if if if if
Realmente, si llevamos a cabo este enriquecimiento de la notación original a su extremo
lógico, terminaremos con una definición completa de un nuevo tipo de MEF. Esto ha
sido hecho varias veces, tanto con MEF como con muchas otras herramientas de
modelado, con el objeto de obtener un lenguaje de especificación nuevo ad hoc.
Las MEF tienen otro inconveniente que es algo típico de las descripciones de los
sistemas de control. Este problema es explicado por el Ejemplo 2.
Ejemplo 2: Un proceso productor produce mensajes y los graba en un buffer de
capacidad para dos mensajes. Un proceso consumidor lee los mensajes y los saca del
buffer. Si el buffer se encuentra lleno, el productor debe esperar hasta que el proceso
consumidor haya vaciado un lugar. Similarmente, si el buffer se encuentra vacío, el
proceso consumidor debe esperar hasta que un mensaje haya sido colocado por el
productor. Los dos procesos y el buffer pueden ser descritos de forma separada por las
MEF de la Figura 5.
Aunque puede resultar útil examinar las tres componentes por separado, está
claro que los dos procesos, junto con el buffer, forman un único sistema sincronizado
que debe ser descrito como un todo.
5
Figura 5. Tres MEF separadas que describen un sistema productor-consumidor. (a) Productor. (b)
Consumidor (c) Buffer.
Una forma natural de atacar este problema es componer las diferentes MEF para
obtener una única MEF que describa todo el sistema. Intuitivamente, el conjunto de
estados resultante debería ser el producto cartesiano del conjunto de estados
componentes; además, los arcos que denoten la misma acción en diferentes
componentes deberían transformarse en un único arco en el grafo resultante. Aplicando
esta composición a la Figura 5, deberíamos obtener el grafo mostrado en la Figura 6. En
esta MEF, un estado tal como el <0, p2, c2> corresponde al buffer vacío, el productor en el estado p2, y el consumidor en el estado c2.
Esta aproximación no se encuentra libre de problemas. Primero, podemos ver
que, aun en el caso simple bajo consideración, la cardinalidad del espacio de estados
crece dramáticamente: si componemos n subsistemas, cada uno con ki estados, el
sistema resultante tendrá una cardinalidad de k1× k2 …× kn.
Figura 6. Una descripción de un sistema productor-consumidor dada por una MEF integrada.
Esta objeción, sin embargo, se encuentra algo mitigada por la consideración de
que lo que necesitamos es una descripción completa del sistema y no una MEF
completa que describa el sistema. Por lo tanto, podemos argumentar que toda la
información acerca del sistema viene dada por las tres componentes de la Figura 5,
aumentadas con reglas algorítmicas precisas para la composición de “módulos” de MEF
en MEF completas, sin necesidad de la descripción explícita de la Figura 6. En cierto
6
sentido, hemos construido una especificación modular del sistema, dejando su
integración a un “linker” de MEF.
Existe, sin embargo, una objeción aun más seria al uso de las MEF para la
descripción de sistemas que consisten de varias unidades concurrentes. Si miramos la
Figura 6, nos daremos cuenta de que ésta es una descripción inadecuada del sistema que
ha sido dada bajo ciertas asunciones restrictivas. Básicamente, el sistema se encuentra
siempre en un único estado y ejecuta exactamente una acción a la vez en un instante de
tiempo. No hay, sin embargo, razón para imponer una serialización entre la producción
y el consumo, dos acciones que son absolutamente independientes.
Una refutación posible a esta objeción es que la Figura 6 sigue siendo una
especificación adecuada del sistema concurrente porque el efecto de dos acciones
concurrentes y compatibles, como por ejemplo write y consume, es el mismo efecto que cualquier serialización de las dos acciones, ya sea write seguido por consume o consume seguido por write. Esta respuesta es parcialmente cierta. Funciona bastante bien si asumimos que el tiempo para cada transición es suficientemente corto como para
poder decir en cualquier instante t “el estado presente del sistema es, digamos, <1, p1, c2>”. En tal caso, con el fin de tratar eventos verdaderamente simultáneos podrían incluso definirse nuevas transiciones que fueran la “ejecución paralela” de las
transiciones elementales.
En cambio, supongamos que varias operaciones consumen tiempos de ejecución
bien diferentes; por ejemplo, consumir es mas largo que producir, el cual a su vez es
bastante mas largo que leer del buffer y que escribir en él. En este caso, podría ocurrir
que el productor y el consumidor comenzaran juntos (produciendo y consumiendo,
respectivamente). Después de un rato, el productor termina de producir y puede
empezar a escribir. Este, de nuevo, puede terminar antes que el consumidor haya
terminado con la operación original, y una nueva instancia de producción podría
comenzar. Por lo tanto, vemos que las transiciones de las distintas componentes ocurren
de una forma asíncrona que no puede ser adecuadamente descrita por la MEF de la
Figura 6.
El Ejemplo 2 muestra que las MEF son esencialmente modelos sincrónicos (en
cualquier instante de tiempo, debe estar definido un estado global del sistema y una
única transición puede ocurrir). Otros modelos son más apropiados para describir
sistemas que consisten de componentes asincrónicas y concurrentes, más aun si son
importantes los aspectos temporales, como por ejemplo el establecimiento de
restricciones de tiempo para la finalización de varias transiciones. En la próxima
sección, presentamos y evaluamos un modelo operacional que está explícitamente
dirigido a la descripción de sistemas concurrentes, las redes de Petri.
7
2. Redes de Petri
Las redes de Petri son un formalismo gráfico para la especificación de sistemas.
Se forman a partir de :
1. Un conjunto finito de lugares (places).
2. Un conjunto finito de transiciones; y
3. Un conjunto finito de arcos que conectan los lugares a las transiciones o las
transiciones a los lugares.
Más formalmente, una red de Petri es un multigrafo bipartito dirigido
representado por una cuádrupla P% = <P, T, I, O> donde
P = {p1, p2, ..., pn} es un conjunto finito de lugares, n ≥ 0
T = {t1, t2, ..., tm} es un conjunto finito de transiciones, m ≥ 0
I: T → P∞ P
∞ denota todos los multisets o bolsas de P.
pi ∈ I(tj) si existe un arco de pi a tj
O: T → P∞
pi ∈ O(tj) si existe un arco de tj a pi
Gráficamente, los lugares son representados por círculos y las transiciones por
barras. La Figura 7 muestra un ejemplo de una red de Petri.
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
Figura 7. Una red de Petri
La red de Petri de la Figura 7 es equivalente a la cuádrupla <P, T, I, O>, donde
P = {p1, p2, p3, p4, p5, p6, p7}
T = {t1, t2, t3, t4, t5, t6}
I(t1) = {p1} O(t1) = {p4}
I(t2) = {p2} O(t2) = {p5}
I(t3) = {p3, p4} O(t3) = {p6}
I(t4) = {p3, p5} O(t4) = {p7}
I(t5) = {p6} O(t5) = {p1, p3}
8
I(t6) = {p7} O(t6) = {p2, p3}
En la Figura 8 se ve otro ejemplo de una red de Petri en donde múltiples arcos
van desde un lugar a una transición o viceversa.
p1 p2
t1
p1 p2
t1
Figura 8. Una red de Petri
La red de Petri de la Figura 8 viene dada por la cuádrupla <P, T, I, O> donde
P = {p1, p2}
T = {t1}
I(t1) = {p1, p1}
O(t1) = {p2, p2, p2}
La función I devuelve el multiset formado por los lugares desde los cuales sale
un arco a una transición dada. Dichos lugares reciben el nombre de lugares de entrada
(input places). La función O devuelve el multiset de los lugares a los cuales llega un
arco desde una transición dada. Dichos lugares reciben el nombre de lugares de salida
(output places). Notar que en la red de la Figura 8 se puede observar el hecho de que las
funciones I y O devuelven un multiset y no un conjunto.
Una red de Petri recibe su estado marcando sus lugares. Una marcación
(marking) consiste en asignar un número entero no negativo a cada lugar de la red. Esto
es representado gráficamente asignando un número de tokens a cada lugar. En las redes
tradicionales de Petri los tokens son indistinguibles y no representan información
específica. La Figura 9 muestra una red de Petri marcada.
• •p1 p2
t1
• •p1 p2
t1
Figura 9. Una red de Petri marcada.
Formalmente, una marcación de una Red de Petri P% = <P, T, I, O> es una
función:
µ: P → {0, 1, 2, ...}
que asigna un número entero no negativo (de tokens) a cada lugar de la red.
Una marcación puede representarse como un vector de dimensión n, donde n es
el número de lugares de la red. Así, por ejemplo, para la red de la Figura 9 tenemos que
µ(p1) = 2 y
µ(p2) = 0, o su equivalente representación vectorial µ = (2,0).
Una red de Petri marcada M = <P%, µ> es un una estructura de red de Petri P%
= <P, T, I, O> y un marking µ. Por ejemplo, la Figura 10 muestra la misma red de la Figura 7 pero con su
marcación inicial µ = (1, 1, 1, 0, 0, 0, 0).
9
Durante la ejecución de la red, el número y posición de los tokens puede variar
dando lugar a una nueva marcación. Cada marcación corresponde a un estado de la red.
•
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
•
•
•
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
•
•
Figura 10. Una red de Petri y su marcación inicial µµµµ = (1, 1, 1, 0, 0, 0, 0).
Para ejecutar una red de Petri se deben seguir una serie de reglas de ejecución:
1) Una transición puede disparar si está habilitada.
2) Una transición está habilitada si en cada uno de sus lugares de entrada existen al
menos tantos tokens como arcos existan desde cada lugar a la transición.
• •p1 p2
t1
•p1 p2
t1 no habilitada
t1
t1 habilitada,
puede disparar
• •p1 p2
t1
• •p1 p2• •p1 p2
t1
•p1 p2
t1 no habilitada
t1
t1 habilitada,
puede disparar
•p1 p2•p1 p2
t1 no habilitada
t1
t1 habilitada,
puede disparar
Figura 11. Ejemplos de transiciones habilitadas y no habilitadas.
La transición t1 de la red de la parte izquierda de la Figura 11 no está habilitada
porque para estarlo debería tener al menos dos tokens, mientras que la de la parte
derecha sí lo está.
Formalmente, diremos que una transición t ∈ T está habilitada en una red de
Petri P% = <P, T, I, O> si y sólo si
∀p ∈ I(t) : µ(p) ≥ #(p, I(t))
donde #(p, I(t)) es el número de arcos que van desde p a t.
3) Cuando una transición dispara, en cada uno de sus lugares de entrada se quitan tantos
tokens como arcos existan desde el lugar de entrada hacia la transición, y en cada uno
de los lugares de salida de la transición se insertan tantos tokens como arcos existan
desde la transición al lugar de salida. Por ejemplo, en la Figura 12 se ve como los tokens
se mueven en la red luego de que la transición t1 disparó.
Formalmente, el disparo de una transición t ∈ T con un marking µ resulta en un nuevo marking µ’ definido por:
∀p ∈ P : µ’(p)= µ(p) − #(p, I(t)) + #(p, O(t))
donde #(p, I(t)) es el número de arcos desde p a t y #(p, O(t)) es el número de arcos
desde t a p.
10
•••p1 p2
t1
• •••p1 p2
t1
Disparó t1
p3 • p3•p4 p4
•••p1 p2
t1
• •••p1 p2
t1
Disparó t1
p3 • p3•p4 p4
Figura 12. Ejemplo de disparo de una transición.
•
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
•
••
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
•
•
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
••
•
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
••
•
(a) (b)
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
• •
•
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
• •
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
• •
•
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
•• •
t1 t2
t3 t4
t5 t6
p1 p2
p4p3
p5
p7p6
•• •
(c) (d)
Figura 13. Evolución de una red de Petri.
En la Figura 13(a) tanto t1 como t2 están habilitadas y ninguna otra transición
está habilitada. En tal caso, la marcación de la red puede evolucionar en dos formas
diferentes, ya sea disparando t1 o disparando t2. Por lo tanto, el modelo es no
determinístico, en el sentido de que dada una marcación inicial, diferentes evoluciones
de la red de Petri son posibles. En el caso de la Figura 13(a), el disparo de t1 produciría
la marcación de la Figura 13(b), mientras que el disparo de la transición t2 produciría la
marcación de la Figura 13(c). Notar que, después de que t1 dispara, t2 sigue aun
habilitada y podría disparar. De igual manera, t1 quedaría habilitada si t2 disparase
primero. En cualquier caso, la red podría alcanzar la marcación de la Figura 13(d). A
este punto, t3 y t4 están ambas habilitadas y cualquiera podría disparar de forma no
11
determinística. Esta vez, sin embargo, el disparo de una impide el disparo de la otra. Por
ejemplo, si t3 dispara, t4 dejará de estar habilitada.
Cuando una transición no tiene lugares de entrada está siempre habilitada ya que
cumple con la condición ∀p ∈ I(t) : µ(p) ≥ #(p, I(t)) para estar habilitada. Por ejemplo,
la transición t1 de la Figura 14 está siempre habilitada.
t1 t3
t2
t1 t3
t2
Figura 14. t1 está siempre habilitada.
Antes de seguir adelante con el análisis del comportamiento de las redes de
Petri, interpretémoslas como un modelo para la descripción de sistemas concurrentes.
En una red de Petri,
� una transición, usualmente, modela un evento o acción;
� el disparo de la transición representa la ocurrencia de tal evento o la
ejecución de la acción;
� una transición está habilitada, si se satisfacen las condiciones necesarias para
la ocurrencia de tal evento o acción;
� la presencia de tokens en los lugares de entrada modelan tales condiciones.
Si miramos la Figura 13(a), podemos interpretar sus dos partes, las que consisten
de las transiciones t1, t3 y t5, y t2, t4 y t6, respectivamente, como dos actividades
independientes que fluyen a través de eventos modelados por las transiciones. Las dos
actividades comparten un recurso común, modelado por el lugar p3. Ellos podrían ser
dos procesos diferentes que usan la misma CPU, o dos estudiantes compartiendo un
libro, etc.
Inicialmente, las dos actividades pueden proceder de forma independiente y
asincrónica. En efecto, t1 y t2 están ambas habilitadas, y el disparo de una no
deshabilita el disparo de la otra. En tal caso, decimos que las transiciones son
concurrentes. Esta situación podría modelar por ejemplo la edición independiente de
dos programas en diferentes terminales, o la lectura por parte de dos estudiantes de sus
notas personales de clase. Después de que ambas transiciones han disparado, (notar que
esto no necesariamente ocurre. Por ejemplo, después de que t1 ha disparado, t3 podría
disparar. Esto deshabilitaría a t2 hasta que t5 dispare) sin embargo, ambas actividades
están habilitadas de nuevo para proseguir, pero con exclusión mutua. Esto es mostrado
por la Figura 13(d). El recurso modelado por p3 está realmente disponible, pero
solamente para una de las dos actividades, siendo la elección no determinística. En este
caso, decimos que ambas transiciones están en conflicto.
Supongamos que el recurso es dado a la actividad de la izquierda de la figura.
Entonces la red podría proseguir a través de t3 y t5, dejando a la otra actividad
temporalmente bloqueada. El disparo de t5 libera el recurso que ahora está de nuevo
libre para su uso. A este punto, t4 podría disparar. Pero también es posible que, por el
contrario, t1 dispare de nuevo, y entonces la elección entre t3 y t4 sea resuelta una vez
más a favor de t3. Esto podría repetirse para siempre.
12
Este modelo no impone ninguna política para resolver situaciones de conflicto.
En la terminología de los sistemas concurrentes, un proceso que nunca recibe acceso a
un recurso que necesita, se dice que sufre starvation (pasa hambre). De esta forma,
secuencias de disparo donde solo las transiciones t1, t3, t5 ocurren conducen a
starvation de la actividad sobre el lado derecho de la figura.
Ahora, asumamos que la marcación inicial de la red tiene dos tokens en p3 en
lugar de uno. Esto significa que dos recursos indistinguibles están disponibles. Como
una consecuencia, t3 y t4 no están mas en conflicto, sino que son concurrentes. Si las
dos actividades representan procesos de computadora y dos CPU están disponibles para
ellos en una máquina con multiprocesadores, los dos procesos podrían ejecutarse en
paralelo.
La Figura 15 es una modificación de la Figura 13(a). Modela el caso en donde
las dos actividades necesitan dos copias idénticas del recurso para proceder. Esas copias
son modeladas por dos tokens en p3. Después de que una actividad comienza, por
ejemplo la de la izquierda, disparando la transición t1, podría obtener cualquiera de los
recursos disponibles (disparando t3’). Luego, intentar obtener también el otro recurso
(disparando t3’’). Una vez que la actividad ha obtenido ambos recursos, la ejecución
podría proceder, eventualmente liberando ambos recursos (disparando t5).
t3’ t4’
t3’’ t4’’
t5 t6
p4 p5
p6
p3
p7
p9p8
•
p1 p2
t1 t2
•
• •
t3’ t4’
t3’’ t4’’
t5 t6
p4p4 p5
p6
p3
p7
p9p8
•
p1 p2
t1 t2
•
• •
Figura 15. Una red de Petri que puede entrar en estado de deadlock.
Consideremos, sin embargo, la secuencia de disparos <t1, t3’, t2, t4’>, la cual
conduce a una marcación donde ninguna transición está habilitada. Por lo tanto, la red
no puede llevar adelante ningún progreso. Cada actividad ha obtenido uno de los
recursos y necesita el otro para seguir adelante. Pero esto no puede ocurrir porque el
recurso necesario está en manos de la otra actividad, la cual a su vez también está
esperando por un recurso más.
Esta es una situación típica de deadlock, la cual es modelada bastante bien por
una red de Petri. Formalmente, una red de Petri con una marcación se dice que está en
deadlock si y sólo si ninguna transición está habilitada en esa marcación. Una red donde
el deadlock no puede ocurrir comenzando desde una marcación dada se dice que está
viva.
Volvamos ahora al ejemplo del sistema productor-consumidor modelado con la
MEF en el Ejemplo 2. Las tres componentes separadas del sistema podrían ser
modeladas por las tres redes de Petri de la Figura 16.
13
p2 p1
produce
write
c1 c2
read
consume
0
write
read
write
read
1 2
⋅ ⋅
⋅
Figura 16. Tres redes de Petri separadas que describen un sistema productor-consumidor.
Gráficamente, la composición de los tres subsistemas en una red de Petri es dado
en la Figura 17. La figura muestra que el principal inconveniente de la correspondiente
representación dada por la MEF de la Figura 6 se encuentra ahora resuelto de forma
satisfactoria. En primer lugar, la complejidad gráfica de la figura no multiplica el
espacio de estados de las componentes, sino que es sólo aditivo. En efecto, en la Figura
6 el número de nodos coincide con el número de estados. En la Figura 17, el número de
estados está dado por el número de posibles marcaciones.
consume
p1 p2
produce
c1 c2
read
1 0
write
2
read
write
⋅
⋅
⋅
Figura 17. Una red de Petri integrada que describe un sistema productor-consumidor.
Segundo, y más importante, en la Figura 17, la concurrencia de las actividades
independientes es descrita adecuadamente. En efecto, si el sistema está en el estado <1, p1, c2>, es decir que hay un token en cada uno de esos lugares, tanto la transición produce y consume están habilitadas. Es decir, las dos transiciones son concurrentes (ellas pueden ser ejecutadas en paralelo sin anular el disparo de una a la otra). También,
mirando la secuencia de disparos
14
<produce, write, produce, read, consume, write, read, consume>
se ve inmediatamente qué acciones podrían ocurrir concurrentemente y cuáles deben ser
serializadas porque la terminación de una es necesaria para el inicio de la otra.
2.1 Limitaciones y extensiones de las Redes de Petri
Aunque las redes de Petri modelan ciertos aspectos de los sistemas bastante bien,
su uso en aplicaciones ha revelado algunas debilidades también. En primer lugar son,
como las MEF, un modelo orientado al control. Los tokens típicamente representan el
flujo de control en la ejecución de varias acciones. Los tokens, sin embargo, son
anónimos. Por ejemplo, la presencia de un token en algún lugar puede denotar
solamente la presencia de un mensaje en el buffer, no lo que el mensaje dice.
Esta simplicidad puede ser útil. Frecuentemente, por ejemplo, cuando estamos
interesados en analizar el flujo de los mensajes dentro de una red de comunicación, un
aspecto importante es si un mensaje que ha sido producido en algún lado será o no
entregado en otro. En tales casos, el contenido real del el mensaje puede ser un detalle
irrelevante.
Pero no siempre la cosa es así. Por ejemplo, supongamos que queremos
especificar un sistema en el cual un mensaje debe enviarse a través de uno o dos canales
diferentes: channel1 es seleccionado si el mensaje está bien formado; channel2 (el canal de error) es seleccionado si el mensaje es incorrecto. El mensaje es bien formado
si contiene un número par de 1’s (es decir, si tiene una paridad correcta).
La Figura 18 muestra una especificación de red de Petri tentativa de tal sistema.
Esta red, sin embargo, sugiere que la elección entre los dos canales es no determinística
cuando un mensaje está listo para ser enviado (representado por un token en el lugar p).
No es una descripción adecuada del sistema que hemos descrito con palabras, dado que
la elección entre los canales está dictada por el contenido del mensaje.
channel1
p
•
channel2
Figura 18. Una porción de una red de Petri que describe el envío de mensajes a través de diferentes
canales.
En nuestro ejemplo, el disparo de una transición debería depender de lo que dice
el mensaje, el cual es representado por un token. Pero esto es claramente imposible, ya
que el token no dice absolutamente nada; un token solamente denota la presencia de un
mensaje. Además de poder asociar lo que un mensaje dice (sus valores) con los tokens,
sería también útil poder computar los valores de los tokens. Entonces, al recibir un
mensaje, una estación podría modificar un mensaje antes de enviarlo, por ejemplo
agregándole un campo con una dirección adicional. Estos problemas son todos comunes
a los modelos orientados al control.
Otra desventaja de las redes de Petri es el hecho de que, en el caso general, no es
posible especificar una política de selección entre diferentes transiciones habilitadas.
Por ejemplo, volviendo a la Figura 13(a), hemos ya notado la posibilidad de que la
secuencia <t1, t3, t5> se repita indefinidamente, provocando starvation de la actividad
consistente en <t2, t4, t6>. Para evitar el starvation en este caso, podríamos forzar una
15
política alternativa modificando la red levemente de manera tal de que las actividades se
alternen en el acceso al recurso.
Sin embargo, puede ser probado matemáticamente, que, en el caso general, las
redes de Petri no son capaces de describir una política tal como
if transición t está habilitada then
disparar t;
else
disparar la primera transición habilitada
de acuerdo a algún criterio de orden.
end if
El tiempo es otro aspecto crítico en algunos sistemas. En algunos sistemas de
tiempo real, una falla para computar una respuesta dentro de un tiempo dado tiene los
mismos efectos graves de no computarla o de computarla incorrectamente. También, el
resultado de un cómputo puede depender de la velocidad de la ejecución de algunas
acciones.
Por ejemplo, supongamos que una línea externa envía mensajes a una
computadora a una velocidad dada. Cada mensaje que es recibido es grabado en un
buffer y luego procesado. Si un mensaje no es sacado del buffer antes de que arribe el
próximo mensaje, es sobrescrito. Por lo tanto, el resultado del procesamiento puede
variar dependiendo de los tiempos de arribo de los mensajes.
Desafortunadamente, la mayoría de los modelos de los sistemas de
computadoras, incluyendo las redes de Petri, no toman en cuenta el tiempo
explícitamente. La consecuencia es una falta de profundidad en el modelado y en el
análisis. Por ejemplo, consideremos de nuevo la red de Petri de la Figura 13(a). Si t1, t3
y t5 toman un segundo cada una en completarse, y t2 toma 5 segundos, está claro que la
secuencia de disparos <t1, t2, t3, t5, t4> no es posible, contrariamente a lo que la red
sugiere. En efecto, supongamos que en el instante de tiempo 0 tanto t1 como t2 se
disparan. En el tiempo 1, t3 puede comenzar pero t2 no se ha completado aun. Por lo
tanto, si el disparo de una transición modela la ejecución completa de la actividad
correspondiente, el disparo de t2 no puede ocurrir antes del disparo de t3.
Afortunadamente, la flexibilidad del modelo ha permitido que sea extendido en
varias direcciones mientras que mantiene su “filosofía” original. Reveamos algunas
modificaciones bastante estándar a las redes de Petri que han probado ser útiles en
varias circunstancias.
Asignación de valores a los tokens. Los tokens pueden ser modificados para llevar un
valor de un tipo adecuado: un entero, un arreglo de bytes, o incluso un ambiente
completo que consista de varias variables y valores asociados. De igual manera,
predicados y funciones se asocian con las transiciones con el siguiente significado: una
transición con k lugares de entrada y h lugares de salida está habilitada si existe una k-tupla de tokens, uno por cada place de entrada, tal que el predicado asociado con la
transición es satisfecho por los valores de los tokens de la tupla. Esos tokens conforman
una tupla ready.
Notar que el predicado es evaluado sobre exactamente un token sobre cada lugar
de entrada. Por lo tanto, podría haber más de una tupla ready para algunas transiciones;
16
es decir, el mismo token podría pertenecer a diferentes tuplas ready. Cuando una
transición dispara, implica todo lo siguiente:
� La eliminación de todos los tokens que pertenecen a la tupla ready de los lugares
de entrada (si existe más de una tupla ready, la elección es no determinística).
� La evaluación de h nuevos valores de tokens sobre la base de los valores de la tupla ready aplicando la función asociada a la transición (por lo tanto, tal función
tiene como dominio una k-tupla y como rango una h-tupla).
� La producción de un token por cada lugar de salida, cuyo valor es calculado por
la función asociada con la transición.
Por ejemplo, consideremos la red de Petri de la Figura 19, donde se asume que
los tokens llevan valores enteros. La notación es auto-explicativa: el nombre de un lugar
en un predicado o función representa un token en ese lugar. Ambas transiciones t1 y t2
están habilitadas. La transición t1 tiene dos tuplas ready, (3, 7) y (3, 4) ya que ambas
tuplas satisfacen el predicado p2 > p1. El token con valor 1 en p2 no pertenece a
ninguna tupla ready. Por lo tanto, el disparo t1 usando la tupla ready (3, 4) produciría un
token con valor 7 en p4 y deshabilitaría a t2, ya que los tokens 3 y 4 desparecerían de p1
y p2 respectivamente. En cambio, el disparo de t1 usando la tupla (3, 7) produciría el
valor 10 en p4. Después de esto, t2 podría aun disparar, produciendo el valor 0 en p4 y 8
en p5.
t1 t2
p1
p2
p3
p5p4
7
4134
p1 < p2
p4:=p2+p1
p2 = p3
p4:=p3-p2
p5:= p2+p3
t1 t2
p1
p2
p3
p5p4
7
4134
t1 t2
p1
p2
p3
p5p4
7
4134
p1 < p2
p4:=p2+p1
p2 = p3
p4:=p3-p2
p5:= p2+p3
Figura 19. Una red de Petri cuyos tokens cargan valores. El predicado p2>p1 y la función
p4:=p2+p1 están asociados a t1; el predicado p3=p2 y las funciones p4:=p3-p2 y p5:=p2+p3 están
asociados a t2.
Este primer enriquecimiento a la notación de redes de Petri permite una solución
natural y simple al problema de la Figura 18. En efecto, sería suficiente considerar los
tokens como que llevan un valor del tipo de los mensajes, digamos, secuencias de bits.
El predicado “p tiene un número par de 1’s” puede entonces ser asignado a la transición
channel1 y análogamente para la transición channel2. También, si el envío de los
mensajes a través de los canales implica alguna modificación de los mensajes, esto
puede ser hecho en una forma natural agregando funciones apropiadas a las
transiciones.
Especificando políticas de prioridades. Cuando el no determinismo de las redes de
Petri no es adecuado, nos enfrentamos con el problema de especificar una política para
seleccionar una transición que dispare primero entre todas las transiciones habilitadas.
Una forma bastante simple de hacerlo es asignar prioridades a las transiciones. Entonces
modificamos la regla de disparo de la siguiente manera: si, en algún estado, varias
transiciones se encuentran habilitadas, solamente aquellas con la máxima prioridad se
les permite disparar.
17
Las prioridades son generalmente definidas estáticamente. Si los tokens llevan
valores, sin embargo, podemos definir prioridades dinámicas cuyos valores dependan de
los valores de los tokens en los lugares de entrada de las transiciones.
Redes de Petri temporizadas. Cuando uno quiere introducir el tiempo en los modelos
computacionales formales surgen problemas teóricos sutiles. Este, sin embargo, no es el
lugar para entrar en tales problemas teóricos. Solamente mencionaremos la idea de que
el tiempo ha sido agregado a las Redes de Petri en muchas maneras. Aquí describiremos
una de las formas más simples y naturales de introducir el tiempo en las redes de Petri
rascando solamente en la superficie de este problema difícil.
Las redes de Petri temporizadas son redes de Petri en las cuales un par <tmin,
tmax> se asocia con cada transición. Nuevamente, tales valores pueden ser constantes o
calculados como funciones de los valores de los tokens en los lugares de entrada. La
idea es que una vez que una transición está habilitada, debe esperar que pase por lo
menos un tiempo tmin antes de poder disparar. También, si está habilitada, debe disparar
antes de que haya pasado un tiempo tmax, a menos que sea deshabilitada por el disparo
de otra transición antes de tmax. Una red de Petri temporizada es equivalente a una red de
Petri original si, para cada transición, tmin = 0 and tmax = ∝.
Las modificaciones temporales y otras modificaciones pueden obviamente ser
combinadas. Así que si agregamos tiempo y prioridades a las transiciones, es necesario
tener cuidado al determinar qué transición puede o debe disparar y en qué tiempo. Una
regla natural es que si varias transiciones pueden disparar (esto no significa solamente
que ellas están habilitadas, sino también que cada una está habilitada durante su
intervalo [tmin, tmax]), entonces solamente las transiciones con las máximas prioridades
pueden realmente disparar, dentro de un tiempo que es menor o igual a sus tmax.
Por ejemplo, consideremos la red de la Figura 20. Supongamos que en el tiempo
t = 0 la marcación es modificada por el arribo de un token en p2, de modo que tanto t1
como t2 quedan habilitadas al mismo tiempo. En tal caso, podría ocurrir que t1 dispare
en un tiempo menor a 2. Si no dispara dentro de ese tiempo, sin embargo, no puede
disparar más, porque en el tiempo t = 2 t2 puede disparar también, y tiene una prioridad
más alta que t1. Ahora, si en el tiempo t = 1 un token es producido en p4, entonces
durante el intervalo 1 ≤t< 2, tanto t3 como t1 pueden disparar, pero t1 no puede disparar
antes que t3 porque tiene menor prioridad.
•
t1 t2
p1
p2
p3 •
p4
prioridad = 3 tmin = 2
tmax = 3
prioridad = 1
tmin = 1
tmax = 4
prioridad = 2
tmin = 0
tmax = 5
t3
Figura 20. Una red de Petri temporizada.