View
278
Download
4
Category
Preview:
Citation preview
Software Unit TestingCase Study: Money Class
Conversation Simulation
COP 4331
OO Processes for Software Development
Dr. David A. Workman
School of EE and Computer Science
October 2, 2006
October 2, 2006 (c) Dr. David A. Workman 2
Hierarchical View of Design
main
A::One() A::Two() A::Three()
B::One()C::One()
B::Two()
D::One()
E::Two()
E::One() D::Three()
D::Two()
Use Case #1
Use Case #3Use Case #2
October 2, 2006 (c) Dr. David A. Workman 3
Design & Testing Principles
A
D
B C
Principle 1: Design should be performed “top-down” for each functional thread defined by a Use Case; that is, the interface and detailed design of a module should follow the design of all modules that functionally depend on it.
Rationale: By performing interface and detailed design top-down, we ensure that all requirements flow from dependent modules toward the modules they depend on. This principle attempts to postpone detailed design decisions until all functional requirements for a module are known.
Principle 2: Coding and Unit Testing should be performed “bottom-up” for a functional thread; that is, the unit testing of a module should precede the unit testing of all modules that functionally depend on it.
Rationale: By performing unit testing bottom-up, we ensure that all subordinate moduleshave been verified before verifying the module that depends on them. This principle attempts to localize and limit the scope and propagation of changes resulting from unit testing.
October 2, 2006 (c) Dr. David A. Workman 4
Design & Testing Schedules
Layer 1 Layer 2 Layer 3 Layer 4 Layer 5A1, A2, A3 B1, D2, C1 E1, B2, D3 D1 E2
Development Layers for Detailed Design and Coding
Layer 1' Layer 2' Layer 3' Layer 4' Layer 5'B1, E1,E2, D3
A1, D2, D1 A2, B2 C1 A3
Development Layers for Unit Testing
B1 A1A1 B1 E1 E1A2 D2 B2 B3 D2 A2A3 C1 D3 D1 E2 E2 D1 B2 C1 A3
Effort
Time
Development Schedule
Build #1 (Integration Test 1)Build #2 (Integration Test 2)Build #3 (System Test)
See Notes
Design & Test Example: Discrete Event Simulator
©Dr. David A. Workman
School of EE and Computer Science
University of Central Florida
March 29, 2007
October 2, 2006 (c) Dr. David A. Workman 6
Use Case Diagram: Simulator
Simulation System
ConstructWorld
SpecifyInput
SimulateWorld
OutputWorldObjects
ReportSimulation
Data
InitializeSimulation
Simulation User
SpecifyOutput
SimulationInputFile
SimulationLogFile
October 2, 2006 (c) Dr. David A. Workman 7
Simulation Architecture
October 2, 2006 (c) Dr. David A. Workman 8
Simulation Architecture: Design Template
The Passive layer contains all classes that model problem data and inanimate objects of the simulated world. Agents make direct calls on passive objects, but must account for the simulation time consumed when doing so. Passive objects make direct calls to each other, if necessary. Passive objects may be passed from one Agent to another as part of a instance of some Message subclass.
This layer contains all the derived subclasses of Message. These classes are used to pass data for servicing interaction events between Agents. Only recipient Agent classes know the content and use of instances of these classes. Methods of Agents receiving messages optionally take parameters which are instances of one (or more) of the Passive classes and return an instance of class Message or one of its sub-classes. Instances of the root class Message carry no data and denotesignals that require some action on the part of the receiver Agent.
Virtual World
Message
Players
Agent
Event
2
Passive Class Layer
Message Layer
Agent Layer(Active Objects)
Interface and Control Layer
EventMgr *
1Other
Subclasses
All ActiveObjects
* *
All PassiveClasses/Objects
* *
*
This layer consists of all active object classes. Active objects must beinstances of some subclass of abstract class Agent. The simulation progresses as a result of Events created andserviced by Agents. An Event has four components: a Sender agent, a Recvr agent, an instance of some Messagesubclass, and an event time. When one Agent wishes to interact with another, it must do so by creating an Eventthat defines a “future” time at which the interaction will occur. The message component defines an action to theRecevr agent and possibly data necessary to complete the action.
SimModels Classes SimMgmt Classes
October 2, 2006 (c) Dr. David A. Workman 9
Simulation Architecture: Student Conversation
Conversation
Message
Players
Agent
Event
2
Passive Class Layer
Message Layer
Agent Layer(Active Objects)
Interface and Control Layer
EventMgr *
1
AnswerMsg
* *
Question
SimModels Classes SimMgmt Classes
Student
Answer
QuestionMsg
October 2, 2006 (c) Dr. David A. Workman 10
Design Graph: 1
0: Main()
4 Reusable Methods9 New MethodsClass Conversation
1: Conversation()
Class Agent2: Agent()3: operator>>()4: Get()
Class Student5: Student()6: Extract()7: Get()
1
5
6
3
2
7
4
Use Case 1
October 2, 2006 (c) Dr. David A. Workman 11
Design Graph: 2
0: Main()
5 Reusable Methods9 New Methods
Class Conversation1: Conversation()8: Initialize()
Class Agent2: Agent()3: operator>>()4: Get()11: NameOf()21: ~Agent()
Class Student5: Student()6: Extract()7: Get()13: Initialize()16: AcceptQuest()
8
20
Class Players9: Players()12: setAgent()14: getAgent()15: getOther()20: ~Players()
Class Message10: Message()
9
2
12 13
11 14 15 16
Class SpeakMsg17: SpeakMsg()
17
10
Class Event18: Event()
18
Class EventMgr-3: EventMgr()19: postEvent()
19 21
Use Case 2
October 2, 2006 (c) Dr. David A. Workman 12
Design Graph: 3
0: Main()
Class Conversation1: Conversation()8: Initialize()22: Insert()
Class Agent2: Agent()3: operator>>()4: Get()11: NameOf()21: ~Agent()23: oper<<()26: Put()
Class Student5: Student()6: Extract()7: Get()13: Initialize()16: AcceptQuest()24: Insert()25: Put
Class Players9: Players()12: setAgent()14: getAgent()15: getOther()20: ~Players()
Class Message10: Message()
Class SpeakMsg17: SpeakMsg()
Class Event18: Event()
Class EventMgr-3: EventMgr()19: postEvent()
25
24
22
23
26
Use Case 3 2 Reusable Methods3 New Methods
October 2, 2006 (c) Dr. David A. Workman 13
Design Graph: 4
0: Main()
2
Class Conversation1: Conversation()8: Initialize()22: Insert()44: Simulate()
Class Agent2: Agent()3: operator>>()4: Get()11: NameOf()21: ~Agent()23: oper<<()26: Put()
Class Student5: Student()6: Extract()7: Get()13: Initialize()16: AcceptQuest()24: Insert()25: Put()37: Dispatch()39: doQuestion()40: AcceptAnswr()41: doAnswer()
Class Players9: Players()12: setAgent()14: getAgent()15: getOther()20: ~Players()
Class Message10: Message()30: Oper<<()31: Insert()32: Put()42: ~Message()
Class SpeakMsg17: SpeakMsg()33: Insert()34: Put()38: getHandlr()
Class Event18: Event()29: oper<<()35: getRecvr()36: getMsg()43: ~Event()
Class EventMgr-3: EventMgr()19: postEvent()27: moreEvents()28: getNextEvent()
17
27 28 29
23
24
25
26
30
32
3133
34
3635
40
3938
37
41
10
18 19
42
44
10 Reusable Methods8 New Methods
43
Use Case 4
October 2, 2006 (c) Dr. David A. Workman 14
Design Graph: 2
0: Main()
Class Conversation1: Conversation()8: Initialize()22: Insert()44: Simulate()45: WrapUp()46: ~Conversation()
Class Agent2: Agent()3: operator>>()4: Get()11: NameOf()21: ~Agent()23: oper<<()26: Put()
Class Student5: Student()6: Extract()7: Get()13: Initialize()16: AcceptQuest()24: Insert()25: Put()37: Dispatch()39: doQuestion()40: AcceptAnswr()41: doAnswer()47: ~Student()
Class Players9: Players()12: setAgent()14: getAgent()15: getOther()20: ~Players()
Class Message10: Message()30: Oper<<()31: Insert()32: Put()42: ~Message()
Class SpeakMsg17: SpeakMsg()33: Insert()34: Put()38: getHandlr()
Class EventMgr-3: EventMgr()19: postEvent()27: moreEvents()28: getNextEvent()48: ~EventMgr()
4645
47
Use Case 5Class Event18: Event()29: oper<<()35: getRecvr()36: getMsg()43: ~Event()
1 Reusable Methods3 New Methods
21 Reusable27 New----------------48
Total Methods
4 Reusable4 New---------------8
Total Classes
October 2, 2006 (c) Dr. David A. Workman 15
Scheduling
Development ScheduleUse Case 1
Use Case 3
Use Case 5
Use Case 4
Use Case 20: Main()
1
5
6 3
2
74
8
20
92 12
13
1114
15
161710
18
19
21 25 24 222326
17
27
28
29
23242526
30
32
31
3334
36
3540
39
38
3741
10
18
19
42
44
43
46
45
47
October 2, 2006 (c) Dr. David A. Workman 16
Money ClassMoney
Char signInt dollarsInt cents
Money(); Money(ifstream&); Money(char,int,int); getSign():char getDollars():int; getCents():int;operator-() :Money; operator-(Money):Money;operator+(Money):Money; operator==(Money):bool; operator<(Money):bool;operator>(Money):bool; operator<=(Money):bool; operator>=(Money):bool; Extract(ifstream&)=>TokenError Insert(ostream&);operator>>(ifstream&,Money&) operator<<(ostream&,Money&)#Get(ifstream&) #Put(ostream&);-toInt(Money):int-toMoney(int):Money
Money(fin)
Extract(fin)
Get(fin)
Money()
Money(char,int,int)getSign()
getDollars()
getCents()
booleanoperators()
*
binaryoperators()
toInt(Money) toMoney(int)
*
Insert(fout)
Put(fout)
operator>>(fin)
operator<<(fout)
TokenError
1
1
1
1
1
1 1
2
2
22
2
33
3
34
4
4 4
Initially make public
October 2, 2006 (c) Dr. David A. Workman 17
Money Class Test Driver 1#include "IOMgmt.h"using namespace IOMgmt;#include "Money.h"int main(){ InMgr finMgr("Enter Input File (Test1):"); ifstream& fin = finMgr.getStream(); OutMgr foutMgr("Enter Output File(Test1):"); ostream& fout = foutMgr.getStream(); int num_cases; char sign; int dollars, cents; fin >> num_cases; for(int I = 1; I <= num_cases; I++) { fin >> sign >> dollars >> cents; fout << "Case #" << num_cases – I + 1 << endl; fout << "Input Data: " << sign << dollars << cents << endl; Money M1(sign,dollars,cents); int M1cents = toInt(M1); Money M2 = toMoney(M1cents); char Sign = M2.getSign(); int Dollars = M2.getDollars(); int Cents = M2.getCents(); fout << "M1cents: " << M1cents << endl; fout << "Sign = " << Sign << ", Dollars= " << Dollars << ", Cents= " << Cents << endl; }//for}//main-1
October 2, 2006 (c) Dr. David A. Workman 18
Money Class Test Driver 2
#include "IOMgmt.h"using namespace IOMgmt;#include "Money.h"int main(){ InMgr finMgr("Enter Input File(Test2):"); ifstream& fin = finMgr.getStream(); OutMgr foutMgr("Enter Output File(Test2):"); ostream& fout = foutMgr.getStream(); int num_cases; char sign1, sign2; int dollars1, cents1, dollars2, cents2; fin >> num_cases; for(int I = 1; I <= num_cases; I++) { fin >> sign1 >> dollars1 >> cents1 >> sign2 >> dollars2 >> cents2; Money M1(sign1,dollars1,cents1), M2(sign2,dollars2,cents2); fout << "Case #" << I << endl; fout << "Input Data (M1): " << sign1 << dollars1 << cents1 << endl; fout << "Input Data (M2): " << sign2 << dollars2 << cents2 << endl; bool Reql, Rneq, Rless, Rgtr, Rleq, Rgeq; Reql = M1 == M2; Rneq = M1 != M2; Rless = M1 < M2; Rgtr = M1 > M2; Rleq = M1 <= M2; Rgeq = M1 >= M2; fout << "(==) " << Reql << " (!=) " << Rneq << //etc. Money Sum, Diff, Neg; Sum = M1 + M2; Diff = M1 – M2; Neg = -M1; fout << "Sum = " << Sum << ", Diff = " << Diff << ", Neg(M1) = " << Neg << endl; fout << "M1 = " << M1 << ", M2 = " << M2 << endl; }//for}//main-2
October 2, 2006 (c) Dr. David A. Workman 19
Money Class Test Driver 3#include "IOMgmt.h"using namespace IOMgmt;#include "Money.h"int main(){ InMgr finMgr("Enter Input File(Test3):"); ifstream& fin = finMgr.getStream(); OutMgr foutMgr("Enter Output File(Test3):"); ostream& fout = foutMgr.getStream(); int num_cases; fin >> num_cases; for(int I = 1; I <= num_cases; I++) { Money M; try{ fout << "Case# " << I; fin >> M; fout << ": Money = " << M << endl; }//try catch(TokenError &e){ fout << ": " << e.getMsg() << endl; }//catch }//for}//main-3
October 2, 2006 (c) Dr. David A. Workman 20
Testing Agent BehaviorsOnce the constructors, Insert, Put, Extract and Get methods have been written and tested, the way is clear to testsimulation initialization and execution behaviors. There are a couple of techniques that can be used to test specificEvents and consequently specific Agent behaviors.
class Conversation { //Virtual World public: Conversation(); ~Conversation(); void Initialize(); void Simulate(); void WrapUp(); void Put(); private int debugOption; //new simulation input paramter int numStudents; int numEvents; int lastEvent; AGENTPTR *students; //dynamic array of Agent* MSGPTR players; //pointer to Players message. void ExtractEvent(); //private method(s) for testing };//Conversation
October 2, 2006 (c) Dr. David A. Workman 21
Testing Agent Behaviors
Void Conversation::Conversation(){ //parses image of virtual world object, Conversation. //if debugOpt = ON, then it calls ExtractEvent()}
void Conversation::ExtractEvent(){ //private method of Conversation //Has visibility to any data the Conversation constructor can see. //Parses the desired image of Event(s) for debugging purposes // Posts the constructed Event(s) to theEventMgr.}
SimModels.cpp
October 2, 2006 (c) Dr. David A. Workman 22
Testing Agent Behaviorsclass Message {//concrete base class public: Message(int Handler,string Description); virtual ~Message() { } //destructor int getHandler() const { return handler;} //inspector friend ostream& operator<<(ostream &fout, Message &anyMsg) throw(IOError); friend ifstream& operator>>(ifstream& &fin, Message &anyMsg) throw(IOError, TokenError); //new protected: virtual void Insert(); virtual void Put (); virtual void Extract() throw(TokenError); //new virtual void Get() throw(TokenError); //new private: int handler; string description; };//Message
class SpeakMsg : public Message { // Inherits from Message public: SpeakMsg(int Handler, string Description, string Speak); ~SpeakMsg() { } string getContent() const { return content; } protected: virtual void Insert(); virtual void Put(); virtual void Extract() throw(TokenError); //reads default program input stream virtual void Get() throw(TokenError); //reads default program input stream private: string content; }; //SpeakMsg
October 2, 2006 (c) Dr. David A. Workman 23
Testing Agent BehaviorsConversation{ debugopt: OFF
#students: 2Student{ name: Betty
questdelay: 5 ansrdelay: 2}StudentStudent{ name: Bart
questdelay: 3 ansrdelay: 4}Student
}Conversation
Conversation{ debugopt: ON
#students: 2Student{ name: Betty
questdelay: 5 ansrdelay: 2}StudentStudent{ name: Bart
questdelay: 3 ansrdelay: 4}Student
debug{ #events: 1 Event{ time: ttt sendr: Bart recvr: Betty msg: SpeakMsg{ handler: 3 description: Testing content: How_Are_You? }SpeakMsg
}Event }debug}Conversation
Applications of theTheory Automata
and Regular Expressions
to Programmingand Software Testing
Presentation by
© Dr. David A. Workman
School of EE & CS
University of Central Florida
March 3, 2003
October 2, 2006 (c) Dr. David A. Workman 25
Outline
1. A Little History of Programming
2. A Little Review of Theory (COT 4210)
3. An Example Applying Theory to Practice
4. Summary and Conclusion
October 2, 2006 (c) Dr. David A. Workman 26
A Little History of Programming
• “Flow Diagram, turing machines and languages with only two formation rules.” by Bohm and Jacopini, CACM Vol. 9, No. 5 (May 1966)
Proved that all algorithms could be expressed using sequential execution assignment statements, conditional logic using if-then-else statements, and iteration using while statements.
• “Goto Statements considered harmful,” by Edsgar Dijkstra, CACM, Vol. 11, No. 3, March 1968, pp. 147-148.
– Contributions to the specification of ALGOL, 1957 – 60.– Cooperating Sequential Processes, 1966
– The THE Operating System, 1968
• ACM/A.M. Turing Award Citation, February 5, 1999: “Edsger Dijkstra was a principal contributor in the late 1950's to the development of the
ALGOL, a high level programming language which has become a model of clarity and mathematical rigor. He is one of the principal exponents of the science and art of programming languages in general, and has greatly contributed to our understanding of their structure, representation, and implementation. His fifteen years of publications extend from theoretical articles on graph theory to basic manuals, expository texts, and philosophical contemplations in the field of programming languages. “
October 2, 2006 (c) Dr. David A. Workman 27
A Little Review of Theory
Definition 1. A Deterministic Finite Automata (DFA) is a 5-tuple, M = (Q, Σ , δ , q0, A), where Q is a finite set of states, Σ denotes the input alphabet, q0 denotes the unique start state, A a finite, possibly empty set of Accept states, and the behavior of M is specified by its transition (computation) function δ : Q × Σ→ Q.
We typically specify the behavior of a DFA, its d function, in the form of a State Transition Diagram such as the one shown below as an example.
154
3
2
starta
b
a
a
a
a
b
b
bb
October 2, 2006 (c) Dr. David A. Workman 28
A Little Review of Theory
Definition 2. The Language Accepted by a DFA, is denoted L(M), and is given by
L(M) = { x ∈Σ* | δ ∗(q0, x) ∈ A }
where the function , δ∗ : Q × Σ * → Q, is an extension of the transition function to strings over the input alphabet.
What is L(M) for the DFA, M, given below???L(M) = { a, ab, abaaaaba, aaaaaaba, …. }
154
3
2
starta
b
a
a
a
a
b
b
bb
October 2, 2006 (c) Dr. David A. Workman 29
A Little More Theory
Definition 3. The Language of Regular Expression, E(Σ), over alphabet Σ , is the set of strings over alphabet Σ’ = Σ ∪ { λ , φ , + , ∗ , ⋅ , ( , ) } given by the inductive definition: Basis: Σ ∪ { λ , φ } ⊂ E(Σ) .Inductive Rules: assume e, f ∈ E(Σ), then each of the following is a member of E(Σ), [1] (e)*[2] (e ⋅ f)[3] (e + f)
Definition 4. The Language defined by Regular Expression, e, is denoted L[e] and is defined recursively below.Basis: L[φ] = Φ (the empty set), and for e ∈ Σ ∪ { λ }, L[e] = {e}.Inductive Rules: e, f, g ∈ E(Σ), [1] if e = (f)*, then L[e] = L[f]* (Kleene-star operation)[2] if e = (f ⋅ g), then L[e] = L[f]L[g] (Language concatenation)[3] if e = (f + g), then L[e] = L[f] ∪L[g] (Language union)
Example. E( {a,b} ) = {φ , λ , a, b, (φ)*, (λ)*, (a)*, (b)*, (φ ⋅ λ), (a ⋅a), (b ⋅ φ), (φ + λ), (a +a), (b +φ), … (((a(ba))+(φ)*)+(φ((φ+λ))*))… }
Example. L[ (((a(ba))+(φ)*)+(φ((φ+λ))*))] = {aba, λ}
October 2, 2006 (c) Dr. David A. Workman 30
A Little Review of Theory
• What is the significance (relevance) of DFAs (and their theory) ?• What is the significance of Regular Expressions (RE)?• How do these mathematical abstractions apply to programming?
SOME ANSWERS– DFAs are algorithmic abstractions– DFAs and REs can be used to model the lexical analysis function of real
compilers– DFA’s recognize Regular languages– RE’s also define Regular Languages
??? “Ho Hum, Yawn”
This could beYou!!!
October 2, 2006 (c) Dr. David A. Workman 31
Example Method (C++)
void Server::Work(){
ifstream input; // input file streamofstream output; // output file streamTray tray;cout << "McDonald's Implementation in C++" << endl;cout << "by XXXXXXXXXX and YYYYYYYYYYY" << endl;cout << endl;
while(1) {
string szInputFileName; cout << "Please enter the name of the input file: "; cin >> szInputFileName; input.open(szInputFileName.c_str()); if( !input ) alpha: { cerr << endl << "No file named " << szInputFileName << " found." << endl; } else break;}
} //Server::WorkInsert Segment A(from next slide
1
2
3
5
4
6
16
A Basic Block of code is a sequence of declaration,assignment, and method call statements, that mayoptionally end with a gotoor contional goto statement.
October 2, 2006 (c) Dr. David A. Workman 32
Example Method (C++)
FoodItems *pFood;
while(!input.eof()) { char szMarker[4]; input >> szMarker; strupper(szMarker); if(strcmp(szMarker, "$D") == 0) pFood = new Drinks; // drink else if(strcmp(szMarker, "$S") == 0) pFood = new Sandwiches; // sandwich else if(strcmp(szMarker, "") == 0) continue; // blank line; skip else throw InputException("Unknown type found " + string(szMarker)); pFood->Get(input); tray.Add_Item(pFood);} //while
Segment A
6
7
8
9 10
11 12
13
14
15
October 2, 2006 (c) Dr. David A. Workman 33
Example Method (C++)
1
2
86
53
10 15
12
17
Exceptionexit
Normalexit
Systemexit
9
11
1416
7
4
13
F
T
F
F
FF
T
TT
T
Notes: This is an example ofa program flow graph, the subject of Bohm and Jacopini’s theorem.
Even though this algorithm waswritten using a “structured style”, the flow graph is not completely structured in the purest sense since there are multiple method exits due to exceptions.
October 2, 2006 (c) Dr. David A. Workman 34
Example Method (C++)
1
2
86
53
10 15
12
Exceptionexit
Normalexit
9
11
14
16
7
4
13
F
T
F
F
F
F
T
TT
T
Note: We have modified the structured version to violate the principles of structured design ( 13 => 5 ).
To Re-Structure we apply the theory of DFAs and REs as follows:
(1) All conditional nodes become “states” in a DFA.(2) Transitions between states are labeled with the sequential computation thatconnects any pair of conditional nodes.(3) Unique transition sequences become “letters” in the DFA alphabet.
October 2, 2006 (c) Dr. David A. Workman 35
Example Method (C++)
a = 123b = (4T)523c = (4F)6d = (7T)8e = (9T)(10)(15)f = (9F)g = (11T)(12)(15)h = (11F)i = (13T523)j = (13F)k = (7F)
start
Exceptionexit
Normalexit
9 11 14
16
74 13
a
b
c
k
d
e
f
g
h j
i
E4 = a + E4b + E13iE7 = E4c + E9e + E11gE9 = E7dE11 = E9fE13 = E11hE14 = E13jE16 = E7k
Define the following “alphabet”
Set up a system of Regular Equations
Solution for Paths = E16 + E14
E16 = ab*c[d ( e + f (g + hib*c)) ]*kE14 = ab*c[d ( e + f (g + hib*c)) ]*dfhjPaths = ab*c[d ( e + f (g + hib*c)) ]* (k+dfhj)
October 2, 2006 (c) Dr. David A. Workman 36
Expression => Code
{ boolean X; 1;3; //a (2 = true) while( 4 ) { 5; 3 } //b* 6; //c X := true; // Boolean variable for exception handling while ( X and 7 ) { //7T 8; //d if( 9 ) { //9T 10; 15 //e } else { //9F = f if( 11 ) { //11T 12;15 //g else{ //h if( 13 ) { //13T 5; 3 //i while( 4 ) { 5; 3} //b* 6; //c = (4F)6 } else X = false; //13F = exception condition }//11 - else }//9 - else }// while(7 and X) if( not X ) throw(exception); //j = abnormal end } //k = normal end
Equivalent Structured Code
a = 123b = (4T)523c = (4F)6d = (7T)8e = (9T)(10)(15)f = (9F)g = (11T)(12)(15)h = (11F)i = (13T523)j = (13F)k = (7F)
Solution for Paths = E16 + E14
E16 = ab*c[d ( e + f (g + hib*c)) ]*kE14 = ab*c[d ( e + f (g + hib*c)) ]*dfhjPaths = ab*c[d ( e + f (g + hib*c)) ]* (k+dfhj)
October 2, 2006 (c) Dr. David A. Workman 37
Summary & Conclusion
• Summary (What are the main points?)– DFAs and REs are more than just (equivalent) mathematical specifications for
Regular Languages and algorithms for lexical analysis, they are useful for modeling algorithms of any kind and complexity.
– Using algorithms for equivalence between DFAs and REs we were able to see why Bohm and Jacopini’s theorem is true, and why Dijkstra so strongly endorced the principles of structured programming.
• Conclusion (What have we learned?) The “marriage” between Theory and Practice is not “on the rocks”, this couple is
not “legally separated” or “divorced” with “irreconcilable differences,” they are a harmonious couple, inextricably entwined, cooperating and complementing each other. What mathematics has brought together, let no computer scientist put asunder!
Applications of theTheory Automata
and Regular Expressions
to Programming
COT 4810: Topics in Computer Science
Spring 2003
Presentation by
© Dr. David A. Workman
School of EE & CS
University of Central Florida
March 3, 2003
October 2, 2006 (c) Dr. David A. Workman 39
Outline
1. A Little History of Programming
2. A Little Review of Theory (COT 4210)
3. An Example Applying Theory to Practice
4. Summary and Conclusion
October 2, 2006 (c) Dr. David A. Workman 40
A Little History of Programming
• “Flow Diagram, turing machines and languages with only two formation rules.” by Bohm and Jacopini, CACM Vol. 9, No. 5 (May 1966)
Proved that all algorithms could be expressed using sequential execution assignment statements, conditional logic using if-then-else statements, and iteration using while statements.
• “Goto Statements considered harmful,” by Edsgar Dijkstra, CACM, Vol. 11, No. 3, March 1968, pp. 147-148.
– Contributions to the specification of ALGOL, 1957 – 60.– Cooperating Sequential Processes, 1966
– The THE Operating System, 1968
• ACM/A.M. Turing Award Citation, February 5, 1999: “Edsger Dijkstra was a principal contributor in the late 1950's to the development of the
ALGOL, a high level programming language which has become a model of clarity and mathematical rigor. He is one of the principal exponents of the science and art of programming languages in general, and has greatly contributed to our understanding of their structure, representation, and implementation. His fifteen years of publications extend from theoretical articles on graph theory to basic manuals, expository texts, and philosophical contemplations in the field of programming languages. “
October 2, 2006 (c) Dr. David A. Workman 41
A Little Review of Theory
Definition 1. A Deterministic Finite Automata (DFA) is a 5-tuple, M = (Q, Σ , δ , q0, A), where Q is a finite set of states, Σ denotes the input alphabet, q0 denotes the unique start state, A a finite, possibly empty set of Accept states, and the behavior of M is specified by its transition (computation) function δ : Q × Σ→ Q.
We typically specify the behavior of a DFA, its d function, in the form of a State Transition Diagram such as the one shown below as an example.
154
3
2
starta
b
a
a
a
a
b
b
bb
October 2, 2006 (c) Dr. David A. Workman 42
A Little Review of Theory
Definition 2. The Language Accepted by a DFA, is denoted L(M), and is given by
L(M) = { x ∈Σ* | δ ∗(q0, x) ∈ A }
where the function , δ∗ : Q × Σ * → Q, is an extension of the transition function to strings over the input alphabet.
What is L(M) for the DFA, M, given below???L(M) = { a, ab, abaaaaba, aaaaaaba, …. }
154
3
2
starta
b
a
a
a
a
b
b
bb
October 2, 2006 (c) Dr. David A. Workman 43
A Little More Theory
Definition 3. The Language of Regular Expression, E(Σ), over alphabet Σ , is the set of strings over alphabet Σ’ = Σ ∪ { λ , φ , + , ∗ , ⋅ , ( , ) } given by the inductive definition: Basis: Σ ∪ { λ , φ } ⊂ E(Σ) .Inductive Rules: assume e, f ∈ E(Σ), then each of the following is a member of E(Σ), [1] (e)*[2] (e ⋅ f)[3] (e + f)
Definition 4. The Language defined by Regular Expression, e, is denoted L[e] and is defined recursively below.Basis: L[φ] = Φ (the empty set), and for e ∈ Σ ∪ { λ }, L[e] = {e}.Inductive Rules: e, f, g ∈ E(Σ), [1] if e = (f)*, then L[e] = L[f]* (Kleene-star operation)[2] if e = (f ⋅ g), then L[e] = L[f]L[g] (Language concatenation)[3] if e = (f + g), then L[e] = L[f] ∪L[g] (Language union)
Example. E( {a,b} ) = {φ , λ , a, b, (φ)*, (λ)*, (a)*, (b)*, (φ ⋅ λ), (a ⋅a), (b ⋅ φ), (φ + λ), (a +a), (b +φ), … (((a(ba))+(φ)*)+(φ((φ+λ))*))… }
Example. L[ (((a(ba))+(φ)*)+(φ((φ+λ))*))] = {aba, λ}
October 2, 2006 (c) Dr. David A. Workman 44
A Little Review of Theory
• What is the significance (relevance) of DFAs (and their theory) ?• What is the significance of Regular Expressions (RE)?• How do these mathematical abstractions apply to programming?
SOME ANSWERS– DFAs are algorithmic abstractions– DFAs and REs can be used to model the lexical analysis function of real
compilers– DFA’s recognize Regular languages– RE’s also define Regular Languages
??? “Ho Hum, Yawn”
This could beYou!!!
October 2, 2006 (c) Dr. David A. Workman 45
Example Method (C++)
void Server::Work(){
ifstream input; // input file streamofstream output; // output file streamTray tray;cout << "McDonald's Implementation in C++" << endl;cout << "by XXXXXXXXXX and YYYYYYYYYYY" << endl;cout << endl;
while(1) {
string szInputFileName; cout << "Please enter the name of the input file: "; cin >> szInputFileName; input.open(szInputFileName.c_str()); if( !input ) alpha: { cerr << endl << "No file named " << szInputFileName << " found." << endl; } else break;}
} //Server::WorkInsert Segment A(from next slide
1
2
3
5
4
6
16
A Basic Block of code is a sequence of declaration,assignment, and method call statements, that mayoptionally end with a gotoor contional goto statement.
October 2, 2006 (c) Dr. David A. Workman 46
Example Method (C++)
FoodItems *pFood;
while(!input.eof()) { char szMarker[4]; input >> szMarker; strupper(szMarker); if(strcmp(szMarker, "$D") == 0) pFood = new Drinks; // drink else if(strcmp(szMarker, "$S") == 0) pFood = new Sandwiches; // sandwich else if(strcmp(szMarker, "") == 0) continue; // blank line; skip else throw InputException("Unknown type found " + string(szMarker)); pFood->Get(input); tray.Add_Item(pFood);} //while
Segment A
6
7
8
9 10
11 12
13
14
15
October 2, 2006 (c) Dr. David A. Workman 47
Example Method (C++)
1
2
86
53
10 15
12
17
Exceptionexit
Normalexit
Systemexit
9
11
1416
7
4
13
F
T
F
F
FF
T
TT
T
Notes: This is an example ofa program flow graph, the subject of Bohm and Jacopini’s theorem.
Even though this algorithm waswritten using a “structured style”, the flow graph is not completely structured in the purest sense since there are multiple method exits due to exceptions.
October 2, 2006 (c) Dr. David A. Workman 48
Example Method (C++)
1
2
86
53
10 15
12
Exceptionexit
Normalexit
9
11
14
16
7
4
13
F
T
F
F
F
F
T
TT
T
Notes: We have modified the structure version to make it violate the principles of structured design ( 13 => 5 ).
To Re-Structure we apply the theory of DFAs and REs as follows:
(1) All conditional nodes become “states” in a DFA.(2) Transitions between states are labeled with the sequential computation thatconnects any pair of conditional nodes.(3) Unique transition sequences become “letters” in the DFA alphabet.
October 2, 2006 (c) Dr. David A. Workman 49
Example Method (C++)
a = 123b = (4T)523c = (4F)6d = (7T)8e = (9T)(10)(15)f = (9F)g = (11T)(12)(15)h = (11F)i = (13T523)j = (13F)k = (7F)
start
Exceptionexit
Normalexit
9 11 14
16
74 13
a
b
c
k
d
e
f
g
h j
i
E4 = a + E4b + E13iE7 = E4c + E9e + E11gE9 = E7dE11 = E9fE13 = E11hE14 = E13jE16 = E7k
Define the following “alphabet”
Set up a system of Regular Equations
Solution for Paths = E16 + E14
E16 = ab*c[d ( e + f (g + hib*c)) ]*kE14 = ab*c[d ( e + f (g + hib*c)) ]*dfhjPaths = ab*c[d ( e + f (g + hib*c)) ]* (k+dfhj)
October 2, 2006 (c) Dr. David A. Workman 50
Expression => Code
{ boolean X; 1;3; //a (2 = true) while( 4 ) { 5; 3 } //b* 6; //c X := true; // Boolean variable for exception handling while ( X and 7 ) { //7T 8; //d if( 9 ) { //9T 10; 15 //e } else { //9F = f if( 11 ) { //11T 12;15 //g else{ //h if( 13 ) { //13T 5; 3 //i while( 4 ) { 5; 3} //b* 6; //c = (4F)6 } else X = false; //13F = exception condition }//11 - else }//9 - else }// while(7 and X) if( not X ) throw(exception); //j = abnormal end } //k = normal end
Equivalent Structured Code
a = 123b = (4T)523c = (4F)6d = (7T)8e = (9T)(10)(15)f = (9F)g = (11T)(12)(15)h = (11F)i = (13T523)j = (13F)k = (7F)
Solution for Paths = E16 + E14
E16 = ab*c[d ( e + f (g + hib*c)) ]*kE14 = ab*c[d ( e + f (g + hib*c)) ]*dfhjPaths = ab*c[d ( e + f (g + hib*c)) ]* (k+dfhj)
October 2, 2006 (c) Dr. David A. Workman 51
Summary & Conclusion
• Summary (What are the main points?)– DFAs and REs are more than just (equivalent) mathematical specifications for
Regular Languages and algorithms for lexical analysis, they are useful for modeling algorithms of any kind and complexity.
– Using algorithms for equivalence between DFAs and REs we were able to see why Bohm and Jacopini’s theorem is true, and why Dijkstra so strongly endorced the principles of structured programming.
• Conclusion (What have we learned?) The “marriage” between Theory and Practice is not “on the rocks”, this couple is
not “legally separated” or “divorced” with “irreconcilable differences,” they are a harmonious couple, inextricably entwined, cooperating and complementing each other. What mathematics has brought together, let no computer scientist put asunder!
Recommended