Introducción Depuración Algorítmica Dos técnicas Loop Expansion (nueva) Tree Compression...

Preview:

Citation preview

Loop Expansion yTree Compression

David Insa CabreraJoint work with

Josep Silva, César Tomás

IntroducciónDepuración Algorítmica

Dos técnicasLoop Expansion (nueva)Tree Compression (mejora)

DemostraciónDDJ

Conclusiones

Contenido

¿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 errorentonces la DA encontrará el error

main = 4

listSum [] = 1

1+3 = 4

2+1 = 3

listSum [1,2] = 4

listSum [2] = 3

Depuración Algorítmica

Ejemplo:

main = listSum [1,2]

listSum [] = 1listSum (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 [] = 1listSum (x:xs) = x + (listSum xs)

main = 4

listSum [] = 1

1+3 = 4

2+1 = 3

listSum [1,2] = 4

listSum [2] = 3

Depuración Algorítmica

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 [] = 0listSum (x:xs) = x + (listSum xs) + 1

main = 5

listSum [] = 0

1+3+1 = 5

2+0+1 = 3

listSum [1,2] = 5

listSum [2] = 3

Depuración Algorítmica

IntroducciónDepuración Algorítmica

Dos técnicasLoop Expansion (nueva)Tree Compression (mejora)

DemostraciónDDJ

Conclusiones

• Estrategias de la DA• Sesión de depuración

Contenido

Estrategias

Top Down - Left to RightTop Down - Heaviest FirstTop Down - More Rules FirstTop Down - Less Yes First

Divide & Query (by Shapiro)Divide & Query (by Hirunkitti)Divide by Rules & QueryDivide by Yes & Query

Single Stepping

Hat Delta - More WrongsHat Delta - Less RightsHat Delta - Best Division

Top Down

Hat Delta

Divide & Query

Single Stepping

Estrategias de la Depuración Algorítmica

Sesión de depuración

main = sqrTest [1,2]

sqrTest x = test (squares (listSum x))

test (x,y,z) = (x==y) && (y==z)

listSum [] = 0listSum (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)) 2sum2 x = div (x + (decr x)) 2

incr x = x + 1decr x = x - 1

Sesión de depuración

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) = False squares 3 = (9,9,8) listSum [1,2] = 3

squares1 3 = 9 squares2 3 = 9 squares3 3 = 8listSum [2] = 2

listSum [] = 0square 3 = 9 listSum [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 = 6 sum2 3 = 2

incr 3 = 4 decr 3 = 2

Sesión de depuración

Sesión de depuración

main = sqrTest [1,2]

sqrTest x = test (squares (listSum x))

test (x,y,z) = (x==y) && (y==z)

listSum [] = 0listSum (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)) 2sum2 x = div (x + (decr x)) 2

incr x = x + 1decr x = x - 1

Sesión de depuración

IntroducciónDepuración Algorítmica

Dos técnicasLoop Expansion (nueva)Tree Compression (mejora)

DemostraciónDDJ

Conclusiones

Contenido

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;}

Loop Expansion

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 };}

Loop Expansion

public void approx(double x, double b) { return ((x / b) + b) / 2;}

Loop Expansion

1

L

L3

L

3

1

3232

2

2…

… …

L

32

32

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ónDepuración Algorítmica

Dos técnicasLoop Expansion (nueva)Tree Compression (mejora)

DemostraciónDDJ

Conclusiones

Contenido

Tree Compression

1

1

1

2

3

2 3 3

2

4

4 5

4

2

6 6

6

Tree Compression

22

23

24

1 4

23

24

25

1 5

1 2

21

22

23

24

25

26

1 6

22

23

24

1 4 22

23

24

1 4

32 / 9 = 3,55

27 / 7 = 3,8626 / 8 = 3,25

Tree Compression

2 3 4

1

AVG1 = (AVG2 + ) * W2 + (AVG3 + ) * W3 + (AVG4 + ) * W4

AVG1 = (2) + (3) + (4) + 4

1 2 3 + 4

13/4 +1

+2 +3

= 13

(AVG2 * W2 + W2) + (AVG3 * W3 + 2W3) + (AVG4 * W4 + 3W4) + 4WI1

W1

AVG1 =

Q1 = (Q2 + W2) + (Q3 + 2W3) + (Q4 + 3W4) + 4WI1

AVG1 * W1 = (AVG2 * W2 + W2) + (AVG3 * W3 + 2W3) + (AVG4 * W4 + 3W4) + 4WI1

/ 4

Tree Compression

Q1 = (Q2 + W2) + (Q3 + 2W3) + (Q4 + 3W4) + 4WI1

Q0 = (Q1 + W1) + (Q5 + 2W5) + (Q6 + 3W6) + (Q7 + 4W7) + 5WI0

