Enhancing Tree Compression in Declarative Debugging
This document discusses enhancements in tree compression techniques utilized in algorithmic debugging. It covers the process of generating and traversing execution trees to identify bugs, defines what an execution tree is, and explains essential strategies such as the "Golden Rule" for identifying buggy nodes. The text presents two phases for efficient debugging and offers detailed examples of a debugging session. Furthermore, it delves into tree compression measures to optimize question generation for effective debugging.
Enhancing Tree Compression in Declarative Debugging
E N D
Presentation Transcript
EnhancingTreeCompression in DeclarativeDebugging David Insa Josep Silva César Tomás
I didX I wantedY Instead I gotZ
AlgorithmicDebugging • TWO PHASES: • Generatetheexecutiontree • Traversetheexecutiontreeaskingquestionsuntilthe bug isfound If a symptom of an error isdetected then AD willfindthe bug main = 4 WhatisanExecutionTree? listSum [1,2] = 4 Example: main = listSum [1,2] listSum [] = 1 listSum (x:xs) = x + (listSumxs) 1+3 = 4 listSum [2] = 3 2+1 = 3 listSum [] = 1
AlgorithmicDebugging • Traversingtheexecutiontree • GOLDEN RULE:When a wrongnode has notanywrongchildrenthen • thisnodeis a buggynode. main = 4 listSum [1,2] = 4 Example: main = listSum [1,2] listSum [] = 1 listSum (x:xs) = x + (listSumxs) 1+3 = 4 listSum [2] = 3 2+1 = 3 listSum [] = 1
AlgorithmicDebugging • Traversingtheexecutiontree • GOLDEN RULE:When a wrongnode has notanywrongchildrenthen • thisnodeis a buggynode. main = 5 listSum [1,2] = 5 Example: main = listSum [1,2] listSum [] = 0 listSum (x:xs) = x + (listSumxs) + 1 1+3+1 = 5 listSum [2] = 3 2+0+1 = 3 listSum [] = 0
Debuggingsession Debuggingsession main = sqrTest[1,2] sqrTestx = test (squares (listSumx)) test (x,y,z) = (x==y) && (y==z) listSum[] = 0 listSum(x:xs) = x + (listSumxs) 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(partialSumsx) partialSumsx = [(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
Debuggingsession DebuggingsessionusingDivide & Query(byHirunkitti). main = False Startingthedebuggingsession… square2 3 = 9? YES square3 3 = 8? NO partialSums 3 = [6,2]? NO sum1 3 = 6? YES sum2 3 = 2? NO decr 3 = 2? YES Bug found in rule: sum2 x = div (x + (decr x)) 2 sqrTest [1,2] = False test (9,9,8) = False squares 3 = (9,9,8) listSum [1,2] = 3 listSum [2] = 2 squares1 3 = 9 squares2 3 = 9 squares3 3 = 8 listSum [] = 0 square 3 = 9 listSum [3,3,3] = 9 list 3 3 = [3,3,3] partialSums 3 = [6,2] listSum [6,2] = 8 listSum [3,3] = 6 list 3 2 = [3,3] listSum [2] = 2 sum1 3 = 6 sum2 3 = 2 decr 3 = 2 listSum [3] = 3 list 3 1 = [3] listSum [] = 0 incr 3 = 4 listSum [] = 0 list 3 0 = []
Debuggingsession Debuggingsession main = sqrTest[1,2] sqrTestx = test (squares (listSumx)) test (x,y,z) = (x==y) && (y==z) listSum[] = 0 listSum(x:xs) = x + (listSumxs) 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(partialSumsx) partialSumsx = [(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
DeclarativeDebuggingStrategies Single Stepping Single Stepping Divide & Query Top Down 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 Hat Delta Hat Delta - More Wrongs Hat Delta - Less Rights Hat Delta - Best Division
AlgorithmicDebugging Isitpossibletooptimizean ET beforestartingthequestiongeneration? Yes, withTreeCompression
1 1 1 1 1 1 1 1 2 1 2 2 1 1 1 1 2 AlgorithmicDebugging • TREE COMPRESSION • Howmanyquestions do youneedtofind a bug in theseETs? • Whatstrategy are youusing? 1
AlgorithmicDebugging • TREE COMPRESSION • ET transformation that can be done before exploring the ET. • It compresses all chains of nodes that represent recursive calls. • Given two nodes A,B where A recursivelly calls B, • Tree compression deletes node B and makes all children of B to be new children of A.
TreeCompression 1 1 2 6 1 2 4 6 6 2 2 3 3 4 5 3 4
TreeCompression 32 / 9 = 3,55 1 2 1 1 4 5 2 2 2 2 2 2 3 4 5 2 3 4 26 / 8 = 3,25 27 / 7 = 3,86 1 4 1 6 1 2 2 2 4 2 2 2 2 3 4 2 2 2 4 5 6 1 2 3 2 2 2 2 3 4
TreeCompression A metrictomeasuretheimpact of ET transformations: 13/4 17/5 1 1 < 2 2 3 4 3 4 4 AVG = Total Questions (Q) / Number of Nodes (W) Q = 4 + 2 + 3 + 4 = 13 W = 4 AVG = Q/W = 13/4
TreeCompression Generalizationforany ET: +1 1 +3 +2 2 3 4 … … … + 4 3 2 Q = (AVG2 + ) * W2+ (AVG3 + ) * W3 + (AVG4 + ) * W4 1 (AVG2 * W2 + W2) + (AVG3 * W3 + 2W3) + (AVG4 * W4 + 3W4) + 4 AVG1 = W1 AVG1 * W1 = (AVG2 * W2 + W2) + (AVG3 * W3 + 2W3) + (AVG4 * W4 + 3W4) + 4 Q1 = (Q2 + W2) + (Q3 + 2W3) + (Q4 + 3W4) + 4
TreeCompression Generalizationforany ET: 0 6 1 5 7 2 3 4 Q1 = (Q2 + W2) + (Q3 + 2W3) + (Q4 + 3W4) + 4 Q0 = (Q1 + W1) + (Q5 + 2W5) + (Q6 + 3W6) + (Q7+ 4W7) + 5 Q0 = (Q2 + Q3 + Q4) + Q5+ Q6 + Q7 + W1 + (W2 + 2W3 + 3W4 + 4WI1) + 2W5 + 3W6 + 4W7 + 5
TreeCompression Generalizationforany ET: 0 2 6 5 3 4 7 Q0 = (Q2 + Q3 + Q4) + Q5+ Q6 + Q7 + W1 + (W2 + 2W3 + 3W4 + 4WI1) + 2W5 + 3W6 + 4W7 + 5 Q’0 = (Q2 + W2) + (Q3 + 2W3) + (Q4 + 3W4) + (Q5+ 4W5) + (Q6 + 5W6) + (Q7 + 6W7) + 5 Q’0 = Q2 + Q3 + Q4 + Q5+ Q6 + Q7 + W2 + 2W3 + 3W4 + 4W5 + 5W6 + 6W7 + 7
TreeCompression Generalizationforany ET: 0 0 6 1 5 7 2 6 5 3 4 7 2 3 4 (Q2 + Q3 + Q4) + Q5 + Q6 + Q7 + Q0 = W1 + (W2 + 2W3 + 3W4 + 4WI1) + 2W5 + 3W6 + 4W7 + 5 Q2 + Q3 + Q4 + Q5 + Q6 + Q7 + Q’0 = Cost(nodes) = Σ{Pos(node, nodes) * Wnodo | node∈nodes} + |nodes| + 1 W2 + 2W3 + 3W4 + 4W5 + 5W6 + 6W7 + 7WI0 Cost(children0) + Cost(children1) Q0 = Cost(children0) + Cost(children1) AVG0 = - W0 > Cost(children’0) Q’0 = Cost(children’0) AVG’0 = W’0
TreeCompression recs = {n | n,n’ ∈ N ∧ (n → n’) ∈ E } ∧ l(n) = l(n’)} while (recs≠ ∅) taken ∈ recssuchthat ∃/ n’ ∈ recswith (n → n’) ∈ E+ recs = recs \ {n} parent = n do maxImpr = 0 children = {c | (n → c) ∈ E ∧ l(n) = l(c)} foreachchild∈ children pchildren = Sort(Children(parent)) cchildren = Sort(Children(child)) comb = Sort((pchildren ∪ cchildren) \ {child}) impr = if (impr > maxImpr) maxImpr = impr bestNode = child endforeach if (maxImpr ≠ 0) T’ = Compress(T’, parent, bestNode) while (maxImpr ≠ 0) endwhile 1 1 2 6 1 2 4 6 6 2 2 3 3 4 5 Cost(comb) Cost(pchildren) + Cost(cchildren) - Wparent - 1 Wparent 3 4 Coste(nodos) = Σ{Pos(nodo, nodos) * Wnodo | nodo ∈ nodos} + |nodos| + 1
Experiments Questionsreductionwiththe new algorithm9.72%
Future Work Reduce the number of questions EXPANDING the structure of the ET Applicable to iterative loops: loop expansion Reduce the granularity level of bugs (from functions to loops) Combine treecompression and loopexpansion L 1 2 3 2 3 2 3 L L