Strategies For Making Friends

925 views

Published on

Published in: Technology, Education
  • Be the first to comment

  • Be the first to like this

Strategies For Making Friends

  1. 1. Adaptive Programming (AP): Strategies for making friends Karl Lieberherr Northeastern University, Boston Demeter Research Group faculty: Lorenz, Mezini, Patt-Shamir, Palsberg, Wand
  2. 2. Overview <ul><li>What is AP? Where does it come from? </li></ul><ul><li>Law of Demeter (talk only to your friends) and how to follow it adaptively. </li></ul><ul><li>Traversal strategies and how they create friends </li></ul><ul><li>Compiling adaptive programs </li></ul><ul><li>Evolutionary use of AP with current lang. </li></ul><ul><li>Connections to polytypic programming </li></ul>
  3. 3. Connection to Components <ul><li>Mira Mezini’s talk on APPC </li></ul><ul><li>An evolutionary use of AP: AP as a solution to component composition problems </li></ul><ul><li>AP ideas useful to working with components with and without tool support: this is practical stuff </li></ul>
  4. 4. What is AP? Some two-line phrases <ul><li>Structure-shy or schema-shy programming </li></ul><ul><li>Programming with “regular expressions” over graphs </li></ul><ul><li>Programming with traversal strategies </li></ul><ul><li>Succinct traversal-visitor-style programming </li></ul><ul><li>Programming in terms of graph constraints on data types, not data types themselves </li></ul>
  5. 5. What is AP? Special case of AOP ordinary program structure-shy functionality structure navigation adaptive program Class dictionary/ graph Traversal strategies Visitors …
  6. 6. What is AP? <ul><li>Aspect-Oriented Programming (AOP) where the components/connectors/aspects are written in terms of graphs and traversal strategies </li></ul>
  7. 7. Why traversal strategies? <ul><li>Law of Demeter </li></ul><ul><li>A style rule for building systems </li></ul><ul><li>See also upcoming book by Krzysztof Czarnecki / Ulrich Eisenegger on Generative Programming </li></ul>
  8. 8. Why Traversal Strategies? <ul><li>Law of Demeter: a method should talk only to its </li></ul><ul><li>friends: </li></ul><ul><li>arguments and part objects (computed or stored)‏ </li></ul><ul><li>and newly created objects </li></ul><ul><li>Dilemma: </li></ul><ul><ul><li>Small method problem of OO (if followed) or </li></ul></ul><ul><ul><li>Unmaintainable code (if not followed) </li></ul></ul><ul><li>Traversal strategies are the solution to this dilemma </li></ul>
  9. 9. Law of Demeter Principle <ul><li>Each unit should only use a limited set of other units: only units “closely” related to the current unit. </li></ul><ul><li>“ Each unit should only talk to its friends.” “Don’t talk to strangers.” </li></ul><ul><li>Main Motivation: Control information overload. We can only keep a limited set of items in short-term memory. </li></ul>
  10. 10. Law of Demeter FRIENDS
  11. 11. Application to OO <ul><li>Unit = method </li></ul><ul><ul><li>closely related = </li></ul></ul><ul><ul><ul><li>methods of class of this/self and other argument classes </li></ul></ul></ul><ul><ul><ul><li>methods of immediate part classes (classes that are return types of methods of class of this/self )‏ </li></ul></ul></ul><ul><li>In the following we talk about this application of the Law of Demeter Principle to OO </li></ul>
  12. 12. The Law of Demeter (cont.) Violation of the Law <ul><li>class A {public: void m(); P p(); B b; }; </li></ul><ul><li>class B {public: C c; }; </li></ul><ul><li>class C {public: void foo(); }; </li></ul><ul><li>class P {public: Q q(); }; </li></ul><ul><li>class Q {public: void bar(); }; </li></ul><ul><li>void A::m() { </li></ul><ul><li>this.b.c. foo (); this.p().q(). bar ();} </li></ul>
  13. 13. Violations: Dataflow Diagram A B C 1:b 2:c P Q 3:p()‏ 4:q()‏ foo()‏ bar()‏ m
  14. 14. Rumbaugh and the Law of Demeter <ul><li>Quote: Avoid traversing multiple links or methods. A method should have limited knowledge of an object model. A method must be able to traverse links to obtain its neighbors and must be able to call operations on them, but it should not traverse a second link from the neighbor to a third class. </li></ul>
  15. 15. Agreement that LoD Good Idea <ul><li>How to follow LoD: good solutions exist but they are not widely known. Two approaches to following LoD: </li></ul><ul><ul><li>OO approach: many programmers do this </li></ul></ul><ul><ul><li>Adaptive approaches </li></ul></ul><ul><ul><ul><li>Traversal support </li></ul></ul></ul><ul><ul><ul><li>APPC </li></ul></ul></ul><ul><ul><ul><li>Demeter/Java </li></ul></ul></ul><ul><ul><ul><li>Demeter/C++ </li></ul></ul></ul>
  16. 16. Adaptive Following of LoD <ul><li>void A::m() { </li></ul><ul><li>(C)‏ </li></ul><ul><li>Traversal.long_get(this,”A->C”).foo(); </li></ul><ul><li>(Q)‏ </li></ul><ul><li>Traversal.long_get(this,”A->Q”).bar();} </li></ul><ul><li>void A::m() { </li></ul><ul><li>this.b.c.foo(); this.p().q().bar();} // violation </li></ul>
  17. 17. OO Following of LoD A B C 1:b c P Q 3:p()‏ q()‏ foo()‏ bar()‏ m 2:foo2()‏ 4:bar2()‏ foo2 bar2
  18. 18. What if your friends are far away? <ul><li>You pay them to travel to you or you send an agent to them to collect the information you need. </li></ul><ul><ul><li>Approximate Directions (AP solution): You give them or your agent directions about what kind of information to collect but you don’t care about accidental details of the travel. </li></ul></ul><ul><ul><li>Detailed Directions : You give them or your agent detailed travel directions. </li></ul></ul>
  19. 19. Adaptive Following LoD FRIENDS S A b C X a: S -> A b: S -> B c: S -> X -> C a c
  20. 20. What is a traversal strategy <ul><li>A graph (defines a “regular expression” for data navigation)‏ </li></ul><ul><li>An edge (A,B) in the graph means: A any* B </li></ul><ul><li>any means: any edge or node </li></ul>
  21. 21. Collaborating Classes BusRoute BusStopList BusStop BusList Bus PersonList Person passengers buses busStops waiting 0..* 0..* 0..* find all persons waiting at any bus stop on a bus route OO solution: one method for each red class
  22. 22. Traversal Strategy BusRoute BusStopList BusStop BusList Bus PersonList Person passengers buses busStops waiting 0..* 0..* 0..* first try: from BusRoute to Person find all persons waiting at any bus stop on a bus route
  23. 23. Traversal Strategy BusRoute BusStopList BusStop BusList Bus PersonList Person passengers buses busStops waiting 0..* 0..* 0..* from BusRoute through BusStop to Person find all persons waiting at any bus stop on a bus route
  24. 24. Robustness of Strategy BusRoute BusStopList BusStop BusList Bus PersonList Person passengers buses busStops waiting 0..* 0..* 0..* from BusRoute through BusStop to Person VillageList Village villages 0..* find all persons waiting at any bus stop on a bus route
  25. 25. Even better: interface class graph BusRoute BusStop Bus Person passengers buses busStops waiting 0..* 0..* 0..* find all persons waiting at any bus stop on a bus route 0..* from BusRoute through BusStop to Person
  26. 26. Map interface class graph to application class graph BusRoute BusStopList BusStop BusList Bus PersonList Person passengers buses busStops waiting 0..* 0..* 0..* from BusRoute through BusStop to Person VillageList Village villages 0..* edge -> path
  27. 27. Map interface class graph to application class graph BusRoute BusStopList BusStop busStops 0..* from BusRoute through BusStop to Person VillageList Village villages 0..* edge -> path BusRoute BusStop busStops 0..* edge path
  28. 28. Adaptive Programming Strategy Graphs Object Graphs define family of Class Graphs are use-case based abstractions of
  29. 29. Adaptive Programming Strategy Graphs Object Graphs define traversals of
  30. 30. Adaptive Programming Strategy Graphs Visitors guide and inform
  31. 31. Strategy Graphs <ul><li>Nodes: positive information: Mark corner stones in class diagram: Overall topology </li></ul><ul><li>of collaborating classes. </li></ul><ul><li>from BusRoute </li></ul><ul><li>through BusStop </li></ul><ul><li>to Person </li></ul>BusRoute BusStop Person
  32. 32. Traversal strategies create friends <ul><li>Class Traversal is an intermediate class between classes that need to communicate </li></ul>Traversal.long_get(Object o, Strategy s)‏
  33. 33. Some nodes are not friends for accidental reasons <ul><li>Non-friend classes exist for other reasons </li></ul><ul><li>Many non-friend classes are filtered out by traversal strategies </li></ul><ul><li>Ideal class graph: all are friends, even “far” away classes </li></ul>
  34. 34. Adaptive Following LoD: Key idea <ul><li>Introduce an ideal class graph </li></ul><ul><li>Write current behavior in terms of ideal class graph </li></ul><ul><li>Map ideal class graph flexibly into concrete class graph using traversal strategies </li></ul>
  35. 35. A = s A B B C C D D E E F=t F G S S is a strategy for G
  36. 36. Important is concept of compatibility <ul><li>A graph G is compatible with a graph S, if S is a connected subgraph of the transitive closure of G. (G: concrete graph, S: abstract graph). </li></ul><ul><li>Different forms of compatibility: refinement, strong refinement </li></ul>
  37. 37. A A B B C C D D E E F F G 1 G 2 G 1 compatible G 2 Compatible: connectivity of G 2 is in G 1
  38. 38. A A B B C C D D E E F F G 1 G 2 G 1 strong refinement G 2 refinement: connectivity of G 2 is in “pure” form in G 1 and G 1 contains no new connections in terms of nodes of G 2
  39. 39. A A B B C C D D E E F F G 1 G 2 G 1 refinement G 2 refinement: connectivity of G 2 is in “pure” form in G 1 Allows extra connectivity.
  40. 40. C1 C2 C3 C4 C5 P1 P2 P3 C1 C3 C2 C4 one generic collaboration reused with a family of concrete applications APPL 1 APPL n Design Goal: Adaptiveness
  41. 41. C1 C2 C3 C4 C5 P1 P2 P3 reused with different mappings APPL 1 APPL 1 C2 C3 C4 C5 C1 of participants to classes of the same application one generic collaboration Design Goal: Adaptiveness
  42. 42. Compiling Adaptive Programs <ul><li>Palsberg/Xiao/Lieberherr: TOPLAS ‘95 </li></ul><ul><li>Palsberg/Patt-Shamir/Lieberherr: Science of Computer Programming 1997 </li></ul><ul><li>Lieberherr/Patt-Shamir: Strategy graphs, 1997 NU TR </li></ul><ul><li>Lieberherr/Patt-Shamir: Dagstuhl ‘98 Workshop on Generic Programming (LNCS)‏ </li></ul>
  43. 43. Short-cut strategy: {A -> B B -> C} A B C X 0..1 x x b c A B C strategy graph with name map c Incorrect traversal code: class A {void t(){x.t();}} class X {void t(){if (b!==null)b.t();c.t();}} class B {void t(){x.t();}} class C {void t(){}} Correct traversal code: class A {void t(){x.t();}} class X {void t(){if (b!==null)b.t2();} void t2(){if (b!==null)b.t2();c.t2();} } class B {void t2(){x.t2();}} class C {void t2(){}}
  44. 44. Short-cut strategy: {A -> B B -> C} A X x B C X 0..1 x b c start set finish set b A( <x> X( <b> B( <x> X( <c> C()))‏ <c> C()))‏ Object graph Traversal graph Modulo some details: Traversal graph = Cross-product of NFAs
  45. 45. Short-cut strategy: {A -> B B -> C} A X x B C X 0..1 x b c start set finish set b A( <x> X( <b> B( <x> X( <c> C()))‏ <c> C()))‏ Object graph Traversal graph Used for token set and currently active object
  46. 46. Short-cut strategy: {A -> B B -> C} A X x B C X 0..1 x b c start set finish set b A( <x> X( <b> B( <x> X( <c> C()))‏ <c> C()))‏ Object graph Traversal graph Used for token set and currently active object
  47. 47. Short-cut strategy: {A -> B B -> C} A X x B C X 0..1 x b c start set finish set b A( <x> X( <b> B( <x> X( <c> C()))‏ <c> C()))‏ Object graph Traversal graph Used for token set and currently active object
  48. 48. Short-cut strategy: {A -> B B -> C} A X x B C X 0..1 x b c start set finish set b A( <x> X( <b> B( <x> X( <c> C()))‏ <c> C()))‏ Object graph Traversal graph Used for token set and currently active object
  49. 49. Short-cut strategy: {A -> B B -> C} A X x B C X 0..1 x b c start set finish set b A( <x> X( <b> B( <x> X( <c> C()))‏ <c> C()))‏ Object graph Traversal graph Used for token set and currently active object
  50. 50. Short-cut strategy: {A -> B B -> C} A X x B C X 0..1 x b c start set finish set b A( <x> X( <b> B( <x> X( <c> C()))‏ <c> C()))‏ Object graph Traversal graph Used for token set and currently active object After going back to X Modulo some details: SIMULATION OF AN NFA
  51. 51. Main Theorem (correctness)‏ <ul><li>Let SS be a strategy, let G be a class graph, let N be a name map, and let B be a constraint map. Let TG be the traversal graph generated by the Traversal Graph Algorithm, and let T s and T f be the start and finish sets, respectively. </li></ul>
  52. 52. Main Theorem (cont.)‏ <ul><li>Let O be an object tree and let o be an object in O . Let H be the sequence of nodes visited when o.Traverse is called with argument T s , guided by TG . Then traversing O from o guided by PathSet[SS,G,N,B] produces H . </li></ul>
  53. 53. Complexity of algorithm <ul><li>Traversal Graph Alg.: All steps run in time linear in the size of their input and output. Size of traversal graph: O(|S| 2 |G| d 0 ) where d 0 is the maximal number of edges outgoing from a node in the class graph. </li></ul><ul><li>Traverse: How many tokens? Size of argument T is bounded by the number of edges in strategy graph. </li></ul>
  54. 54. Traversal Support for Java: class Traversal <ul><li>static Object long_get(Object o, Strategy s); </li></ul><ul><li>static Iteration long_collect(Object o, Strategy s); </li></ul><ul><li>static Object traverse(Object o, Strategy s, Visitor v[]); </li></ul>
  55. 55. Traversal Support for Java <ul><li>static X long_get(Object o, Strategy s); </li></ul><ul><ul><li>starting at object o, traverse down following s and return target object of s </li></ul></ul><ul><ul><li>s must have a single target and s must specify unique path </li></ul></ul>
  56. 56. Traversal Support for Java <ul><li>static Iteration long_collect(Object o, Strategy s); </li></ul><ul><ul><li>starting at object o traverse following s and return the collection of target objects of s. </li></ul></ul>
  57. 57. Traversal Support for Java <ul><li>static Object traverse(Object o, Strategy s, Visitor v[]); </li></ul><ul><ul><li>starting at object o traverse down following s and execute the visitors in v. Return the object returned by first visitor. </li></ul></ul>
  58. 58. Traversal Support: visitors class SampleVisitor extends Visitor{ // local variables public SampleVisitor(); // initialize public void before(Visited host)...; public void after (Visited host)...; public void before_z(X source, Y dest)...; public void after_z (X source, Y dest)...; Object get_return_val()...; public void start()...; public void finish()...; }
  59. 59. Traversal Support: visitors abstract class Visitor { // GENERATED CODE public Visitor() {super();} public void start() {} public void finish() {} public void before(Visited host){}; public void after (Visited host){}; public void before_p(Q source, H dest){}; public void after_p (Q source, H dest){}; … }
  60. 60. Polytypic and Adaptive Programming <ul><li>Polytypic programming is programming in the meta-model of self-describing systems </li></ul><ul><li>Adaptive programming is useful for polytypic programming as well as for application-centered polytypic programming </li></ul>
  61. 61. Polytypic and Adaptive Programming
  62. 62. Polytypic and Adaptive Programming
  63. 63. Related Work <ul><li>AOP at Xerox PARC </li></ul><ul><li>Subject-oriented Programming </li></ul><ul><li>Polytypic Programming </li></ul><ul><li>Generative Programming </li></ul>
  64. 64. Conclusions/On-line information <ul><li>AP works well </li></ul><ul><ul><li>no tool support: navigation/visitor separation is useful: HP printer installation project </li></ul></ul><ul><ul><li>with tool support: Demeter/C++, Demeter/Java: several industrial projects </li></ul></ul><ul><li>The best way to follow the LoD </li></ul><ul><li>www.ccs.neu.edu/research/demeter </li></ul>
  65. 65. The end
  66. 66. Future work <ul><li>Does AP work on infinite graphs? </li></ul><ul><li>Inductive graphs in polytypic programming </li></ul><ul><li>Non regular data types: correspond to the ones where grammar defines non-context sensitive language? </li></ul>
  67. 67. Nested polymorphic datatypes and traversals <ul><li>Nested datatype but rational tree </li></ul><ul><li>ZigZag(A,B) : Nil|NonNil(A,ZigZag(B,A)). </li></ul><ul><li>NonNil(C,D) = <first> C <rest> D. </li></ul><ul><li>Nil = . </li></ul><ul><li>MyZigZag = ZigZag(X,Y). X=“x”.Y=“y”. </li></ul><ul><li>Sentence: x y x y ... </li></ul>
  68. 68. Polymorphic datatypes and traversals <ul><li>Non-nested datatype with rational tree </li></ul><ul><li>Zig(A,B) : Nil|NonNil(A,Zag(A,B)). </li></ul><ul><li>Zag(A,B) : Nil|NonNil(B,Zig(A,B)). </li></ul><ul><li>NonNil(C,D) = <first> C <rest> D. Nil = . </li></ul><ul><li>MyZig = Zig(X,Y). X=“x”.Y=“y”. </li></ul><ul><li>Sentence: x y x y … </li></ul><ul><li>Zig(A,B) = ZigZag(A,B)‏ </li></ul>
  69. 69. Polymorphic datatypes and traversals <ul><li>TypeConstructor Bool </li></ul><ul><li>ValueConstructors False, True </li></ul><ul><li>data Bool = False | True </li></ul><ul><li>TypeConstructors = AbstractClasses </li></ul><ul><li>There is a need for type constructors / value constructors in Haskell because of parameterization: need nice constructor names </li></ul>
  70. 70. Polymorphic datatypes and traversals <ul><li>Rose(A) = Branch(A, List(Rose(A)). </li></ul><ul><li>Rose(A) = <a> A <l> List(Rose(A). </li></ul><ul><li>If we don’t use Branch, we don’t have a constructor name if definition is algebraic, i.e., there is no finite expansion. </li></ul><ul><li>Interface inheritance using “nested” polymorphic types: subtype polymorphism is a special case of nested parametric polymorphism </li></ul>
  71. 71. Polymorphic datatypes and traversals <ul><li>Non-nested datatype with rational tree: </li></ul><ul><li>Rose(A) = Branch(A, List(Rose(A)). </li></ul><ul><li>List(S) : Nil|NonNil(S,List(S)). </li></ul><ul><li>NonNil(C,D) = <first> C <rest> D. Nil = . </li></ul><ul><li>Branch(C,D) = “(”<first> C <rest> D “)”. </li></ul><ul><li>MyRose = Rose(X). X=“x”. </li></ul><ul><li>Sentence: (x (x) (x) (x (x)))‏ </li></ul>
  72. 72. Perfect trees <ul><li>Perfect(T) : Zero(T) | </li></ul><ul><li>Succ(Perfect(Pair(T,T))). </li></ul><ul><li>Zero(T) = <t> T. </li></ul><ul><li>Pair(S,T)= <f> S <s> T. Succ(A) = A </li></ul><ul><li>succ(succ(zero(((1,2),(3,4))))‏ </li></ul>
  73. 73. Perfect trees <ul><li>Perfect t = Zero | Succ(Perfect(t,t))‏ </li></ul><ul><li>succ(succ(zero(((1,2),(3,4))))‏ </li></ul><ul><li>Zero :: t -> Perfect t </li></ul><ul><li>Succ :: Perfect(t,t) -> Perfect t </li></ul>
  74. 74. Usage of nested polymorphic datatypes <ul><li>Nested means: recursive call different. </li></ul><ul><li>Phil Wadler: GJ works with them.They are only used by people with large brains. </li></ul><ul><li>Complex data structures: 2-3 trees, Perfect trees, etc. </li></ul>
  75. 75. Usage of “nested” polymorphic datatypes <ul><li>Nested means: like a nested function call. </li></ul><ul><li>Simulate inheritance </li></ul><ul><li>See also paper by Remy (Ask Eric Meijer)‏ </li></ul>
  76. 76. Parameterized traversal strategies <ul><li>T1(A) = from Rose(A) to A </li></ul><ul><li>T2(A,B) = from Rose(A) via B to A </li></ul><ul><li>Sources(N) = from Graph(N,*) through *,source,* to N </li></ul><ul><li>Sources2(G,T) = from G through *,source,* to T. </li></ul><ul><li>call: Sources2(Graph(Integer,X),X) </li></ul><ul><li>DJ: put traversal strategies in separate file </li></ul><ul><li>Navigation aspect file: Strategy s = new Strategy(…); </li></ul>
  77. 77. Graph example <ul><li>Graph(NL,EL) = </li></ul><ul><li><edges> List(Edge(NL,EL))‏ </li></ul><ul><li><nodes> List(Node(NL)). </li></ul><ul><li>Edge(N,L) = </li></ul><ul><li><source> Node(N) <label> L </li></ul><ul><li><target> Node(N). </li></ul><ul><li>Node(N) = <n> N. </li></ul>
  78. 78. Program Analysis via Graph Reachability <ul><li>Talk by Thomas Reps at Dagstuhl March 1998: Program Comprehension and SE. </li></ul><ul><li>CFL reachability is central problem </li></ul><ul><ul><li>graph, edges labeled from alphabet </li></ul></ul><ul><ul><li>grammar defining L </li></ul></ul><ul><ul><li>a path from s to t counts as valid connection if the word formed by labels is in L </li></ul></ul><ul><ul><li>O(n3) </li></ul></ul>
  79. 79. Concrete syntax is more abstract than abstract syntax <ul><li>ICG as grammar. Represent ICG objects by constructor expressions. CCG defines same language as CCG. Have new CCG2 also same language. Create CCG2 objects automatically: pretty print CCG objects and parse them as CCG2 objects </li></ul><ul><li>Advantage: ICG objects not as sentences; not dependent on concrete syntax. Is this a good way to define the map? Adding syntax to ICG and matching syntax to CCG so that parsing creates correponding objects. How get accessors? Get_x() -> get_a()->get_b()-> … For long_get: unique: can derive from one sample object. For long_collect: use maximal sample object. </li></ul><ul><li>language equivalence: not just same language but objects must correspond </li></ul>
  80. 80. Concrete syntax versus traversal strategies <ul><li>Expressing map with traversal strategies versus expressing it with concrete syntax </li></ul>
  81. 81. Traversal Strategies Concrete Syntax <ul><li>Default translation is often sufficient </li></ul>
  82. 82. Distinguish between paths <ul><li>A = B C. B = D. C = D. </li></ul><ul><li>from A via B to D </li></ul><ul><li>A = [“b” B[ [C]. B = D. C = D. </li></ul><ul><li>Want only mapping between class graphs: </li></ul><ul><li>A = B C. B = D. C = D. </li></ul>
  83. 83. Mapping between class graphs <ul><li>A = B. B = D. </li></ul><ul><li>Want only mapping between class graphs: </li></ul><ul><li>A = B1 C1. B1 = B2. B2 = D. C1 = C2. C2 = D. </li></ul><ul><li>No syntax needed to translate. </li></ul><ul><li>If multiple paths in CCG: B1 = [D]. Added </li></ul><ul><li>B1 = [“d”D]. For edge </li></ul><ul><li>B1 = “b2” B2. Object represented by b2. A=“b2”B. Is this general? </li></ul>
  84. 84. Parsers weave sentences into objects Problem in OO programs: Constructor calls for compound objects are brittle with respect to structure changes. Solution : Replace constructor calls by calls to a parser. Annotate class diagram to make it a grammar. Benefit : reduce size of code to define objects, object descriptions are more robust Correspondence: Sentence defines a family of objects. Adaptive program defines family of object-oriented programs. In both cases, family member is selected by (annotated) class diagram. Structure-shy Object
  85. 85. Run-time weaving: Description Sentence * 3 + 4 5 Grammar C ompound ... S imple ... N umber ... M ultiply ... A dd ... etc. C M * N 3 C A + N N 4 5 Object in linear form (Constructor calls)‏ C M * N 3 C A + N 4 N 5 Object as tree Grammar defined by annotating UML class diagram SENTENCE IS MORE ROBUST THAN OBJECT Structure-shy Object
  86. 86. Connection: Program Analysis via Graph Reachability <ul><li>graph, edges labeled from alphabet: class graph </li></ul><ul><li>grammar defining cfl L: traversal graph! </li></ul><ul><li>a path from s to t counts as valid connection if the word formed by labels is in L </li></ul><ul><li>traversal graph: regular language? </li></ul>

×