Q0 = (Q2 + Q3 + Q4) + Q5 + Q6 + Q7 + W1 + (W2 + 2W3 + 3W4 + 4WI1) + 2W5 + 3W6 + 4W7 + 5WI0

2 3 4

0

1 5 6 713/4

Tree Compression

Q0 = (Q2 + Q3 + Q4) + Q5 + Q6 + Q7 + W1 + (W2 + 2W3 + 3W4 + 4WI1) + 2W5 + 3W6 + 4W7 + 5WI0

2 3 4

0

5 6 7

Q’0 = (Q2 + W2) + (Q3 + 2W3) + (Q4 + 3W4) + (Q5 + 4W5) + (Q6 + 5W6) + (Q7 + 6W7) + 5WI0

Q’0 = Q2 + Q3 + Q4 + Q5 + Q6 + Q7 + W2 + 2W3 + 3W4 + 4W5 + 5W6 + 6W7 + 7WI0

Tree Compression

Q0 =

2 3 4

0

5 6 7

Q’0 =

2 3 4

0

1 5 6 7

Coste(nodos) = Σ{Pos(nodo, nodos) * Wnodo | nodo ∈ nodos} + |nodos| + 1

W1 + (W2 + 2W3 + 3W4 + 4WI1) + 2W5 + 3W6 + 4W7 + 5WI0

W2 + 2W3 + 3W4 + 4W5 + 5W6 + 6W7 + 7WI0

(Q2 + Q3 + Q4) + Q5 + Q6 + Q7 +

Q2 + Q3 + Q4 + Q5 + Q6 + Q7 +

Q0 = Coste(hijos0) + Coste(hijos1)

Q’0 = Coste(hijos’0)

AVG0 =

AVG’0 =

Coste(hijos0) + Coste(hijos1)W0

Coste(hijos’0)W’0

>-

Tree Compression

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)Wparent

Coste(comb)Wparent - 1

-

Coste(nodos) = Σ{Pos(nodo, nodos) * Wnodo | nodo ∈ nodos} + |nodos| + 1

1

1

1

2

3

2 3 3

2

4

4 5

4

2

6 6

6

IntroducciónDepuración Algorítmica

Dos técnicasLoop Expansion (nueva)Tree Compression (mejora)

DemostraciónDDJ

Conclusiones

Contenido

IntroducciónDepuración Algorítmica

Dos técnicasLoop Expansion (nueva)Tree Compression (mejora)

DemostraciónDDJ

Conclusiones

Contenido

L

Conclusiones

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

1

3232 32L

L

Benchmark

Nodos

LE

Tiempo Preguntas %

AE LE TCori TCopt LE TC AE LE TCori

TCop

t

LETC TC

Factoricer 55 331 51 51 5 151 105 11.62 8.50 7.35 7.35 63.25 100.0

Classifier 25 57 22 24 3 184 4 8.64 6.19 6.46 6.29 72.80 97.36

LegendGame 87 243 87 87 10 259 31 12.81 8.28 11.84 11.84 92.43 100.0

Romanic 121 171 112 113 3 191 12 16.24 7.74 10.75 9.42 58.00 87.62

FibRecursive 5378 6192 98 101 12 251 953 15.64 12.91 9.21 8.00 51.15 86.86

FactTrans 197 212 24 26 3 181 26 10.75 7.88 6.42 5.08 47.26 79.13

BinaryArrays 141 203 100 100 5 172 79 12.17 7.76 7.89 7.89 64.83 100.0

FibFactAna 178 261 44 49 7 202 33 7.90 8.29 8.50 6.06 76.71 71.29

RegresionTest 13 121 15 15 5 237 4 4.77 7.17 4.20 4.20 88.05 100.0

BoubleFibArrays

16 164 10 10 10 213 27 9.31 8.79 4.90 4.90 52.63 100.0

StatsMeanFib 19 50 23 23 6 195 21 7.79 8.12 6.78 6.48 83.18 95.58

Integral 5 8 8 8 3 152 2 6.80 5.75 7.88 5.88 86.47 74.62

TestMath 3 5 3 3 3 195 2 7.67 6.00 9.00 7.67 100.0 85.22

TestMath2 92 2493 13 13 3 211 607 14.70 11.54 15.77 12.77 86.87 80.98

Figures 2 10 10 10 24 597 13 9.00 7.20 6.60 6.60 73.33 100.0

FactCalc 128 179 75 75 3 206 46 8.45 7.60 7.96 7.96 94.20 100.0

SpaceLimits 95 133 98 100 15 786 10 36.26 12.29 18.46 14.04 38.72 76.06Average 385.59 637.24 46.65 47.53 7.06 257.80 116.18 11.80 8.35 8.82 7.79 72.35 90.28

Loop Expansion yTree Compression

David Insa CabreraThe Declarative Debugger for Java (DDJ)

http://www.dsic.upv.es/~jsilva/DDJ/

Recommended