COSC3311 – Software Design Tuples and Agents 12/9/2018 1:48 AM Object Oriented Software Construction 09/12/2018 1:48 AM 0
Why agents? c: CITIZEN p: CITIZEN | p c.parents c p.children b my_function (x) dx a c: CITIZEN p: CITIZEN | p c.parents c p.children GUI Callback: your_button. click_actions.extend(agent your_routine) Object Oriented Software Construction 09/12/2018 1:48 AM 1
Agents 2 Operations (routines) are not objects object technology starts from the decision to separate these two aspects, and to choose object types (data), rather than the operations, as the basis for modular organization of a system, attaching each operation to the resulting modules -- the classes. But, in a number of applications, we may need objects that represent operations, so that we can store operations in object structures and execute them later This is similar to the notion of a function pointer in C, but it must be translated to the OO paradigm. Object Oriented Software Construction 09/12/2018 1:48 AM 2
12/9/2018 1:48 AM Tuples vs Array The generic array ARRAY[G] represents a sequence of elements, all of the same type. e.g. a: ARRAY[INTEGER] a := <<2, 4, 6, 8>> All elements are of the same (or conforming) type A typical tuple type is of the form TUPLE[X,Y,Z] denoting a tuple of at least three elements, such that the type of the first conforms to X , the second to Y, and the third to Z . Object Oriented Software Construction 09/12/2018 1:48 AM 3
12/9/2018 1:48 AM What is a tuple? Analogous to describing the types for the fields of a record Example of a 5 field record with sufficient space in each field to hold items of the indicated type TUPLE [ INTEGER , CHARACTER , BOOLEAN , ARRAY[TIGERS] , STACK[ELEPHANTS] ] Object Oriented Software Construction 09/12/2018 1:48 AM 4
12/9/2018 1:48 AM Tuple You may list any number of types in square brackets, including none at all. TUPLE, with no types in square brackets, denotes tuples of arbitrary length. TUPLE is an already defined class. Object Oriented Software Construction 09/12/2018 1:48 AM 5
Tuple classes Syntax: TUPLE [X, Y, …] TUPLE TUPLE [A] TUPLE [A, B] 12/9/2018 1:48 AM Tuple classes Syntax: TUPLE [X, Y, …] TUPLE TUPLE [A] TUPLE [A, B] Object Oriented Software Construction 09/12/2018 1:48 AM 6
Contract view of TUPLE class TUPLE feature count: INTEGER 12/9/2018 1:48 AM Contract view of TUPLE class TUPLE feature count: INTEGER -- number of fields in the tuple item (index: INTEGER): ANY -- Entry of key `index'. require valid_index: valid_index (index) put (v: ANY; index: INTEGER) -- Insert `v' at position `index'. valid_index (index) valid_type_for_index (v, index) end Object Oriented Software Construction 09/12/2018 1:48 AM 7
12/9/2018 1:48 AM Infix operators item alias "[]", infix "@" (index: INTEGER): ANY assign put is require valid_index: valid_index (index) Use either item or @ or [] for accessing an entry in the tuple Object Oriented Software Construction 09/12/2018 1:48 AM 8
TUPLE[BOOLEAN, INTEGER, STRING] 12/9/2018 1:48 AM TUPLE[BOOLEAN, INTEGER, STRING] test_three_tuple: BOOLEAN local t3: TUPLE[BOOLEAN, INTEGER, STRING] do comment("test_three_tuple") t3 := [False, 342, "Bzttt!"] Result := t3[1] = False and t3[2] = 342 and t3[3] ~ "Bzttt!" end Object Oriented Software Construction 09/12/2018 1:48 AM 9
Debugger view of the TUPLE[X,Y,Z] 12/9/2018 1:48 AM Debugger view of the TUPLE[X,Y,Z] Object Oriented Software Construction 09/12/2018 1:48 AM 10
Integer Division as a Tuple 12/9/2018 1:48 AM Integer Division as a Tuple div (b, c: INTEGER): TUPLE [INTEGER, INTEGER] is -- illustration of multi-functions -- (two return values) using tuples -- b divided by c yields quotient q and remainder r require c /= 0 local r, q: INTEGER do q := b // c r := b \\ c Result := [q, r] end Object Oriented Software Construction 09/12/2018 1:48 AM 11
Test div test_integer_divison: BOOLEAN is 12/9/2018 1:48 AM Test div test_integer_divison: BOOLEAN is -- Calculate 23/4, i.e. 23 = 5*4 + 3 local t2: TUPLE[INTEGER, INTEGER] do t2 := div (23, 4) Result := t2[1] = 5 and t2[2] = 3 end Object Oriented Software Construction 09/12/2018 1:48 AM 12
Accessing TUPLE fields 12/9/2018 1:48 AM Accessing TUPLE fields class FOO[G] create make feature make(a_t: TUPLE[g:G]) do item1 := a_t.g -- first way item2 ?= a_t[1] -- second way: type safe assignment attempt if item2 /= Void then print(item2.out) end item1: G item2: G Void safe version: Object Oriented Software Construction 09/12/2018 1:48 AM 13
Agents Operations (i.e. routines) are not objects 12/9/2018 1:48 AM Agents Operations (i.e. routines) are not objects object technology starts from the decision to separate these two aspects, and to choose object types, rather than the operations, as the basis for modular organization of a system, attaching each operation to the resulting modules -- the classes. In a number of applications, however, we may need objects that represent operations, so that we can include them in object structures that some other routine can call later. Object Oriented Software Construction 09/12/2018 1:48 AM 14
Function routine do_something in class A 12/9/2018 1:48 AM Function routine do_something in class A class A feature do_something (flag: BOOLEAN; x: INTEGER) : INTEGER -- Return 1000*x if `flag’ holds do if flag then Result := x * 1000 end Object Oriented Software Construction 09/12/2018 1:48 AM 15
Function do_something as a type 12/9/2018 1:48 AM Function do_something as a type test_function_do_something: BOOLEAN is local a: A f: FUNCTION[A,TUPLE[INTEGER],INTEGER] do create a f := agent a.do_something(true, ?) -- above is not executed until f.call([123]) Result := f.last_result = 123000 end Transform function do_something into an agent expression do_something is a function in class A with arguments TUPLE[INTEGER] and return type INTEGER Like a function pointer in C but with type safety and open and closed arguments. === http://publications.gbdirect.co.uk/c_book/chapter5/function_pointers.html Pointers to functions. A useful technique is the ability to have pointers to functions. Their declaration is easy: write the declaration as it would be for the function, say int func(int a, float b); and simply put brackets around the name and a * in front of it: that declares the pointer. Because of precedence, if you don't parenthesize the name, you declare a function returning a pointer: /* function returning pointer to int */ int *func(int a, float b); /* pointer to function returning int */ int (*func)(int a, float b); Once you've got the pointer, you can assign the address of the right sort of function just by using its name: like an array, a function name is turned into an address when it's used in an expression. You can call the function using one of two forms: (*func)(1,2); /* or */ func(1,2); The second form has been newly blessed by the Standard. Here's a simple example. #include <stdio.h> #include <stdlib.h> void func(int); main(){ void (*fp)(int); fp = func; (*fp)(1); fp(2); exit(EXIT_SUCCESS); } void func(int arg){ printf("%d\n", arg); } Example 5.16 If you like writing finite state machines, you might like to know that you can have an array of pointers to functions, with declaration and use like this: void (*fparr[])(int, float) = { /* initializers */ }; /* then call one */ fparr[5](1, 3.4); This email was cleaned by emailStripper, available for free from http://www.papercut.biz/emailStripper.htm Object Oriented Software Construction 09/12/2018 1:48 AM 16
Closed and Open arguments 12/9/2018 1:48 AM Closed and Open arguments f := agent a.do_something( true, ? ) Object Oriented Software Construction 09/12/2018 1:48 AM 17
Function routine as an anonymous type 12/9/2018 1:48 AM Function routine as an anonymous type f: FUNCTION[A,TUPLE[INTEGER],INTEGER] f is a function in class A with argument TUPLE[INTEGER] and return type INTEGER do_something (flag: BOOLEAN; x: INTEGER) : INTEGER is -- Return 1000*x do if flag then Result := x * 1000 end end Object Oriented Software Construction 09/12/2018 1:48 AM 18
What must X be to make the test work? 12/9/2018 1:48 AM What must X be to make the test work? f: FUNCTION[A,TUPLE[INTEGER],INTEGER] f := agent a.do_something(false, ?) f.call([123]) Result := f.last_result = X ?? = 0 Object Oriented Software Construction 09/12/2018 1:48 AM 19
Reminder: constrained genericity 12/9/2018 1:48 AM Reminder: constrained genericity LIST [G] (unconstrained): G represents arbitrary type. May use LIST [INTEGER] LIST [EMPLOYEE] LIST [SHIP] SORTABLE_LIST [G -> COMPARABLE] (constrained by COMPARABLE) G represents type descending from COMPARABLE LIST [INTEGER] LIST [T] only if T descendant of COMPARABLE Object Oriented Software Construction 09/12/2018 1:48 AM 20
Agent types: Kernel library classes 12/9/2018 1:48 AM Agent types: Kernel library classes Inherits from ROUTINE* [BASE, ARGS -> TUPLE] call Deferred * item PROCEDURE [BASE, ARGS -> TUPLE] FUNCTION [BASE, ARGS -> TUPLE, RES] Object Oriented Software Construction 09/12/2018 1:48 AM 21
FUNCTION[BASE, ARGS, RESULT_TYPE] 12/9/2018 1:48 AM FUNCTION[BASE, ARGS, RESULT_TYPE] call (args: OPEN_ARGS) is -- Call routine with operands `args'. require valid_operands (args) do … end last_result: RESULT_TYPE -- Result of last call, if any item (args: OPEN_ARGS): RESULT_TYPE -- Result of calling function with `args' -- Does call then sets last_result as a side effect Object Oriented Software Construction 09/12/2018 1:48 AM 22
Features of routine classes 12/9/2018 1:48 AM Features of routine classes call (values: ARGS) item (values: ARGS): RES -- In FUNCTION only ... target, arguments, set_target, set_arguments... Introspection features (in progress): precondition: FUNCTION [BASE, ARGUMENTS, BOOLEAN] postcondition type: TYPE Features of class TYPE: heirs, parents, routines etc. Object Oriented Software Construction 09/12/2018 1:48 AM 23
Keeping arguments open 12/9/2018 1:48 AM Keeping arguments open An agent can have both “closed” and “open” arguments. Closed arguments set at time of agent definition; open arguments set at time of each call. To keep an argument open, just replace it by a question mark: u := agent a0.f (a1, a2, a3) -- All closed (as before) w := agent a0.f (a1, a2, ?) x := agent a0.f (a1, ?, a3) y := agent a0.f (a1, ?, ?) z := agent a0.f (?, ?, ?) Object Oriented Software Construction 09/12/2018 1:48 AM 24
Agent types -- in class C Reminder: PROCEDURE [BASE, ARGS –> TUPLE] 12/9/2018 1:48 AM Agent types Reminder: PROCEDURE [BASE, ARGS –> TUPLE] a0: C having feature f f (x1: T1; x2: T2; x3: T3) -- in class C do ... end agent a0.f (a1, a2, a3) PROCEDURE [C, TUPLE] -- All closed agent a0.f (a1, a2, ?) PROCEDURE [C, TUPLE [T3]] agent a0.f (a1, ?, a3) PROCEDURE [C, TUPLE [T2]] agent a0.f (a1, ?, ?) PROCEDURE [C, TUPLE [T2, T3]] agent a0.f (?, ?, ?) PROCEDURE [C, TUPLE [T1, T2, T3]] Object Oriented Software Construction 09/12/2018 1:48 AM 25
Calling an agent a0: C; a1: T1; a2: T2; a3: T3 12/9/2018 1:48 AM Calling an agent a0: C; a1: T1; a2: T2; a3: T3 u :=agent a0.f (a1, a2, a3) PROCEDURE [C, TUPLE] u.call ([]) v := agent a0.f (a1, a2, ?) PROCEDURE [C, TUPLE [T3]] v.call ([a3]) w := agent a0.f (a1, ?, a3) PROCEDURE [C, TUPLE [T2]] w.call ([a2]) x := agent a0.f (a1, ?, ?) PROCEDURE [C, TUPLE [T2, T3]] x.call ([a2, a3]) y := agent a0.f (?, ?, ?) PROCEDURE [C, TUPLE [T1, T2, T3]] y.call ([a1, a2, a3]) Object Oriented Software Construction 09/12/2018 1:48 AM 26
Calling an agent: integration example b my_function (x) dx a your_function (x, u, v) dx my_integrator.integral (agent my_function(?), a, b) my_integrator.integral (agent your_function (?, u, v), a, b) Object Oriented Software Construction 09/12/2018 1:48 AM 27
12/9/2018 1:48 AM The integral function integral (f: FUN [ANY, TUPLE [REAL], REAL]; low, high: REAL): REAL -- Integral of f over the interval [low, high] local x: REAL do from x := low until x > high loop Result := Result + f.item ([x]) * step x := x + step end step: REAL f: FUNCTION [ANY, TUPLE [REAL], REAL]; Object Oriented Software Construction 09/12/2018 1:48 AM 28
Calling an agent: iterator 12/9/2018 1:48 AM Calling an agent: iterator integer_list: LIST[INTEGER] employee_list: LIST[EMPLOYEE] all_positive, all_married: BOOLEAN all_positive := integer_list.for_all (agent is_positive (?)) all_married := employee_list.for_all (agent {EMPLOYEE}.is_married) Object Oriented Software Construction 09/12/2018 1:48 AM 29
12/9/2018 1:48 AM Iterators In class LINEAR [G], ancestor to all classes representing lists, sequences etc. item: G -- Item at current position for_all (test: FUNCTION [ANY, TUPLE [G], BOOLEAN]): BOOL -- Do all items satisfy test? do from start Result := True until off or not Result loop Result := test.item ([item]) forth end end Where does [item] come from: class LINEAR[G] feature item: G after: BOOLEAN start, forth … end Object Oriented Software Construction 09/12/2018 1:48 AM 30
Iterators (cont’d) for_all there_exists do_all do_if do_while do_until 12/9/2018 1:48 AM Iterators (cont’d) for_all there_exists do_all do_if do_while do_until Object Oriented Software Construction 09/12/2018 1:48 AM 31
Keeping the target open 12/9/2018 1:48 AM Keeping the target open r := agent {T0}.f (a1, a2, a3) -- Target open, arguments closed Type is: PROCEDURE [T0, TUPLE [T0]] Example call: r.call ([a0]) s := agent {T0}.f (?, ?, ?) -- Open on all operands -- Can also be written as just: agent {T0}.f Type is: PROCEDURE [T0, TUPLE [T0, T1, T2, T3]] Example call: s.call ([a0, a1, a2, a3]) Object Oriented Software Construction 09/12/2018 1:48 AM 32
Advanced Info about Tuples & Agentss 12/9/2018 1:48 AM Advanced Info about Tuples & Agentss For more details on tuples and agents see https://wiki.cse.yorku.ca/project/eiffel/resources Object Oriented Software Construction 09/12/2018 1:48 AM 33
BON: http://www.bon-method.com Object Oriented Software Construction 09/12/2018 1:48 AM 34
Event-B Ascii (see slides svn) 12/9/2018 1:48 AM Event-B Ascii (see slides svn) For comments Object Oriented Software Construction 09/12/2018 1:48 AM 35
Predicate Logic and Set Theory 12/9/2018 1:48 AM Predicate Logic and Set Theory The following formulas are all legitimate BON expressions See BON book for more examples Object Oriented Software Construction 09/12/2018 1:48 AM 36
bon-method.com: BON book 57 Object Oriented Software Construction 09/12/2018 1:48 AM 37
Textual notation ! r: REAL . (1 <= r <= 10) => (r + 1 > 10) This can be embedded informally as a comment in a pre or post condition Agents can help us to make contracts testable at runtime Object Oriented Software Construction 09/12/2018 1:48 AM 38
test0: BOOLEAN local a: ARRAY[STRING] do a := <<"hello", "hell", "help">> Result := a.for_all (agent {STRING}.has_substring ("hel")) check Result end Result := not a.for_all (agent {STRING}.has_substring ("hell")) end Object Oriented Software Construction 09/12/2018 1:48 AM 39
BON Static Diagram 12/9/2018 1:48 AM Client supplier association or reference type (like a UML association) aggregation or expanded type (UML composition) Object Oriented Software Construction 09/12/2018 1:48 AM 40
BON static diagram Object Oriented Software Construction 09/12/2018 1:48 AM 41
First test for SORTABLE_ARRAY 12/9/2018 1:48 AM First test for SORTABLE_ARRAY test_sort: BOOLEAN is local a: SORTABLE_ARRAY[REAL] do create a.make(1,3) a.put(30.0, 1) a.put(10.0,2) a.put(20.0,3) Result := not a.sorted check Result end a.sort Result := a[1] = 10 and a[2] = 20 and a[3] = 30 check Result end Result := a.sorted end Object Oriented Software Construction 09/12/2018 1:48 AM 42
Quantified Contracts a: ARRAY[REAL] 12/9/2018 1:48 AM Quantified Contracts a: ARRAY[REAL] Result := a.for_all (agent greater_than_ten (?)) First math predicate cannot be done easily using ARRAY.for)all Second one can be done easily as shown in agent expression agent {REAL}.is_positive Object Oriented Software Construction 09/12/2018 1:48 AM 43
ARRAY.for_all for_all (predicate: FUNCTION [ANY, TUPLE [G], BOOLEAN]): BOOLEAN is -- Is `test' true for all items in array? do …. end Object Oriented Software Construction 09/12/2018 1:48 AM 44
Quantifiers using agents 12/9/2018 1:48 AM Quantifiers using agents test_quantifiers: BOOLEAN is local a: ARRAY [REAL] do a := << 10.0, 13.6, 22.4 >> Result := a.for_all (agent greater_than_ten (?)) end greater_than_ten (x: REAL): BOOLEAN is -- Is `x' >10? Result := x > 10 Object Oriented Software Construction 09/12/2018 1:48 AM 45
ARRAY.for_all for_all (predicate: FUNCTION [ANY, TUPLE [G], BOOLEAN]): BOOLEAN is -- Is `test' true for all items in array? do …. end Problem: Can we do Object Oriented Software Construction 09/12/2018 1:48 AM 46
Providing SORTABLE_ARRAY with quantifiers We will use the counting quantifier Object Oriented Software Construction 09/12/2018 1:48 AM 47
12/9/2018 1:48 AM Counting Quantifier is an INTEGER that denotes the number of different values in the range [m .. n] for which P(i) is true (note that is of type BOOLEAN). Object Oriented Software Construction 09/12/2018 1:48 AM 48
Example The number of even numbers in the range [2 .. 6] is three Object Oriented Software Construction 09/12/2018 1:48 AM 49
for_all and there_exists 12/9/2018 1:48 AM for_all and there_exists In terms of counting quantifier, can express for_all there_exists How? Object Oriented Software Construction 09/12/2018 1:48 AM 50
SORTABLE_ARRAY.hold_count 12/9/2018 1:48 AM SORTABLE_ARRAY.hold_count hold_count (predicate: FUNCTION [ANY, TUPLE [INTEGER], BOOLEAN]): INTEGER -- Number of values between `data.lower' and -- `data.upper‘ that satisfy `predicate' local i: INTEGER; do from i := lower; until i > upper loop if predicate.item([i]) then Result := Result + 1 end i := i + 1 Object Oriented Software Construction 09/12/2018 1:48 AM 51
for_all_index (test: FUNCTION[ANY,TUPLE[INTEGER], BOOLEAN]): BOOLEAN -- does `test' hold for all indices? require test_exits: test /= void do Result := (hold_count (test) = count) ensure Result = (hold_count (test) = count) end Object Oriented Software Construction 09/12/2018 1:48 AM 52
there_exists_index (test: FUNCTION[ANY,TUPLE[INTEGER], BOOLEAN]): BOOLEAN -- does `test' hold for at least one index? require test_exits: test /= void do Result := (hold_count (test) > 0) ensure Result = (hold_count (test) > 0) end Object Oriented Software Construction 09/12/2018 1:48 AM 53
sorted data: ARRAY [G] -- is `data' sorted? do 12/9/2018 1:48 AM sorted sorted: BOOLEAN is -- is `data' sorted? do Result := for_all (agent less_than_next(?)) ensure data_sorted: Result = for_all (agent less_than_next(?)) end data: ARRAY [G] less_than_next (i: INTEGER):BOOLEAN is -- Is item[i] <= item[i+1] require valid_index (i) if i = upper then Result := true else Result := item(i) <= item(i+1) Object Oriented Software Construction 09/12/2018 1:48 AM 54
Homework Do sortablearray in code directory Implement hold_count, for_all, there_exists and the sorted contract Object Oriented Software Construction 09/12/2018 1:48 AM 55