Introducción Depuración Algorítmica Dos técnicas Loop Expansion (nueva) Tree Compression (mejora) Demostración DDJ Conclusiones
¿Qué es un Árbol de Ejecución? Depuración algorítmica [Shapiro (1982)] Paradigma Lógico DOS FASES: Generar el árbol de ejecución Recorrer el árbol de ejecución haciendo preguntas hasta encontrar el error Si se detecta el efecto de un error entonces la DA encontrará el error main = 4 listSum [] = = = 3 listSum [1,2] = 4 listSum [2] = 3 Ejemplo: main = listSum [1,2] listSum [] = 1 listSum (x:xs) = x + (listSum xs)
Recorriendo el árbol de ejecución REGLA DE ORO: Cuando un nodo incorrecto no tiene hijos incorrectos, entonces este nodo es erróneo. Ejemplo: main = listSum [1,2] listSum [] = 1 listSum (x:xs) = x + (listSum xs) main = 4 listSum [] = = = 3 listSum [1,2] = 4 listSum [2] = 3
Recorriendo el árbol de ejecución REGLA DE ORO: Cuando un nodo incorrecto no tiene hijos incorrectos, entonces este nodo es erróneo. Ejemplo: main = listSum [1,2] listSum [] = 0 listSum (x:xs) = x + (listSum xs) + 1 main = 5 listSum [] = = = 3 listSum [1,2] = 5 listSum [2] = 3
(1) do (2) node = selectNode(T) (3) answer = askNode(node) (4) if (answer = NO) (5) then M(node) = Wrong (6) buggyNode = node (7) N = {n ∈ N | (node n) ∈ E*} (8) else N = N \ {n ∈ N | (node n) ∈ E*} (9) while ( ∃ n ∈ N, M(n) = Undefined) (10) return buggyNode
Introducción Depuración Algorítmica Dos técnicas Loop Expansion (nueva) Tree Compression (mejora) Demostración DDJ Conclusiones Estrategias de la DA Sesión de depuración
Estrategias Top Down - Left to Right Top Down - Heaviest First Top Down - More Rules First Top Down - Less Yes First Divide & Query (by Shapiro) Divide & Query (by Hirunkitti) Divide by Rules & Query Divide by Yes & Query Single Stepping Hat Delta - More Wrongs Hat Delta - Less Rights Hat Delta - Best Division Top Down Hat Delta Divide & Query Single Stepping
Sesión de depuración main = sqrTest [1,2] sqrTest x = test (squares (listSum x)) test (x,y,z) = (x==y) && (y==z) listSum [] = 0 listSum (x:xs) = x + (listSum xs) squares x = ((square1 x),(square2 x),(square3 x)) square1 x = square x square x = x*x square2 x = listSum (list x x) list x y | y==0 = [] | otherwise = x:list x (y-1) square3 x = listSum (partialSums x) partialSums x = [(sum1 x),(sum2 x)] sum1 x = div (x * (incr x)) 2 sum2 x = div (x + (decr x)) 2 incr x = x + 1 decr x = x - 1
Empezando la sesión de depuración… 1)main = False? NO 2)sqrTest [1,2] = False? NO 3)test [9,9,8] = False? SI 4)squares 3 = [9,9,8]? NO 5)square1 3 = 9? SI 6)square2 3 = 9? SI 7)square3 3 = 8? NO 8)listSum [6,2] = 8? SI 9)partialSums 3 = [6,2]? NO 10) sum1 3 = 6? SI 11) sum2 3 = 2? NO 12) decr 3 = 2? SI Error encontrado en la regla: sum2 x = div (x + (decr x)) 2 Sesión de depuración con la búsqueda Top-Down – Left to Right. main = False sqrTest [1,2] = False test (9,9,8) = Falsesquares 3 = (9,9,8)listSum [1,2] = 3 squares1 3 = 9squares2 3 = 9squares3 3 = 8 listSum [2] = 2 listSum [] = 0 square 3 = 9listSum [3,3,3] = 9 listSum [3,3] = 6 listSum [3] = 3 listSum [] = 0 list 3 3 = [3,3,3] list 3 2 = [3,3] list 3 1 = [3] list 3 0 = [] listSum [6,2] = 8 listSum [2] = 2 listSum [] = 0 partialSums 3 = [6,2] sum1 3 = 6sum2 3 = 2 incr 3 = 4 decr 3 = 2
Empezando la sesión de depuración… 1)main = False? NO 2)sqrTest [1,2] = False? NO 3)squares 3 = [9,9,8]? NO 4)square2 3 = 9? SI 5)square3 3 = 8? NO 6)partialSums 3 = [6,2]? NO 7) sum1 3 = 6? SI 8) sum2 3 = 2? NO 9) decr 3 = 2? SI Error encontrado en la regla: sum2 x = div (x + (decr x)) 2 Sesión de depuración con la búsqueda Top-Down – Heaviest First. main = False sqrTest [1,2] = False test (9,9,8) = Falsesquares 3 = (9,9,8)listSum [1,2] = 3 squares1 3 = 9squares2 3 = 9squares3 3 = 8 listSum [2] = 2 listSum [] = 0 square 3 = 9listSum [3,3,3] = 9 listSum [3,3] = 6 listSum [3] = 3 listSum [] = 0 list 3 3 = [3,3,3] list 3 2 = [3,3] list 3 1 = [3] list 3 0 = [] listSum [6,2] = 8 listSum [2] = 2 listSum [] = 0 partialSums 3 = [6,2] sum1 3 = 6sum2 3 = 2 incr 3 = 4 decr 3 = 2
Empezando la sesión de depuración… 1)square2 3 = 9? SI 2)square3 3 = 8? NO 3)partialSums 3 = [6,2]? NO 4)sum1 3 = 6? SI 5) sum2 3 = 2? NO 6) decr 3 = 2? SI Error encontrado en la regla: sum2 x = div (x + (decr x)) 2 Sesión de depuración con la búsqueda Divide & Query (by Hirunkitti). main = False sqrTest [1,2] = False test (9,9,8) = Falsesquares 3 = (9,9,8)listSum [1,2] = 3 squares1 3 = 9squares2 3 = 9squares3 3 = 8 listSum [2] = 2 listSum [] = 0 square 3 = 9listSum [3,3,3] = 9 listSum [3,3] = 6 listSum [3] = 3 listSum [] = 0 list 3 3 = [3,3,3] list 3 2 = [3,3] list 3 1 = [3] list 3 0 = [] listSum [6,2] = 8 listSum [2] = 2 listSum [] = 0 partialSums 3 = [6,2] sum1 3 = 6sum2 3 = 2 incr 3 = 4 decr 3 = 2
Sesión de depuración main = sqrTest [1,2] sqrTest x = test (squares (listSum x)) test (x,y,z) = (x==y) && (y==z) listSum [] = 0 listSum (x:xs) = x + (listSum xs) squares x = ((square1 x),(square2 x),(square3 x)) square1 x = square x square x = x*x square2 x = listSum (list x x) list x y | y==0 = [] | otherwise = x:list x (y-1) square3 x = listSum (partialSums x) partialSums x = [(sum1 x),(sum2 x)] sum1 x = div (x * (incr x)) 2 sum2 x = div (x + (decr x)) 2 incr x = x + 1 decr x = x - 1
Introducción Depuración Algorítmica Dos técnicas Loop Expansion (nueva) Tree Compression (mejora) Demostración DDJ Conclusiones
public void sqrt(double x) { if (x < 0) return Double.NaN; double b = x; while (Math.abs(b * b - x) > 1e-12) b = ((x / b) + b) / 2; return b; }
public void sqrt(double x) { if (x < 0) return Double.NaN; double b = x; while (Math.abs(b * b - x) > 1e-12) b = approx(x, b); return b; } public void sqrt(double x) { if (x < 0) return Double.NaN; double b = x; { if (Math.abs(b * b - x) > 1e-12) { Object[] result = this.sqrt_loop(x, b); x = (Double) result[0]; b = (Double) result[1]; } return b; } private Object[] sqrt_loop(double x, double b) { b = approx(x, b); if (Math.abs(b * b - x) > 1e-12) return this.sqrt_loop(x, b); return new Object[] { x, b }; } public void approx(double x, double b) { return ((x / b) + b) / 2; }
1 L L3 L … …… L public void sqrt(double x) { if (x < 0) return Double.NaN; double b = x; while (Math.abs(b * b - x) > 1e-12) b = approx(x, b); return b; }
Introducción Depuración Algorítmica Dos técnicas Loop Expansion (nueva) Tree Compression (mejora) Demostración DDJ Conclusiones
/ 9 = 3,55 27 / 7 = 3,86 26 / 8 = 3,25
AVG 1 = (AVG 2 + ) * W 2 + (AVG 3 + ) * W 3 + (AVG 4 + ) * W 4 AVG 1 = (2) + (3) + (4) / = 13 (AVG 2 * W 2 + W 2 ) + (AVG 3 * W 3 + 2W 3 ) + (AVG 4 * W 4 + 3W 4 ) + 4WI 1 W1W1 AVG 1 = Q 1 = (Q 2 + W 2 ) + (Q 3 + 2W 3 ) + (Q 4 + 3W 4 ) + 4WI 1 AVG 1 * W 1 = (AVG 2 * W 2 + W 2 ) + (AVG 3 * W 3 + 2W 3 ) + (AVG 4 * W 4 + 3W 4 ) + 4WI 1 / 4
Q 1 = (Q 2 + W 2 ) + (Q 3 + 2W 3 ) + (Q 4 + 3W 4 ) + 4WI 1 Q 0 = (Q 1 + W 1 ) + (Q 5 + 2W 5 ) + (Q 6 + 3W 6 ) + (Q 7 + 4W 7 ) + 5WI 0 Q 0 = (Q 2 + Q 3 + Q 4 ) + Q 5 + Q 6 + Q 7 + W 1 + (W 2 + 2W 3 + 3W 4 + 4WI 1 ) + 2W 5 + 3W 6 + 4W 7 + 5WI /4
Q 0 = (Q 2 + Q 3 + Q 4 ) + Q 5 + Q 6 + Q 7 + W 1 + (W 2 + 2W 3 + 3W 4 + 4WI 1 ) + 2W 5 + 3W 6 + 4W 7 + 5WI Q’ 0 = (Q 2 + W 2 ) + (Q 3 + 2W 3 ) + (Q 4 + 3W 4 ) + (Q 5 + 4W 5 ) + (Q 6 + 5W 6 ) + (Q 7 + 6W 7 ) + 5WI 0 Q’ 0 = Q 2 + Q 3 + Q 4 + Q 5 + Q 6 + Q 7 + W 2 + 2W 3 + 3W 4 + 4W 5 + 5W 6 + 6W 7 + 7WI 0
Q 0 = Q’ 0 = Coste(nodos) = Σ{Pos(nodo, nodos) * W nodo | nodo ∈ nodos} + |nodos| + 1 W 1 + (W 2 + 2W 3 + 3W 4 + 4WI 1 ) + 2W 5 + 3W 6 + 4W 7 + 5WI 0 W 2 + 2W 3 + 3W 4 + 4W 5 + 5W 6 + 6W 7 + 7WI 0 (Q 2 + Q 3 + Q 4 ) + Q 5 + Q 6 + Q 7 + Q 2 + Q 3 + Q 4 + Q 5 + Q 6 + Q 7 + Q 0 = Coste(hijos 0 ) + Coste(hijos 1 ) Q’ 0 = Coste(hijos’ 0 ) AVG 0 = AVG’ 0 = Coste(hijos 0 ) + Coste(hijos 1 ) W0W0 Coste(hijos’ 0 ) W’ 0 > -
Q 0 = Q’ 0 = Coste(nodos) = Σ{Pos(nodo, nodos) * W nodo | nodo ∈ nodos} + |nodos| + 1 W 1 + (W 2 + 2W 3 + 3W 4 + 4WI 1 ) + 2W 5 + 3W 6 + 4W 7 + 5WI 0 W 2 + 2W 3 + 3W 4 + 4W 5 + 5W 6 + 6W 7 + 7WI 0 (Q 2 + Q 3 + Q 4 ) + Q 5 + Q 6 + Q 7 + Q 2 + Q 3 + Q 4 + Q 5 + Q 6 + Q 7 + Q 0 = Coste(hijos 0 ) + Coste(hijos 1 ) + K Q’ 0 = Coste(hijos’ 0 ) + K AVG 0 = AVG’ 0 = Coste(hijos 0 ) + Coste(hijos 1 ) W0W0 Coste(hijos’ 0 ) W’ 0 K = Q 2 + Q 3 + Q 4 + Q 5 + Q 6 + Q 7 K W0W0 K W’ Coste(hijos 0 ) + Coste(hijos 1 ) W0W0 Coste(hijos’ 0 ) W’ 0 K W 0 * W’ 0 + >
AVG 0 = (AVG 1 + 1)W 1 + (AVG 5 + 2)W 5 + (AVG 6 + 3)W W0W0 AVG 1 = (AVG 2 + 1)W 2 + (AVG 3 + 2)W 3 + (AVG 4 + 3)W W1W1 AVG 0’ = (AVG 2 + 1)W 2 + (AVG 3 + 2)W 3 + (AVG 4 + 3)W 4 + (AVG 5 + 4)W 5 + (AVG 6 + 5)W W ¿AVG 0 > AVG 0’ ? = 2W 2 + 3W 3 + 4W W1W1 = 13 4
recs = {n | n,n’ ∈ N ∧ (n → n’) ∈ E } ∧ l(n) = l(n’)} (1) while (recs ≠ ∅ ) (2) take n ∈ recs such that ∃ / n’ ∈ recs with (n → n’) ∈ E + (3) recs = recs \ {n} (4) parent = n (5) do (6) maxImpr = 0 (7) children = {c | (n → c) ∈ E ∧ l(n) = l(c)} (8) for each child ∈ children (9) pchildren = Sort(Children(parent)) (10) cchildren = Sort(Children(child)) (11) comb = Sort((pchildren ∪ cchildren) \ {child}) (12) impr = (13) if (impr > maxImpr) (14) maxImpr = impr (15) bestNode = child (16) end for each (17) if (maxImpr ≠ 0) (18) T’ = Compress(T’, parent, bestNode) (19) while (maxImpr ≠ 0) (20) end while Coste(pchildren) + Coste(cchildren) W parent Coste(comb) W parent Coste(nodos) = Σ{Pos(nodo, nodos) * W nodo | nodo ∈ nodos} + |nodos|
Introducción Depuración Algorítmica Dos técnicas Loop Expansion (nueva) Tree Compression (mejora) Demostración DDJ Conclusiones
Introducción Depuración Algorítmica Dos técnicas Loop Expansion (nueva) Tree Compression (mejora) Demostración DDJ Conclusiones
L Reducir el número de preguntas mejorando la estructura del AE Permitir bajar el nivel de granularidad de métodos a bucles Combinar ambas técnicas L L Benchmark Nodos LE TiempoPreguntas% AELE TC ori TC opt LE TC AELE TC ori TC op t LETCTC Factoricer Classifier LegendGame Romanic FibRecursive FactTrans BinaryArrays FibFactAna RegresionTest BoubleFibArrays StatsMeanFib Integral TestMath TestMath Figures FactCalc SpaceLimits Average