510 likes | 615 Views
Playing with Verification, Planning and Aspects Unusual Methods for Running Scenario-Based Programs. David Harel The Weizmann Institute of Science. biological systems commercial systems, health care, …. Examples of reactive systems (H & Pnueli, ‘ 85). command & control systems
E N D
Playing with Verification, Planning and Aspects Unusual Methods for Running Scenario-Based Programs David Harel The Weizmann Institute of Science
biological systems commercial systems, health care,… Examples of reactive systems(H & Pnueli, ‘85) command & control systems telecommunication systems avionics & aerospace systems automotive systems circuits & VLSI medical instrumentation interactive software . . . . . . . . .
Two dual ways to model reactivity “Classical” approach State-based Intra-object e.g., Statecharts(H, ‘84) tool:Rhapsody (H&Gery,‘92) Newer approach Scenario-based Inter-object LSCs(Damm&H,‘98) tool:Play-Engine (H&Marelly,’02)
intra-object behavior (all pieces of stories given for each relevant object) This leads naturally to implementation
inter-object behavior (each story given for all relevant objects) Can this be made powerful enough to be the implementation?
First, a quick introduction to LSCs, a visual formalism for scenario-based programming
Most popular language for formal requirements: Temporal Logic(Pnueli ’74) Most popular visual formalism for requirements: Message Sequence Charts (MSCs) (CCITT ’92 and before) (or “ UML Sequence Diagrams”)
Keyboard Send Key Click Click(digit) Click Sent Retrieve(digit) number Call(number) signal signal not busy MSC for a quick-dial feature
MSCs are usually used in practice for testing As a language for behavioral requirements, they are extremely weak in expressive power Semanticsis mere partial order on events Hence, in principle, a system that does nothing at all (or one that does everything) satisfies all MSCs!
They cannot say: - under these conditions systemmust do this - instance will send message - message will arrive (within such and such time) - this is not allowed to happen - this condition must be true (otherwise abort) . . . . . . . . .
So we need a lot more than MSCs: may/must; can/always; fragmental and overlapping scenarios; anti-scenarios; etc.
Live sequence charts(LSC’s) “LSC’s: Breathing Life into Message Sequence Charts” (Damm & H, 1998 ) A multi-modal extension of classical MSCs, with logicalmodalities (universal/existential, hot/cold, etc.) and structure (subcharts, conditionals, loops, etc.)
element mandatory provisional A E chart universal all system runs satisfy chart existential at least one run satisfies chart
element mandatory provisional A E chart universal all system runs satisfy chart existential at least one run satisfies chart hot run of instance must progress beyond location cold run of instance need not progress beyond location location in chart hot if message is sent it must be received cold receipt of message is not guaranteed message cold if condition not met exit current (sub) chart hot condition must be met otherwise abort condition
Basic form of a (universal) LSC prechart (if) main chart (then) (similar to [a]<b> in dynamic logic)
the forbidden scenario False • Subcharts • Loops • Coldconditions enable control structures • Hotconditions enable anti-scenarios:
LSC specification : LS = M, pc, mod mod(m) is mode of m: Set of LSC’s pc(m) is the prechart , A E Chart m satisfied by system run r: rm m existential: m universal: System S satisfies specification LS: SLS existential . run . rm universal . run . rm
inter-object behavior (one story for all relevant objects) Can this be made powerful enough to be the implementation?
Traditionally, scenario-based behavior was considered unsuitable for execution, and therefore no good for implementation How do you execute a bunch of scenarios?
Extensive strengthening of the language of LSCs (e.g., symbolic instances, time & real-like time, weighted choice, forbidden elements,…) Play-In (friendly & convenient capture) Play-Out (algorithm for execution) The Play-Engine: A full supporting tool Work done with R. Marelly(’99-’03)
Basic idea behind play-out Play-out works like an over-obedient, but strictly minimalistic citizen, zealously adhering to the Book of Rules. Universal charts drive the execution; relevant chart copies started and monitored continuously; instances & variables unified and bound on the fly. (external event;step*; stable?) = superstep Hot stuff willbe done, cold stuff might. Play-engine can thus be viewed as a “universal reactive machine”.
At the very least, this provides many enhancements to the conventional system development life-cycle Such as…
Convenient GUI-based method for specifying desired behavior Ability to execute requirements (actually, “executable use cases”) A “deep” kind of rapid prototyping and more solid starting point for design Rich language for test generation; execution-based testing (much work done on this in W. Damm’s group) Strong basis for synthesisandverification (both groups) and more . . .
But one can be more ambitious, and actually use LSCs as the language for programming (and running) the system!
2003 book attempts to describe it all (including formal semantics: ) Come, Let’s Play: Scenario-Based Programming Using LSCs and the Play-Engine D. Harel and R. Marelly Springer, June 2003 (includes the Play-Engine software)
LSCs are inherently declarative and non-deterministic: They may give rise to different legal runs, even within supersteps, due to partial order within a chart, and multiple charts interleaving. The Play-Engine takes a practical approach: implements policies and heuristics to execute system runs, not controllable by the user (unless programmed explicitly into the LSCs). The problem with naïve play-out
Smart play-out(uses model-checking) Planned play-out(uses planning algorithms) Compilation(uses aspect-oriented programming) This talk:Three unusual ways to address this problem(using, respectively, hard-core CS, AI techniques, and a very different programming paradigm)
We apply powerful methods taken from program verification (model checking, to be precise) to help find the “correct” run or identify inconsistencies So we use verification, but not to prove or analyze programs. We use it to run them! I. Smart Play-out(with H. Kugler, A. Pnueli & R. Marelly, ‘02)
Variables: - chart mi is active (in main chart) - Oj sends msg to Ok - Ok receives msg from Oj - Oj‘s location (0 . . . lmax ) Mapping to a transition system
There is an active chart causing msg, and all active charts must agree on msg Translation relation (cont.)
Chart is active when the prechart reaches maximal locations, and is deactivated when the main chart reaches maximal locations. Chart activation
Ask the model checker to prove that at any time, at least one of the universal charts is still active: Final step If this is true, there is no way to proceed, but if it isn’t the model-checker finds a counter-example, which is exactly a desired superstep! The resulting sequence of events is then fed automatically to the Play-Engine for execution
Being smart helps Pre-recorded demo
We exploit the similarities between aspect-oriented programming and the inter-object nature of LSCs, by compiling LSCs into AspectJ “Scenario aspects” are used to coordinate the simultaneous monitoring and direct execution of the LSCs. II. Compilation via Aspects(with S. Maoz, ‘06)
Each chart is compiled into a Scenario Aspect Pointcuts capture message calls + context Corresponding advice advances the cut state A central Coordinator aspect is built, containing A single pointcut to “catch” all message calls An advice that collects cut state information from all active scenarios, and uses a strategy to choose the next method to execute
Actually, our compiler does not work on LSCs, but on a UML 2.0-complient variant, called MUSDs(H & Maoz, ‘06) The resulting code follows the naïve play-out execution strategy, but we are working on a mechanism for parameterizing strategies
Example objA:ClassA objB1:ClassB objB2:ClassB methodM1() methodM1() !objB1.isFoo(objB2)) methodM2() methodM3() Sample scenario aspect public aspect MUSDAspectExample extends MUSDAspect { //... pointcut objAobjBmethodM1 (ClassA s, ClassB t): call(void classB.methodM1()) && this(s) && target(t); after (ClassA s, ClassB t): objAobjB1methodM1(s , t) { changeCutState(MUSDMethod.CLASSA_CLASSB_M1, s, t);} //... private void changeCutState (int MUSDMethod, Object sourceObject, Object targetObject) { //... switch (MUSDMethod) { case MUSDMethod.CLASSA_CLASSB_M1: if (isInCut(0,0,0)) { objB1 = (ClassB)targetObject; setCut(1,0,1); return; } if (isInCut(1,0,1)) { objB2 = (MemoryCard)targetObject; setCut(1,1,2); if (!objB1.isFoo(objB2)) { setCut(2,2,3); return; } } break; case MUSDMethod.CLASSA_CLASSB_M2 : //... } MUSDCompletion(); //... } //... }
Compilation to AspectJ Pre-recorded demo
We adapt a planning algorithm (specifically, Graphplan) to do what smart play-out does; e.g., to plan and execute a superstep However, here we are able to detect and generate all solutions, if so desired. We’ve also set-up a user-guided exploration mechanism for traversing supersteps III. Planned Play-out(with I. Segall, ‘06)(ack: Orna K.)
Result: Propositions possibly true at time 2 Propositions True at time 1 Precondition edges Possible actions at time 1 Add edges Delete edges In (A) In (A) In (A) Proposition Levels Action Levels Remove (A, R2) Insert (A, R1) Insert (A, R1) In (B) In (B) In (B) Remove (B, R2) Insert (B, R1) Insert (B, R1) At (Bag, R2) At (Bag, R2) Move (R1, R2) Move (R1, R2) At (A, R2) At (A, R1) At (A, R1) At (A, R1) At (B, R2) At (B, R1) At (B, R1) At (B, R1) At (Bag, R1) At (Bag, R1) At (Bag, R1) Actions Time 3 Propositions time 4 Propositions Time 1 Actions Time 1 Propositions time 2 Actions Time 2 Propositions time 3 No-op edges Planning graph
Mutex Actions: never chosen together in a timestep Mutex Propositions: never true together in a timestep Mutual exclusions
Actions Time 3 Propositions time 4 Propositions Time 1 Actions Time 1 Propositions time 2 Actions Time 2 Propositions time 3 Mutex example Mutex Propositions Competing Needs Interference B Interference A At (A, R2) At (B, R2) In (A) In (A) In (A) Remove (A, R2) Insert (A, R1) Insert (A, R1) In (B) In (B) In (B) Remove (B, R2) Insert (B, R1) Insert (B, R1) At (Bag, R2) At (Bag, R2) Move (R1, R2) Move (R1, R2) At (A, R1) At (A, R1) At (A, R1) At (B, R1) At (B, R1) At (B, R1) At (Bag, R1) At (Bag, R1) At (Bag, R1)
Actions Time 3 Propositions time 4 Propositions Time 1 Actions Time 1 Propositions time 2 Actions Time 2 Propositions time 3 Plan extraction At (A, R2) At (B, R2) In (A) In (A) In (A) Remove (A, R2) Insert (A, R1) Insert (A, R1) In (B) In (B) In (B) Remove (B, R2) Insert (B, R1) Insert (B, R1) At (Bag, R2) At (Bag, R2) Move (R1, R2) Move (R1, R2) At (A, R1) At (A, R1) At (A, R1) At (B, R1) At (B, R1) At (B, R1) At (Bag, R1) At (Bag, R1) At (Bag, R1)
Planned play-out Pre-recorded demo
✓ ✓ ✓ Kernel(msgs+conds) ✓ ✓ ✗ - variables in msgs hard ✓ ✓ ✓ ✓ - if, choice, etc. ✓ ✓ ✓ ✗ not bounded ✓ - loops ✓ ✗ ✗ ✓ - multiple copies ✓ ✗ ✗ ✓ - symbolic instances hard ✓ ✗ ✓ ✓ - time (discrete) hard ✓ ++ ✓ ✓ ✓ - forbidden elements ✗ easy ✓ ✗ ✗ - probabilistic choice ✗ easy ✗ easy Status of current Play-Engine implementation Execution strategy naïve smart naïve play-out compilation to AspectJ smart play-out planned play-out LSC feature
The two smart methods exhibit rather severe time complexity My feeling: some powerful idea, awaiting discovery, is needed to help ease performance
Which of the methods will turn out to be best? And what does “best” even mean? The jury is still far from being in. Stay tuned…