Sven Köhler 1 Bertram Ludäscher 1,3 Yannis Smaragdakis 2,3 1 University of California, Davis 2 University of Athens, Greece 3 LogicBlox Inc., Atlanta, USA UC DAVIS Department of Computer Science Datalog2.0, Vienna Logic Weeks
Outline Motivation ¤ Debugging and Profiling Declarative Rules Basic Idea ¤ Capture derivations (provenance) in an enriched model M’ ¤ … then run Datalog queries on M’ (when in Rome, … ) Simple “Tricks” for Mere Mortals ¤ F : record rule firings ( T P instances) ¤ G : reify firings as nodes in a firing graph ¤ S : keep track of firing stages ( Statelog ) ¤ Query the enriched model (provenance graph)! Debugging and Profiling Examples Musings & Conclusions ¤ Graph-based Provenance Analyzer ( GPad/DLV, GPad/LB)
Declarative Debugging Resurgence/Renaissance of Datalog … ¤ … and Declarative Programming e.g., parallel programming beyond MapReduce ¤ … an old dream: Executable Specifications! But writing large declarative programs is still tricky ¤ 9-valued logics anyone? (cf. Kunen’s PhD effect) ¤ How can we empower “regular” Datalog programmers ( mere mortals )? Simple tools & techniques for debugging (and profiling) Ideally: ¤ Don’t tie the approach to a particular computation model ¤ Instead devise a declarative debugging approach should work for different implementations
Running Example
Pop Quiz: Why/how come tc(a,b) ? Why/how is (a,b) in the transitive closure tc of e ? What about ?-tc(e,X) vs ?-tc(X,e)
Declarative Debugging: Prolog
Declarative Debugging: Prolog
Hmm.. Many answers …
(Infinitely) ?-tc(a,b) Many branches :-e(a,_G263), :-e(a,b) tc(_G263,b) saying “Yes” :-true :-tc(b,b) Different ways :-e(b,_G347), Answer: :-e(b,b) tc(a,b) tc(_G347,b) to say “No”! :-tc(c,b) :-e(c,_G431), :-e(c,b) tc(_G431,b) finitely failed tree :-true :-tc(b,b) :-tc(d,b) :-e(b,_G515), :-e(d,_G515), Answer: :-e(b,b) :-e(d,b) tc(a,b) tc(_G515,b) tc(_G515,b) :-tc(c,b) :-e(c,_G599), :-e(c,b) tc(_G599,b) :-true :-tc(b,b) :-tc(d,b) Answer: :-e(b,_G683), :-e(d,_G683), :-e(b,b) :-e(d,b) tc(a,b) tc(_G683,b) tc(_G683,b) :-tc(c,b) :-e(c,_G767), :-e(c,b) tc(_G767,b) infinitely failed :-true :-tc(b,b) :-tc(d,b) tree Answer: :-e(b,_G851), :-e(d,_G851), :-e(b,b) :-e(d,b) tc(a,b) tc(_G851,b) tc(_G851,b)
Declarative Debugging: DATALOG
Debug this! Evaluating P on I yields model M P ( I ) Too much information! Not enough information!
Declarative Debugging: DATALOG Scope of this paper: ¤ positive Datalog programs (recursion OK, negation: not yet) ¤ Why/How provenance (but no Why-Not provenance… yet)
Some Debugging and Profiling Use Cases
Solving the Provenance Quiz Example : Datalog program P = { [r 1 ] ¡ ¡ ¡tc(X,Y) ¡:-‑ ¡e(X,Y). ¡ ¡tc(X,Y) ¡:-‑ ¡e(X,Z), ¡tc(Z,Y). ¡ } [r 2 ] ¡ ¡ EDB instance I = { ¡ ¡ e(a,b). ¡e(b,c). ¡e(c,b). ¡e(c,d). ¡ } ¡ Question : How can we justify / explain … ¤ Why ( how ) is tc(a,b) ¡ in M P ( I )? ¡
[r1] tc(X,Y) :- e(X,Y) [r2] tc(X,Y) :- e(X,Z), tc(Z,Y)
DATALOG Rewritings (GPAD) Firing graph : captures the “full” provenance • reasonable overhead!? • has been/is being used (e.g. Orchestra, LogicBlox) • can be easily constructed! • Provenance-enabled Debugging and Profiling for the rest of us! •
Step 1: Capturing Rule Firings (“ F -trick”) Capture rule firings and keep “witness info” (existential variables) ¤ no premature projections in the rule head please! Example . Instead of a given rule … ¡ ¡tc(X,Y) ¡:-‑ ¡e(X,Z), ¡tc(Z,Y) . ¡ ¡ … we rather use these two rules, keeping witnesses Z around: ¡ ¡ ¡fire2 (X,Z,Y) ¡:-‑ ¡e ( X,Z), ¡tc(Z,Y). ¡ ¡tc(X,Y) ¡ ¡ ¡ ¡ ¡ ¡:-‑ ¡ fire2 (X,Z,Y). ¡ ¡ ��� ���������� ��� ������ ��� ������� ��� ������������ ��� ������� Example rule firings
Step 2: Graph Transformation (“ G -trick”) Reify provenance atoms & firings in a labeled graph g /3 Example for N = 2 subgoals and 1 head atom … ¡ ¡ fire2 (X,Z,Y) ¡:-‑ ¡e(X,Z), ¡tc(Z,Y). ¡% ¡two ¡ in -‑edges ¡ tc(X,Y) ¡ ¡ ¡ ¡ ¡ ¡:-‑ ¡ fire2 (X,Z,Y). ¡ ¡ ¡ ¡% ¡one ¡ out -‑edge ¡ ¡ … generates N +1 “reification rules” (Skolems are safe): ¡ ¡ g ( ¡e(X,Z), ¡ ¡ ¡ ¡ ¡ ¡ ¡ in , ¡ ¡sk fire2 (X,Z,Y) ¡) ¡:-‑ ¡fire2(X,Z,Y). ¡ g ( ¡tc(Z,Y), ¡ ¡ ¡ ¡ ¡ ¡ in , ¡ ¡sk fire2 (X,Z,Y) ¡) ¡:-‑ ¡fire2(X,Z,Y). ¡ ¡ g ( ¡ sk fire2 (X,Z,Y), ¡ out , ¡tc(X,Y) ¡) ¡ ¡ ¡ ¡ ¡ ¡:-‑ ¡fire2(X,Z,Y). ¡ e(a,b) in out fire2(a,b,d) tc(a,d) in tc(b,d) Example instance generated by these rules
Step 3: Using Statelog (“ S -Trick”) Use Statelog to keep record of firing rounds: ¤ Add state (=stage) argument to provenance rules and graph relations ¤ EDB facts are derived in state 0. ¤ Subsequently: extract earliest round for firings and IDB facts Example : r in : fire r ( S1 , X) :- B 1 ( S , X 1 ), … , B n ( S , X n ), next( S , S1 ). r out : H( S , Y) :- fire r ( S , X). e(a,b) r1 [1] tc(a,b) [1] e(b,c) r2 [3] tc(b,b) r2 [2] [2] r1 [1] tc(c,b) e(c,b) [1] r2 [3]
How long (does it take) Provenance! These definitions are recursive but well-founded The numbers can be easily obtained via Statelog
More Provenance Querying Provenance Views: ¤ Provenance subgraph relevant for debug atom Q: ¡ ProvView(Q,X, ¡out, ¡Q) ¡:-‑ ¡g(_,X,out,Q). ¡ ProvView(Q,X, ¡L, ¡ ¡ ¡Y) ¡:-‑ ¡ProvView(Q,Y,_,_), ¡g(_,X,L,Y). ¡ ¡ Length of derivations : ¤ first round this firing occurred ¡ len(F,LenF) ¡:-‑ ¡ newFiring ( S ,F), ¡LenF= S . ¡ ¡ Length of an atom : ¤ first round it was derived: ¡ len(A,LenA) ¡:-‑ ¡ newAtom ( S ,A), ¡LenA= S . ¡
Declarative Profiling P rr : tc(X,Y) :- e(X,Y). tc(X,Y) :- e(X,Z), tc (Z,Y). P dr : tc(X,Y) :- e(X,Y). tc(X,Y) :- tc (X,Z), tc (Z,Y).
Declarative Profiling Number of Facts : tc(a,d) ¡ [3] tc(b,d) 3 [2] derived(H) ¡:-‑ ¡ tc(a,b) tc(c,d) 1 [1] 2 e(a,b) ¡ ¡g(_,out, ¡H). ¡ 1 [1] e(c,d) tc(b,c) tc(a,c) e(b,c) 1 2 [1] [2] tc(d,e) tc(c,e) e(d,e) 1 2 derivedHeadCount(C) ¡:-‑ ¡ ¡ 3 [1] tc(b,e) tc(a,e) [2] 4 [3] [4] ¡ ¡C ¡= ¡ count { ¡ (a) right-recursive ¡ ¡ ¡ ¡H ¡: ¡derived(H) ¡ ¡ ¡}. ¡ tc(a,b) e(a,b) 1 [1] Number of Firings : 3 tc(a,c) 2 [2] 4 ¡ tc(a,d) [3] tc(b,c) 3 e(b,c) 1 firing(F) ¡:-‑ ¡g(_,F,out,_). ¡ [1] ¡ tc(b,d) tc(a,e) 2 3 [2] [3] firingCount(C) ¡:-‑ ¡ ¡ tc(c,d) e(c,d) 1 3 [1] tc(b,e) ¡C ¡= ¡ count {F ¡: ¡firing(F)}. ¡ [3] 3 tc(c,e) 2 [2] 4 tc(d,e) e(d,e) 1 [1] (b) doubly-recursive
Declarative Profiling Number of Rederivations: Schema-Level Profiling : ¡ ¤ Number of new facts per relation reDerivation(S,F) ¡:-‑ ¡ ¡ used in each round to derive new ¡ ¡g(S,F,out,A), ¡ ¡ facts ¡ ¡len(A,LenA), ¡ LenA ¡< ¡S . ¡ ¡ ¡ factInRound(S,R,A) ¡:-‑ ¡ ¡ reDerivCount(S,C) ¡:-‑ ¡ ¡ ¡g(S, ¡A, ¡in, ¡_), ¡ ¡ ¡C ¡= ¡ count { ¡ ¡ ¡relName(A,R). ¡ ¡ ¡ ¡ ¡F ¡: ¡reDerivation(S,F) ¡ ¡ ¡ ¡ ¡}. ¡ factInRound(S1,R,A) ¡:-‑ ¡ ¡ ¡ ¡ ¡g(S,_, ¡out, ¡A), ¡ ¡ ¡ ¡next(S,S1), ¡ ¡ reDerivTotal(T) ¡:-‑ ¡ ¡ ¡ ¡relName(A,R). ¡ ¡ ¡T ¡= ¡ sum { ¡ ¡ ¡ ¡ ¡ ¡C ¡: ¡reDerivCount(S,C) ¡ newFact(S,R,A) ¡:-‑ ¡ ¡ ¡ ¡}. ¡ ¡ ¡g(S,_,out,A), ¡ ¡ ¡ ¡ ¡ not ¡factsInRound(S,R,A), ¡ ¡ ¡relName(A,R). ¡ ¡ newFactsCount(S,R,C) ¡:-‑ ¡ ¡ ¡ ¡C ¡= ¡ count { ¡ ¡ ¡ ¡ ¡ ¡A ¡: ¡newFact(S,R,A) ¡ ¡ ¡}. ¡
Profiling Example: Transitive Closure Right Recursive Double Recursive 45 facts 45 facts 45 rule firings 129 rule firings 10 rounds 6 rounds 285 rederivations 325 rederivations [Related factoid: a chain of length N has exactly one derivation in the right-recursive program but Catalan-number ( N ) many derivations in the doubly-recursive program!]
Real-‑World ¡Profiling ¡Example ¡ Provenance-‑based ¡profiling ¡can ¡explain ¡real-‑world ¡ behavior ¡ E.g., ¡realis<c ¡graph, ¡~1700 ¡nodes ¡~4000 ¡edges: ¡ ¤ doubly ¡recursive ¡trans. ¡closure ¡>64M ¡rule ¡firings ¡ ¤ right-‑recursive ¡trans.closure ¡~560K ¡rule ¡firings ¡ ¤ explains ¡execu<on ¡<me ¡difference: ¡>15sec ¡vs. ¡2.5sec ¡
Recommend
More recommend