Está en la página 1de 10

Redes de Petri.

Es una técnica de especificación formal de sistemas. Es una herramienta gráfica. La


utilidad de una técnica de especificación o descripción formal (FDT) es la siguiente:
En un programa secuencial la forma de depurar es mediante prueba y error. Pero en
programación concurrente es mucho más difícil escribirlos, depurarlos y corregirlos; es incluso
complicado reproducir el caso específico en que un proceso puede fallar. Además, la fase de
depuración de un proyecto es muy costosa. Por todo esto se intenta que la depuración sea fácil,
pues además mientras más avanzados estemos en el proyecto más difícil será corregir un error
de diseño inicial.
Las FDT intentan disminuir los costes de depuración, dando unas especificaciones muy
claras de forma que un sistema será correcto si las cumple (se intenta probar que un sistema es
correcto incluso antes de implementarlo).
Hay multitud de FDT’s: Z, VDM, SOL, ESTELLE, LOTOS, redes de Petri, etc.
Las redes de Petri se utilizan para modelar sistemas siendo sus características las
siguientes:
• Hacen posible modelar comportamientos que comprenden concurrencia,
sincronización y recursos compartidos.
• Con ellas se puede comprobar si un sistema cumple ciertas características (de
esta forma se pueden detectar ciertos errores en el sistema incluso antes de su
realización.
• Si el análisis del sistema no es satisfactorio no podríamos abordar la
implementación; en caso contrario sí podríamos hacerlo con bastantes garantías.
Las aplicaciones más utilizadas son:
• Sistemas de fabricación (en industrias).
• Sistemas informáticos (sistemas operativos).
• Protocolos de comunicación.
Una red de Petri es un grafo orientado compuesto por dos clases diferentes de nodos:
• Los lugares: representados por una circunferencia o una elipse. Se llama P al
conjunto de los lugares. P será un conjunto finito y no vacío.
• Las transiciones: representadas por un trazo rectilíneo vertical. El conjunto de
transiciones es T y también es finito y no vacío.
Lugares y transiciones se unen alternativamente con arcos. O sea, un arco une una
transición con un lugar o viceversa pero no entre dos lugares o dos transiciones.
Formalemente una red de Petri es una cuádrupla que se compone de P, T, Pre, Post.
Pre está incluido en PxT. Post está incluido en TxP. Si el par (p,t) está incluido en
Pre, habrá un arco de p a t, y se dice que p es un lugar de entrada para t. Si el par (t,p) está
incluido en Post, habrá una flecha de t a p, y se dice que p es un lugar de salida para la
transición t.
Normalmente a las transiciones se les asocian acciones y a los lugares condiciones.
O sea, Pre marca las precondiciones de una transición. Asimismo, Post da las
postcondiciones de una transición.

Marcado de las redes de Petri.


En una red de Petri, los lugares pueden contener un número positivo o nulo de marcas
(tokens) las cuales se representan por puntos. Se habla de M(p) como el marcado del lugar p.
El número de marcas en una red de Petri no tiene por que ser constante a lo largo del
tiempo. Se denomina M0 al marcado inicial, y se dice que es la distribución de marcas en cada
uno de los lugares en el instante inicial.
Un marcado se puede representar como un vector, donde cada elemento se corresponde
con un lugar.
Se dice que una transición está sensibilizada o validada, o que es franqueable, si todos
sus lugares de entrada están marcados.
Una transición es franqueada o disparada si se verifica el acontecimiento (acción) a que
está asociada, en ese caso se dispara o franquea. El disparo o franqueo de una transición
consiste en :
• Se quita una marca de cada lugar de entrada de esa transición.
• Se añade una marca a cada lugar de salida de esa transición.
La primera transición se denomina transición fuente y no tiene ningún lugar de entrada.
La última es una transición sumidero y no tiene ningún lugar de salida.
Por ejemplo:
p1

p3

t1
p2
Suponiendo que el ejemplo anterior se refiere a una barbería:
• p1: un cliente espera.
• p2: el barbero espera.
• p3: un cliente está siendo atendido y el barbero trabaja.
• t1: el barbero empieza un afeitado.

Si la situación inicial es la anterior es que un cliente y el barbero están esperando.


Entonces t1 está validada y se disparará cuando el barbero comience. En ese instante, se quita
una marca de p1 y de p2 y se pone otra a p3: se cumple así la postcondición.
Ahora vamos a suponer que tenemos varios clientes:
t4
t2 p3 t3

p1
t1 p4
p2

• p1: cliente espera.


• p2: barbero inactivo.
• p3: cliente está siendo servido.
• p4: cliente atendido.
• t1: entra cliente.
• t2: barbero empieza.
• t3: barbero termina.
• t4: sale cliente.
Cuando entra un cliente, espera. Si hay un cliente esperando y el barbero está inactivo,
el barbero empieza. Cuando acaba, el cliente está atendido y puede salir.

Comportamientos modelables con las redes de Petri.


Con una red de Petri podemos modelar:
• Acciones secuenciales:

• Acciones concurrentes: t1 y t2 son transiciones que se pueden disparar


de forma concurrente:
t1
t2

• Exclusión mutua o conflicto: t1 y t2 comparten un lugar de entrada


común. Si dicho lugar de entrada estuviera marcado, t1 y t2 serían ambas
franqueables, pero sólo podemos disparar una. Se produce un conflicto. Además,
existe exclusión mutua entre ambas, se dispara una o la otra:
t1

t2
Hay dos tipos de conflictos:
• Estructural: También llamado potencial. Cuando el conjunto de los
lugares de entrada a alguna transición tiene intersección no vacía (hay algún lugar
de entrada común). Es el caso de la red de Petri anterior.
• Efectivo: Cuando existe un conflicto estructural y además las dos
transiciones son franqueables. Sería el ejemplo anterior pero con el lugar de entrada
marcado.
Es decir, el conflicto efectivo depende del marcado mientras que el estructural no. A
una red donde existe un conflicto se le denomina red no determinista, depende de si disparamos
una u otra transición. Así se producirá uno u otro efecto.

Ejemplo: Exclusión mutua en la utilización de un recurso compartido.


Tenemos dos procesos, A y B, y un recurso compartido R. Estamos en un punto donde
A y B esperan R, R está disponible.
En esta red hay un conflicto estructural (y efectivo) entre t1 y t4. Vemos que existe
exclusión mutua pues R lo toma A o lo toma B, pero no ambas. Si lo toma A, por ejemplo, hasta
que no se produce t2 no vuelve la marca a R disponible y no lo podría tomar B:

A espera R B espera R

t1 t4

R disponible
t3 A utiliza R B utiliza R

t6

t2 t5
Sincronización.
Es otro comportamiento modelable con una red de Petri.
Ejemplo: Comportamiento de las bolas de billar en un tablero. Supongamos un tablero
donde hay dos bolas, A y B, que chocan y rebotan.
Más adelante, A rebota contra el borde y vuelve, y B también rebota luego contra el
borde. Volverían a chocar, y este proceso (supuesto ideal) continuaría indefinidamente. Lo
meodelamos como una red de Petri:
A derecha B izquierda

Chocan
t2 t1 t3

A izquierda B derecha

La transición t1 es la que realiza la sincronización, hasta que las bolas no chocan, A y B


no cambian de sentido simultáneamente.
t2 y t3 son concurrentes por otro lado

Invariantes de marcado.
Son propiedades del marcado de una red de Petri que se cumplen siempre. Por ejemplo,
en el caso de las bolas de billar, dos invariantes de marcado son:

Mi(p1)+Mi(p3)=1
Mi(p2)+Mi(p4)=1
Esto nos dice que siempre estarán marcados p2 o p3, pero nunca ambas o ninguna de las
dos. Algo parecido sucede con p2 y p4.

Invariantes de disparo.
Son condiciones que se cumplen siempre en el disparo de las transiciones. En el
ejemplo de las bolas de billar, podemos decir que las posibles secuencias de disparo son t1t2t3
y t1t3t2, es decir, estas secuencias de disparo son repetitivas.

Propiedades básicas de las redes de Petri.


• Red de Petri viva: Una transición es viva para M0 si todas las
transiciones son vivas.
Viva No viva

• Transición viva: Una transición es viva para M0 si para todo M0 que se


puede alcanzar a partir de M0 existe un M’ sucesor de M a partir del cual se puede
disparar esa transición.
• Transición no viva: Si podemos llegar a un marcado donde esa
transición no se pueda ejecutar ya nunca más.
Las redes vivas nunca se bloquean. Las redes de Petri no vivas puden bloquearse pero
puede que no.
• Red de Petri parcialmente viva: A partir de M0, para todo marcado M,
sucesor de M’, alguna transición es disparable.
• Red de Petri binaria o sana: Si para cualquier marcado alcanzable a
partir del marcado inicial M0, ningún lugar posee más de una marca.
• Red de Petri no limitada: Si en cierto lugar se puede acumular un
número infinito de marcas.
• Lugar k-limitado: Si para cualquier marcado alcanzable desde el
marcado inicial el máximo número de marcas en ese lugar es K.
• Red de Petri k-limitada: Si todos sus lugares son k-limitados.
Las redes de Petri binarias son importantes pues son fáciles de implementar. Y la
importancia de las redes de Petri limitadas es que tendrán un número finito de estados.

Parcialmente viva
No binaria

Ejemplo: Productor-consumidor con exclusión mutua.


Estamos suponiendo que el almacén sólo tiene cuatro elementos.
• O indica el número de objetos que hay en el almacén.
• H indica el número de huecos que hay en el almacén.
• Ep indica el estado en el que el productor está esperando.
• Ec indica el estado en el que el consumidor está esperando.
• D indica que el productor está depositando un elemento en el almacén.
• P indica que el productor está produciendo un elemento.
• E indica que el consumidor está extrayendo un elemento.
• C indica que el consumidor está consumiendo un elemento.
• Ar asegura la exclusión mutua, de forma que si el consumidor dispara
la transición al lugar E (extrae un elemento), quita la marca de Ar y el productor no
podría depositar nada. Además, hasta que no se ejecute la transición E no habría
ninguna marca en H.
Una invariante de marcado sería:
M(Ar)+M(D)+M(E)=1
Debido a la exclusión mutua. Otra sería:
M(O)+M(H)+M(E)+M(D)=4
Pues el número total de objetos dentro del almacén es cuatro.
Ep H O Ec

Ar E
D

C
P
Tipos de redes de Petri.
Vamos a ver sólo los tipos más comunes. Hay muchos más:
• Redes de Petri ordinarias: Todos los arcos tienen el mismo peso
(unidad), no se involucra al tiempo, sólo hay un tipo de token o marca, la capacidad
de los lugares es infinita.
• Redes de Petri generalizadas: Son como las ordinarias con la diferencia
de que existen pesos diferentes asociados a los arcos. Ejemplo:

3 2

Esto indica que cuando se dispara esta transición, se quitan tres marcas del lugar de
entrada y se añaden dos marcas al lugar de salida. O sea, para disparar la transición se necesitan
tres marcas en el lugar de entrada.
• Redes de Petri coloreadas: En ellas se identifican los tokens por colores
(en general, las redes de Petri donde se identifican los tokens se denomina redes de
Petri de alto nivel).
• Redes de Petri temporizadas: En ellas existe un tiempo asociado, ya sea
a un lugar o a una transición. Si es a un lugar es que un token sólo puede
permanecer ese tiempo en dicho lugar. Si es a una transición indica el tiempo límite
para realizar la acción asociada a una transición.

Nota: Bibliografía de redes de Petri.


• “Las redes de Petri: Teoría y práctica” G. W. Brams (Ed. Masson).
• “Las redes de Petri en la Automática y la Informática” Manuel Silva
(Ed. AC).

ADA

Se usa para programación concurrente. Se convirtió en estándar ANSI. Usa el


mecanismo rendez-vous para comunicación entre procesos. Pueden establecerse muchos hilos
(tareas). Las tareas se especifican así (interfaz con otras tareas):
task nombre_tarea is
... (declaraciones)
end nombre tarea;
task body nombre_tarea is
... (sentencias)
end nombre_tarea;
Con task body se da el cuerpo de la tarea, su comportamiento dinámico.
Ejemplo: Una familia va a la compra y debe comprar carne, ensalada y vino.
procedure COMPRAR is
begin
COMPRAR_CARNE;
COMPRAR_ENSALADA;
COMPRAR_VINO;
end;
procedure COMPRAR is
task OBTENER_ENSALADA;
task body OBTENER_ENSALAD is
begin
COMPRAR_ENSALADA;
end OBTENER_ENSALADA;
task OBTENER_VINO;
task body OBTENER_VINO is
begin
COMPRAR_VINO;
end OBTENER_VINO;
task OBTENER_CARNE;
task body OBTENER_CARNE is
begin
COMPRAR_CARNE;
end COMPRAR_CARNE;
end COMPRAR;

Es una situación en paralelo; se activan todas las tareas definidas al llegar el último
begin (el del procedure); el procedimiento termina cuando lo hacen todas las tareas
definidas en él.
Citas: Se producen como consecuencia de la llamada de una tarea a un punto de entrada
de la otra.
Declaración del punto de entrada:
task T is
entry E(parámetros);
end;
Un punto de entrada no puede tener resultados (no es una función) como los
procedimientos (pueden devolver valores por los parámetros, pero no por sí mismas). Llamada:
nombre_tarea.E(parámetros)
En el cuerpo:
accept E(parámetros) do
sentencias
end E;
En otra tarea:

task body T2 is
...
T1.E(parámetros);
...
end T2;
T y T2 se ejecutan en paralelo hasta que se llega a la llamada del punto de entrada,
momento en el que se sincronizan; cuando se alcanza el end E; ambas siguen ejecutándose en
paralelo.
Ejemplo: Tarea que emplea un buffer de un único elemento:
task BUFFERING is
entry DEPOSITAR(x: in ITEM);
entry RETIRAR(x: out ITEM);
end;
task body BUFFERING is
v: ITEM;
begin loop
accept DEPOSITAR(x: in ITEM) do
v:=x
end DEPOSITAR;
accept RETIRAR(x: out ITEM) do
x:=v
end RETIRAR;
end loop;
end BUFFERING;
En otra tarea:
BUFFERING.DEPOSITAR(parámetros);
BUFFERING.RETIRAR(parámetros);
Si varias tareas llaman a la vez a un punto de entrada se almacenan en cola y se van
atendiendo conforme van terminando. Las colas pueden estar vacías (BUFFERING estará en
espera).
Los puntos de entrada pueden no tener parámetros, por ejemplo: entry SEÑALAR.
También puede haber una tarea cuyo accept no hace nada: accept SEÑALAR. Sólo
sincroniza tareas. Si una tarea se llama a sí misma se produce un interbloqueo (no tiene sentido).

Sentencia ‘select’.
Veamos una tarea que proporciona acceso exclusivo a una variable protegida.
task VAR_PROTEGIDA is
entry LEER(x: out ITEM);
entry ESCRIBIR(x: in ITEM);
end;
task body VAR_PROTEGIDA is
v:ITEM;
begin
accept ESCRIBIR(x: in ITEM) do
v:=x;
end;
loop
select
accept LEER(x: out ITEM) do
x:=v;
or
accept ESCRIBIR (x: in ITEM) do
v:=x;
end select;
end VAR_PROTEGIDA;
Condiciones de guarda: Condiciones a cumplir antes de llamar a un punto de entrada.
Ejemplo: Buffer finito.
task BUFFERING is
entry DEPOSITAR(x: in ITEM);
entry RETIRAR(x: out ITEM);
end;
task body BUFFERING is
N: constant:=8;
BUF: array (1...N) of ITEM;
ENT,SAL: INTEGER range 1...N:=1;
CUENTA: INTEGER range 0...N:=0;
begin
loop
select
when CUENTA<N =>
accept DEPOSITAR(x:in ITEM) do
BUF(ENT):=x;
end;
ENT:=(ENT+1) mod N;
CUENTA:=CUENTA+1;
or
when CUENTA>0 =>
accept RETIRAR(x: out ITEM) do
x:=BUF(SAL);
end;
SAL:=(SAL+1) mod N;
CUENTA:=CUENTA-1;
end select;
end loop;
end BUFFERING;
Las condiciones de guarda se comprueban cada vez que se entra en el select.
Siempre debe haber una condición que se cumpla (sino la petición de encola). Si en las
condiciones se comprueban variables globales no se garantiza que la condición de guarda se
siga cumpliendo a la hora de la cita (en este caso no porque son variables locales).
Otras estructuras para la sentencia select:

select
llamada al punto de entrada
else
sentencias
end select;

select
accept...
else
sentencias
end select;

select
llamada al punto de entrada
or
delay tiempo;
sentencias
end select;

select
accept...
or
delay tiempo;
sentencias
end select;

Si en lugar de or se pone else las sentencias (ya no hay delay) se aceptan si no se


realiza la llamada al punto de entrada (sin retraso, aunque en las sentencias puede ir delay, son
retrasos sin más).

También podría gustarte