Ejercicio de TADs completo. Algoritmos y Estructuras de Datos II Segundo Cuatrimestre 2010 Enunciado La empresa XYZ desea contar con una especificación formal de su proceso de producción. Las tareas y el orden de ejecución de las mismas están definidos a través de un workflow. Un workflow especifica el conjunto de todas las tareas que deben ser ejecutadas en el proceso y el orden de precedencia de las mismas. La siguiente tabla muestra un workflow simple compuesto por cuatro tareas T0 , T1 , T2 , T3 : Tarea Requiere T0 T1 T0 T2 T0 T3 T1 , T2 La columna Requiere establece el orden de ejecución de las tareas. Por ejemplo, T1 y T2 pueden ser ejecutadas luego de que T0 ha sido completada (notar que estas dos tareas podrı́an ser ejecutadas en paralelo). T0 es la tarea inicial del workflow, dado que no tiene tareas precedentes, y T3 es la tarea final, ya que no tiene tareas sucesivas. La definición de un workflow debe respetar las siguientes restricciones: tiene una única tarea inicial, tiene una única tarea final, y no existen dependencias circulares. Por ejemplo, no podrı́a definirse en el workflow anterior que T1 requiere T0 y T3 . Un proceso de producción está definido por un único workflow que se establece al momento de creación del proceso y permanece invariable en el tiempo. Una vez definido un proceso de producción es posible comenzar a procesar órdenes. Cada vez que arriba una nueva orden, ésta se coloca en producción. La producción de una orden es muy simple: cada tarea comienza a ejecutarse apenas se encuentra disponible la máquina que tiene asignada, y siempre y cuando todas las tareas que la preceden hayan sido ejecutadas. La máquina asignada a una tarea no estará disponible para la ejecución de otra hasta tanto la misma finalice. Por ejemplo, considere un proceso definido con el workflow anterior. Cuando llega la primera orden de producción O1 , automáticamente se inicia la ejecución de su tarea inicial T0 . Si antes de que finalice la tarea T0 , llega una orden O2 , la misma se mantiene en espera a que se libere la máquina asignada a T0 . Apenas finaliza la ejecución de T0 , las tareas T1 y T2 podrán iniciarse para la orden O1 , mientras que la tarea T0 podrá iniciarse para O2 . Si luego finalizan las tareas T1 de O1 y la T0 de O2 , entonces la tarea T1 debe iniciarse para la orden O2 , aunque la tarea T3 para O1 no se inicia hasta que no finalice la tarea T2 . La polı́tica de selección de tareas a iniciar en caso de que haya más de una orden esperando una máquina será un criterio determinı́stico que precisará la empresa en el futuro. Se solicita describir la dinámica de los procesos de producción de la empresa XYZ utilizando TADs. Se desea conocer en todo momento el estado de ejecución de las órdenes ingresadas, es decir, si las mismas ya fueron completadas o no, y para el caso de las órdenes no completadas, cuáles son las tareas finalizadas y cuáles se encuentran en ejecución. 1 Resolución TAD Planta de producción géneros planta exporta observadores, generadores, otras operaciones (exportadas) igualdad observacional (∀p, p0 : planta) p =obs observadores Workflow Ordenes EnEspera Ejecutando? EnEjecucion Workflow(p) = Workflow(p0 ) ∧ Ordenes(p) = Ordenes(p0 ) ∧ 0 (∀t : tarea)(t ∈ Tareas(p) ⇒L EnEspera(p, t) = EnEspera(p , t) ∧ p0 ⇐⇒ Ejecutando?(p, t) = Ejecutando?(p0 , t) ∧L 0 (Ejecutando?(p, t) ⇒L EnEjecucion(p, t) = EnEjecucion(p , t))) básicos : planta : planta : tarea t × planta p : tarea t × planta p : tarea t × planta p −→ −→ −→ −→ −→ workflow conj(orden) conj(orden) bool orden generadores Crear : workflow w −→ planta AgOrden : orden o × planta p −→ planta Terminar : tarea t × planta p −→ planta otras operaciones (exportadas) Tareas : planta Predecesoras : tarea t × planta p OrdenesFinalizadas : planta TareasFinalizadas : orden o × planta p TareasEnEjecucion : orden o × planta p −→ −→ −→ −→ −→ {t ∈ Tareas(p)} {t ∈ Tareas(p)} {t ∈ Tareas(p) ∧L Ejecutando?(p, t)} {#finales(w) = 1} {o 6∈ Ordenes(p)} {t ∈ Tareas(p) ∧L Ejecutando?(p, t)} conj(tarea) conj(tarea) conj(orden) conj(tarea) conj(tarea) otras operaciones (no exportadas) Esperando? : tarea t × tarea t0 × planta p −→ bool QuéEjecutan : conj(tarea) ct × planta p −→ dicc(tarea, orden) {t ∈ Tareas(p)} {o ∈ Ordenes(p)} {o ∈ Ordenes(p)} {{t, t0 } ⊆ Tareas(p)} {ct ⊆ Tareas(p)} axiomas Workflow(Crear(w)) ≡ w Workflow(AgOrden( , p)) ≡ Workflow(p) Workflow(Terminar( , p)) ≡ Workflow(p) Ordenes(Crear( )) ≡ ∅ Ordenes(AgOrden(o, p)) ≡ Ag(o, Ordenes(p)) Ordenes(Terminar( , p)) ≡ Ordenes(p) EnEspera( , Crear( )) ≡ vacı́a EnEspera(t, AgOrden(o, p)) ≡ if t = 0 ∧ Ejecutando?(t, p) then {o} else ∅ fi ∪ EnEspera(t, p) EnEspera(t, Terminar(t0 , p)) ≡ if t = t0 ∧ ¬∅?(EnEspera(t, p)) then SinUno(EnEspera(t, p)) else if Esperando?(t, t0 , p) ∧ Ejecutando?(t, p) then {o} else ∅ fi ∪ EnEspera(t, p) fi Ejecutando?( , Crear( )) ≡ false Ejecutando?(t, AgOrden(o, p)) ≡ t = 0 ∨ Ejecutando?(t, p) Ejecutando?(t, Terminar(t0 , p)) ≡ (t = t0 ⇒ ¬∅?(EnEspera(p, t))) ∧ (t 6= t0 ⇒ (Ejecutando?(t, p) ∨ Esperando?(t, t0 , p))) EnEjecucion(t, AgOrden(o, p)) ≡ if t = 0 ∧ ¬Ejecutando?(t, p) then o else EnEjecucion(t, p) fi 2 EnEjecucion(t, Terminar(t0 , p) Tareas(p) ≡ if t = t0 then DameUno(EnEspera(t, p)) else if ¬Ejecutando?(t, p) ∧ Esperando?(t, t0 , p) then EnEjecucion(t0 , p) else EnEjecucion(t, p) fi fi ≡ Tareas(Workflow(p)) Predecesoras(t, p) ≡ Predecesoras(t, Workflow(p)) ≡ ∅ OrdenesFinalizadas(Crear( )) OrdenesFinalizadas(AgOrden( , p)) ≡ OrdenesFinalizadas(p) OrdenesFinalizadas(Terminar(t, p)) ≡ if t ∈ Finales(Workflow(p)) then {EnEjecucion(t, p)} else ∅ fi ∪ OrdenesFinalizadas(p) TareasFinalizadas(o, AgOrden(o0 , p)) ≡ if o = o0 then ∅ else TareasFinalizadas(o, p) fi TareasFinalizadas(o, Terminar(t, p)) ≡ if EnEjecucion(t, p) = o then {t} else ∅ fi ∪ TareasFinalizadas(o, p) TareasEnEjecucion(o, p) ≡ ObtenerClaves(o, QuéEjecutan(Tareas(p), p)) Esperando?(t, t0 , p) ≡ Predecesores(t, p) \ TareasFinalizadas(EnEjecucion(t0 , p), p) = {t0 } QuéEjecutan(ct, p) ≡ if ∅?(ct) then vacio else if Ejecutando?(DameUno(ct)) then {hDameUno(ct), EnEjecucion(DameUno(ct), p)i} else ∅ fi ∪ QuéEjecutan(SinUno(ct), p) fi Fin TAD 3 TAD Workflow géneros workflow exporta observadores, generadores, otras operaciones igualdad observacional (∀w, w0 : workflow) w =obs Tareas(w) = Tareas(w0 ) ∧L w0 ⇐⇒ (∀t: tarea)(t ∈ Tareas(w) ⇒L 0 Predecesoras(t, w) = Predecesoras(t, w )) observadores básicos Tareas : workflow −→ conj(tarea) Predecesoras : tarea t × workflow w −→ conj(tarea) generadores Nuevo : −→ workflow AgTarea : conj(tarea) ps × workflow w −→ workflow {t ∈ Tareas(w)} {∅ ⊂ ps ⊆ Tareas(w)} otras operaciones Finales : workflow −→ conj(tarea) ... axiomas Tareas(Nuevo) Tareas(AgTarea( , w)) ≡ {0} ≡ Ag(#Tareas(w), Tareas(w)) Predecesoras( , Nuevo) ≡ ∅ Predecesoras(t, AgTarea(ps, w)) ≡ if t 6∈ Tareas(w) then ps else Predecesoras(t, w) fi Finales(Nuevo) Finales(AgTarea(ps, w)) ≡ {0} ≡ Ag(#Tareas(w), Finales(w)) \ ps Fin TAD TAD Diccionario Extendido(clave, significado) extiende Diccionario(clave, significado) otras operaciones ObtenerClaves : dicc(clave, significado) × significado −→ conj(clave) •∪• : conj(hclave, significadoi) × dicc(clave, significado) −→ dicc(clave, significado) axiomas ObtenerClaves(Vacio, s) ≡ ∅ ObtenerClaves(Definir(c, s0 , d), s) ≡ (ObtenerClaves(s, d) \ if Def?(c, d) then {c} else ∅ fi) ∪ if s0 = s then {c} else ∅ fi c ∪ d ≡ if ∅?(c) then d else Definir(π1 (DameUno(c)), π2 (DameUno(c)), SinUno(c) ∪ d) fi Fin TAD Los TADs Tarea, Orden y Recurso, con géneros tarea, orden y recurso respectivamente, son renombre de nat. 4