System and method for programming using independent and reusable software units6851104Abstract A programming implementation providing support for reusable software units built in a hierarchical and modular form. The implementation includes a repository of the reusable software units, where each are arranged to behave independently, communicate transparently, and facilitate creation of new reusable software units. Claims What is claimed is: Description BACKGROUND OF THE INVENTION
value := 0.
for i := 1 to (valueList size) do
value := value + valueList[i]
endFor
return(value)
In the current implementation, if no output function is defined, the following default function, named .phi., is used defaultOutputFunction(valueList)
if (valueList size = 0)
return(nil)
else
sz := valueList size
return(valueList[sz] )
endIf
This function just returns nil if no channel links to a gate and returns the last value from the input list, if there is at least one channel. This behavior seems to cover the most common situations and it seems to be preferable to just return a list of values. IX. The OR Connecton FIG. 2 represents an OR connecton 202. This connecton has one input gate called out 204, and two output gates called in1206 and in2208. The input gate corresponds to an action (method) defined in the connecton. The output gates correspond to request for actions (message calls) that a connecton can send to its peers. The OR connecton has no internal state and computes the logical Or of the values present at output gates in1 and in2. This connecton is described by OR=({out}, {(.O slashed.,B)}, {a.sub.out }, {(in1,in2}), {.O slashed.,B),(.O slashed.,B)}) where B={0,1} is the set of Boolean values, and .O slashed. represents that no value is needed. The output function is omitted for no adaptation is needed. When the OR element receives a message on gate out, it asks for two values through gates in1 and in2 and returns the logical Or of these two values. We describe now the implementation in the DEMOS system, a Smalltalk implementation of the Connecton paradigm. The OR connecton has two actions (methods): inGates and outGates, that define, respectively, input and output gates. inGates ^super inGates add: #out. outGates ^super outGates add: #in1; add: #in2. The code for action out that computes the logical Or is given by out
.vertline.a b.vertline.
a := out in1. "Obtain the value at gate in1"
b := out in2. "Obtain the value at gate in2"
a.vertline.b "Returns the logical Or"
As mentioned before, the access to outside connectons is achieved by the use of the pseudo-variable out. The name of the output gates provides just an alias to access the gates of other connectons. There is also no need for a connecton to know the names of other connecton actions, i.e., their input gates. The pseudo variable out and the gate concept permit to define the OR connecton without any reference to other connectons. X. Bank Account Example We describe now, in more detail, the bank account example used in a previous section. FIG. 3 represents the client connecton 302 that receives in the output gate deposit: 304 the values deposited in bank accounts B1, B2 and B3 at respective connectons 308, 310, 312. The connectons 308, 310, 312 have respective value gates 314, 316 and 318 that are linked to the client connecton via respective channels or links 320, 322, 324. The client is described by C=({value}, {(.O slashed.,R)}, {a.sub.value }, {deposit:}, {(Names,R)}, {ouputFunction.sub.deposit: }) where Names is the set of client names (not defined here for simplicity). Output gates and the respective output function are defined by the method outGates given by ^super outGates add: #deposit: function: [:x.vertline.x inject: 0 into:[:a :b.vertline. a+b]] Gate deposit: is attached to an output function described in Smalltalk by the block: [:x.vertline. x inject: 0 into: [:a :b.vertline. a+b]]. This block converts the input list into a single value (the sum of values in the list). This function also provides the default value 0 if no channel is connected to gate deposit. The action associated with input gate value 306 is defined by value ^out deposit: myself where myself represents the bank customer. XI. Network of Connectons A connecton network, or connecton ensemble, is a complex connecton built by the composition of other connectons. It is defined by E=(inGates, {inSign.sub.g },.epsilon.,M.sub.g, outGates, {outSign.sub.gt }, {outFunction.sub.gt }) This definition introduces the ensemble (network) executive .epsilon., and its model M.sub.g, a special connecton that maintains the ensemble structure. The executive keeps a list of the connectons that compose the ensemble and also keeps a list of the channels existing among connectons. This information is not static, and can be changed by executive actions. The executive is defined by M.sub.g =(inGates,{inSign.sub.g },{a.sub.g },.sigma.,.SIGMA.*,Q,q.sub.0,outGates,{outSign.sub.gt },{outFunction.sub.gt }) A special function is defined in the executive that maps the executive state into an ensemble structure. The structure function is expressed by .sigma.: Q.fwdarw..SIGMA.* Each structure .SIGMA. in .SIGMA.* is given by .SIGMA.={C,{M.sub.c },L,.XI.) where C is the set of connectons that belong to the ensemble, M.sub.c is the model (definition) of each connecton c belonging to set C, L is a set of channels and .XI. is the order function. A channel is a 3-tuple defined by ((i,g.sub.i), (j,g.sub.j),(dF,rF)), where i is the name of the source connecton, g.sub.i is a gate of the i connecton, j is the receiver connecton, g.sub.j is a gate of j, dF is the channel direct filter, and rF is the channel reverse filter. When absent, dF and rF are assumed to be the identity function. The identity function IDY, is a function that just yields the input parameter. It is given by IDY(x)=x. When value a x is sent from gate g.sub.i to gate g.sub.j by a channel with filter (dF,rF), connecton j performs j a.sub.gj dF(x) and returns the value rF(j a.sub.gj dF(x)), being the action executed only once. In the previous statements we assume the Smalltalk syntax for message calls given by: object message arguments, where the arguments are omitted if the message needs no parameters. Filters transform both the values sent and received by a connecton. For example if a connecton works with values in Miles and needs to communicate with connectons operating in Km, then filtering capabilities provide an elegant solution to make this conversion without the creation of additional connectons to make the adaptation. In this case the direct filter would be given by df(x)=1.65x, and the reverse filter would be given by rF(x)=x/1.65 to make the conversions between Miles and Km. .XI.: L.sup.+.fwdarw.L.sup.+ is the order function, where L.sup.+ is the set of all sets of links (excluding the empty sequence). The order function establishes the order of the outside calls when several channels are linked from the same output gate. For simplicity, we omit reference to this function for the remainder herein by assuming a non-deterministic order. The initial structure of the ensemble .SIGMA..sub.o is given by .SIGMA..sub.o =a(q.sub.0), where q.sub.0 is the executive initial state. XII. Random Logic Application FIG. 4 represents an ensemble with three connectons 202, 404 and 406, and the executive 408. The ensemble is defined by M.sub.ORTest =(inGates,{inSign.sub.g },.epsilon., M.sub..epsilon.) where inGates={in1:,in2:,out} inSign={(B, .O slashed.),(B, .O slashed.),(.O slashed.,B)} M.sub..epsilon. =({q.sub.0,.epsilon.},q.sub.0,.epsilon.,.sigma.,.SIGMA.*). The executive has just one state that corresponds to a single ensemble structure defined by .sigma.(q.sub.0,c)=(C,{M.sub.c },L where C={H1,H2,M.sub.OR } {M.sub.c }={M.sub.H1,M.sub.H2,M.sub.OR } L={((ORTest,in1:),(H1,value:)),((ORTest,in2:),(H2,value:)), ((OR,in1),(H1,value)),(OR,in2),(H2,value)),((ORTest,out),(OR,out))}. The following example explains how connectons may be used within a program. First, we define a "holder" connecton. A holder connecton has two input gates: 1) value: that sets a state variable to a given value storing this value, 2) value that returns the stored value. The connecton ensemble 402, represented in FIG. 4, is composed of one OR connecton 202, linked to holder connectons, H1404 and H2406. The ensemble has two input gates in1: 410 and in2: 412 to set logical values, and the gate out 414 to communicate the result. The ensemble connecton is called ORTest and includes the executive connecton, ORTest.sub.g, that holds the overall structure. The structure of any ensemble is defined by the method connectonStructure that every ensemble class must define. The variable Network is an alias for the actual network (ensemble). The ORTest connecton network is defined in the DESMOS system by connectonStructure
.vertline.str.vertline.
str := super connectonStructure.
"Obtain the structure cf the parent class"
str addConnecton: #H1 class: Holder. "Adds Holder H1"
str addConnecton: #H2 class: Holder. "Adds Holder H2"
str addConnecton: #OR class: OR. "Add an OR connecton"
"Links the Network to H1"
str link: Network gate: #in1: to: #H1 gate: #value:.
"Links the Network to H2"
str link: Network gate: #in2: to: #H2 gate: #value:.
str link: #OR gate: #in1: to: #H1 gate: #value. "Links OR to H1"
str link: #OR gate: #in2: to: #H2 gate: #value. "Links OR to H2"
str.
To test this network, we use the method or Test that is defined in DESMOS by orTest
.vertline.orN value.vertline.
orN := ORTest new. "Creates a ORTest Network"
orN in1: true. "Sets the in1: gate value"
orN in2: false. "Sets the in2: gate value"
value := orN out. "Computes the Or value"
Transcript nextPutAll: value asString; cr. "Prints the value"
The message new sent to the Connecton class ORTest creates a new connecton with the structure defined in its connectonStructure class method. As gate names correspond to method names, standard object messages can be used to communicate with connectons. XII. Scaling Modularity and hierarchy connecton building can be used as a paradigm to represent very complex systems. FIG. 5 illustrates how "small" connecton granularity may be. We model the factorial function by a connecton. In FIG. 5, a connecton 502 receives an initial value n at gate fact: 510 for calculating a factorial. The value n is then transmitted to gate fact: 506 of a factorial connecton 504, which determines the factorial of the initial value n by recursively transmitting values associated with the factorial from gate out: 508 to gate fact: 506 of the factorial connecton 504. The recursive definition of factorial is given by fact(n) if n=0 1 else n.times.fact(n-1) The connecton representation of this function for connecton 504 is given by fact: n n=0 ifTrue: [^1]. ^n*(out out:(n-1)). In FIG. 5, the factorial executive was omitted for simplification. While this example is merely illustrative, it shows that the connecton paradigm may be used for representing arbitrarily small components. XIV. Changes in Connecton Structure FIG. 6 shows the Node connecton 602 that serves as a basis to build the Erastosthenes sieve of prime numbers. In FIG. 6, the connecton 602 holds a number id 604 and receives an incoming number via gate in: 606 and transmits an outgoing number via the gate out: 608. FIG. 7 represents the Erastosthenes sieve connecton 702 initial configuration, having an executive connecton 704. In FIG. 7, the sieve connecton 702 receives a number via gate in: 708, and the executive connecton 704 also recives a number via gate in: 706. Each connecton 804-808 of Erastosthenes sieve connecton 702 in FIG. 8 is based on connecton 602 in FIG. 6 and holds a different prime number named id (not shown here for simplicity). Each connecton 804-808 tests if it can divide an incoming number received at gate in: by id. If the connecton can divide the incoming number then the number is discarded for it is not prime. If the number cannot be divided by id, the connecton sends the number to other connectons, which perform the same test, and so on. If the number cannot be divided by the last connecton 808 in the chain, the connecton sends a signal to the executive connecton 704 to create a new connecton to handle the found prime. This action is defined by in: aNumber (aNumber .backslash. .backslash. id=0) ifTrue: [^nil]. "Tests if aNumber is divisible by id" ^out out: aNumber "Sends the number to the next node for checking." In this simplified and non optimized version of the sieve each node can only give a negative answer. Saying that a number is prime involves the cooperation of all the nodes. A number is considered to be prime no node in the pipeline that can divide it. The message outs directs the question from a connecton to its neighbor. The last connecton is linked to the executive and the call out: aNumber tells the executive to create a new node to handle the found prime. The initial configuration of the Erastosthenes Sieve is represented in FIG. 7. This model has just the network executive and no prime numbers. The following method tests the pipe with a sequence of 1000 numbers !Pipe class method! test .vertline.p.vertline. p :=Pipe new: #P. 2 to: 1000 do: [:n.vertline. p in: n]. Variable p represents the pipeline network. The interface between connectons and objects is straightforward, a connecton is seen by objects as another object. Thus the call p in: n invokes the action in: n of the pipeline network. The structure of the pipeline after receiving the sequence <2,3,4,5,6,> is represented in FIG. 8, where there is a node for primes 2, 3 and 5, represented by nodes (connectons) N2804, N3806 and N5808, respectively. Initially, the network contains just the executive connecton 704 connected to gate in: 708 as depicted in FIG. 7. When the first number arrives the executive connecton creates the first connecton 804, disconnects itself from the network (i.e., disconnecting itself from gate in: 708) and connects the created connecton to the network (i.e. connecting gate in: 606 of connecton 804 to gate in: 708 of connecton 702) and to itself (i.e., connecting gate out: 608 of connecton 804 to gate in: 706 of connecton 704). The executive connecton becomes the last connecton. The other depicted connectons 806 and 808 are added in the same fashion. The action in: aNumber handles the arrival of a prime number to the executive connecton and it is defined by !Pipeline Interface method! in: aNumber DESMOS, the embodiment of the invention implementing the connecton paradigm as disclosed herein is built on the Smalltalk language, see Smalltalk MT User's Guide. Object Connect, 1995. Smalltalk was used for simplicity of the delegation implementation. However, the DESMOS implementation of the connecton paradigm of this invention is not limited to Smalltalk, but to any object-oriented programming (OOP) language that can use delegation and reflection. The reader should note that those skilled in the art will understand how and which changes to make in conventional compilers/interpreters of existing languages in order to implement an embodiment of this invention.
.vertline.n new gate.vertline.
new := (`N`,aNumber asString) asSymbol. "Node name: #N<aNumber>"
n := self add: new class: Node. "creates a new nod""
n id: aNumber. "Sets the id of the new node"
last = #Network ifTrue: [gate := #in:]
ifFalse: [gate := #out:]. "Sets the gate variable"
"Unlinks the last node (or the network)"
self unLink: last port: gate from: #Executive port:#in:.
"Links the last node to the new node"
self link: last port: gate to: new port:#in:.
"Links the new node to the executive"
self link: new port: #out: to: #Executive port: #in:.
last := new. "The new node becomes the last node"
aNumber.
XV. The DESMOS System DESMOS, the embodiment of the invention implementing the connecton paradigm as disclosed herein is built on the Smalltalk language, see Smalltalk MT User's Guide. Object Connect, 1995. Smalltalk was used for simplicity of the delegation implementation. However, the DESMOS implementation of the connecton paradigm of this invention is not limited to Smalltalk, but to any object-oriented programming (OOP) language that can use delegation and reflection. The reader should note that those skilled in the art will understand how and which changes to make in conventional compilers/interpreters of existing languages in order to implement an embodiment of this invention. FIG. 9 represents a block diagram of the Connecton Kernel 902. For simplicity, we have only represented a connecton ensemble 904 with its executive 906 and with just one connecton 908 in FIG. 9. The information about channels is only depicted for connecton C 908. The main difference between the abstract description of ensembles and the actual implementation is that connectons keep their own channel information. This option is more efficient and can become easier to implement in parallel/distributed computers. Each connecton or connecton ensemble has a reference to the ensemble within which it belongs 914, 924. This reference, however, is nil if the connecton is the topmost one. The ensemble connecton also has a reference to its executive 912. Additional variables are currently used to manage the link information: extChannels 928 is an association list where each entry has the format gate.fwdarw.((connecton.sub.1,gate.sub.1,fFiiter.sub.1,rFilter.sub.1), (connecton.sub.2,gate.sub.2,fFilter.sub.2,rFilter.sub.2), (connecton.sub.n,gate.sub.n fFilter.sub.n,rFilter.sub.n)) where gate.sub.i is an input gate if connecton i is not the network, and is a network output gate otherwise. The variable intChannels 918 is associated with the network and defines all the channels starting at the network input gates. The two variables are defined for implementation convenience: revExtChannels 930 and revIntChannels 922. The reverse channels are maintained to make the operation of removing connectons in run-time, faster. There is a reverse channel for each (direct) channel in the model. Each entry in the list represents a channel connecting two gates. A gate can have several channels to different gates. There is no constraint on the number of channels from a gate, or into a gate. For each channel there are two filters: direct (forward) and reverse filters. XVI. Message Table Channels among connectons are stored in a message table. A message table has one entry for each gate, and associated with each gate can be an arbitrary number of channels. Variables extChannels 920 and intChannels 918 are instances of class MessageTable, that implements a mapping table for messages. Each message is an instance of class SCMessage and is defined by 6 variables: m_sender, the connecton that sends the message; m_receiver, the connecton that will receive the message; m_selector, the message name; m_arguments, the message arguments; fFilters, channel direct (forward) filter; and rFilters, channel reverse filter. The SCMessage method value is defined by value
m_receiver_sender: m_sender.
(fFilter == Identity) & (rFilter == Identity) ifTrue: ["No filters"
m_receiver _perform: m_selector withArguments: m_arguments].
"Only one argument signals are implemented"
"Apply filters"
rFilter value:(m_receiver _perform: m_selector withArguments:
(Array with: (fFilter value: (m_arguments at: )))).
Each channel can have two filters: forward (direct) and reverse represented by variables fFilter and rFilter, respectively. These filters transform the values sent to a gate, and the values returned from a gate, respectively. Filters are an effective solution to couple gates with different signatures without the creation of additional connectons to make the adaptation. If no filter is set, a default filter called the Identity is used. The Identity class method value: just returns the input value, and is defined by !Identity class method! value: aValue "Implements the identity function filter" ^aValue. EXAMPLE We describe a connecton that sends and accepts values in Km that need to be linked with connectons that work in Meters and Miles. The structure of the connecton is given by the method connectonStructure
.vertline.t.vertline.
t := super connectonStructure. "The parent returns the empty structure"
t add: #Km model: VelocityKm. "Km connecton"
t add: #M model: VelocityM. "Meters connecton"
t add: #Mi model: VelocityMi. "Miles connecton"
t link: #Km gate: #out to: #M gate: #in: filter:
[:x.vertline. x*1000] filter: [:x.vertline. x/1000].
t link: #Km gate:#out to: #Mi gate:#in: filter:
[:x.vertline. x/1.65] filter: [x.vertline. x*1.65].
Links are established by the method link:gatet:to:gate:filter:filter:, where he first filter is the direct filter and the second is the reverse filter. The direct filters convert Km into meters and miles and the reverse filters makes the reverse conversions. Filters permit to join gates with different interfaces without additional elements. Channel filters can be combined with gate output functions. For example the output function of gate outs could sum all the input values in Km from connectons #M and #Mi. In the current implementation only one argument signals can have direct and reverse filters. The reason is the complex Smalltalk syntax necessary to handle general number of arguments. In this case filter functions would become difficult to read. XVII. Message Breaking The current implementation keeps the information about channels distributed in the out variable 932, 934 of each connecton 908, 906 so the executive is only invoked to handle changes in the structure (i.e., message breaking). This design, although it implements conceptually the role of the executive, might prove more efficient in distributed applications. Additionally, caching systems can also be become easier to implement. When the number of channels is very large, a central store implementation would need a hashing system to handle messages efficiently. Thus distributing channel information is an effective way to avoid hashing. In static structure networks, the message doesNotUnderstand: is not strictly necessary if some pre-processing is done before compilation, replacing calls to variable out with a defined message. In this case the exception mechanism would not be necessary and the implementation becomes faster. So the breaking process could be implemented as a pre-processor by those skilled in the art. The actual code of the message doesNotUnderstand: implemented in Smalltalk MT is as follows !ConnectonOutput 05:24-Oct. 4, 1997! doesNotUnderstand: aMessage
.vertline.ms selector filter.vertline.
selector := aMessage at: 2. "selector"
ms := extChannels at: selector ifNone: nil.
ms is Nil ifTrue: [self error:`Gate:`,selector asString,`does not exist.`].
filter := filters at: selector ifNone: nil.
self_broadcast: ms arguments: (aMessage at: 3) filter: filter.!!
As shown, aMessage is a 3-element array described by: [receiver, messageName, arguments]. This method acts as a message breaker that divides a message into the receiver, the selector (message name), and the arguments. The reader should note that Smalltalk is one of the few languages where this breaking mechanism is so easy to use, in spite that the original intention was exception handling. The call _broadcast: aMessage arguments: arguments filters aFilter, broadcasts messages to all connectons linked to a gate. The last argument represents the gate output function. This function is used to handle the set of input values to a gate. The method_broastcast:arguments:filter: is defined in class Output, a parent class of ConnectonOutput and NetworkOutput classes, and is given by !Output 09:04-Oct. 4, 1997! _broadcast: nMessages arguments: anArray filter: filter
.vertline.ret .vertline.
filter is Nil ifTrue: [
.vertline.value.vertline.
"Default behavior: no filter is defined at the output gate"
(nMessages size = 0) ifTrue: [ nil].
"if there are no charnels returns nil"
ret := nil.
nMessages do: [:m.vertline.
value := self _send: m arguments: anArray.
(value == DeletedChannel) ifFalse: [ret := value].
].
ret "Returns the last value"
]
ifFalse: [
.vertline.value.vertline. "A filter is defined"
ret := OrderedCollection new.
nMessages do: [:m.vertline.
value := self _send: m arguments: anArray.
(value = DeletedChannel) "The channel has heen deleted,ignore
it"
ifFalse: (ret add: value]. "Collects all input values"
].
filter value: ret. "Applies the filter to the input list"
] ! !
There is a default behavior in the absence of filters. If an output gate has no filter assigned, the method returns the last value received, or the value nil if the output gate has no channels. When a filter is defined, a list of input values is collected and the filter is applied to this list to compute the return value. The default behavior was chosen for it seems to be used in most of the situations. The call _send: a SCMessage arguments: anArray, sends a signal to linked connectons, and is defined by !Output 09:04-Oct. 4, 1997! _send: aSCMMessage arguments: anArray
.vertline.receiver.vertline.
aSCMessage isNil ifTrue: [ DeletedChannel]. "The channel has been
deleted"
aSCMessage arguments: anArray.
receiver := aSCMessage receiver.
"Send signal to the connecton"
(receiver .about.= networkOutput) ifTrue: [ aSCMessage value] .
"Send signal to external connections"
receiver _extMesasage: aSCMessage arguments: anArray. ! !
This method makes the separation between signals that are sent to connectons inside the network, and signals that are sent to connectons outside the network. In the later case, gate names are translated using the link information of the parent network. Variable networkOutput 910 is used to send messages from a network to external connectons. The call _extMessage: aSCMessage arguments: anArray is defined in the network output to access connectons outside the network, and is defined by !NetworkOutput 09:04-Oct. 4, 1997! _extMessage: aSCMessage arguments: anArray
.vertline.ms selector filter.vertline.
selector := aSCMessage selector.
ms := extChannels at: selector.
ms isNil ifTrue: [self error: `Port:`,selector asString,`does not exist`].
filter := filters at: selector ifNone: nil.
self_broadcast: ms arguments: anArray filter: filter!!
Networks also need to break messages. Although messages coming from a connecton within a network can be easily sent to the output directly, because they are already broken, messages arriving to the network from the outside must also be identified for they can come from a standard calling mechanism, that is, the message connecton message must work whenever connecton represents a basic connecton or the connecton is an ensemble. The message breaker in the network is defined by !NetworkOutput. CALLBACK methods 09:04-Oct. 4, 1997! doesNotUnderstand: aMessage .vertline.ms selector filter.vertline. selector :=aMessage at: 2. "selector" ms :=intChannels at: selector ifNone: nil. ms isNil ifTrue: [self error:`Gate:`, selector asString, `does not exist`]. filter :=inFilters at: selector if None: nil. ^self_broadcast: ms arguments: (aMessage at: 3) filter: filter.!! If the network is an inner model and it is not accessed by regular messages, signals are transmitted by the method _perform:withArguments: defined by !NetworkOutput 09:04-Oct. 4, 1997! _perform: selector withArguments: arguments
.vertline.ms filter.vertline.
ms := intChannels at selector ifNone: nil.
ms isNil ifTrue: [self error.`Gate:`,selector asString,`does no exist`].
filter := inFilters at: selector ifNone: nil.
self_broadeast: ms arguments: arguments filter: filter.!!
Message broadcast is done by the method already described before because both ConnectonOutput and NetworkOutput are subclasses of class output. XVIII. Support for Structural Changes The following methods were defined in the DEMOS System to change the connecton structure during the execution of a program: addConnecton: aConnecton name: aName, adds a new connecton aConnecton, with an identifier aName; link: aName gate: aGate to: bName gate: bGate filter: dFilter filter: rFilter, links aConnecton named aName gate aGate to gate bGate of connecton bName, establishing direct filter dFilter and reverse filter rFilter; link: aName gate: aGate to: bName gate: bGate, links aConnecton named aName gate aGate to gate bGate of connecton bName, direct and reverse filters are assumed to be the identity function; removeConnecton: aName, removes the connecton named aName and all its channels; replaceConnecton: aName with: bConnecton name: bName, replaces a connecton named aName with connecton a named bName; unLink: aName gate: aGate from: bName gates bGate, unlinks aConnecton named aName gate aGate from gate bGate of connecton bName; unLink: aName gate: aGate, deletes all the links starting at aGate of connecton named aName. A connecton is referenced by a name and not by a pointer. Connecton names are assigned to connector instances in the connecton structure definition. XIX. Structural Inheritance New connectons are seldom built from scratch. Instead they are usually built using an existing connecton class as a template. A new class is defined just by incorporating all common features of the existing class and by the addition of some new characteristics (methods and state variables). Inheritance provides not only an effective means for code reuse but also a mechanism for grouping related models in a taxonomic hierarchy. Structural inheritance is an effective way to build new connectons from existing ones. Support for reusing structural objects is given by inheritance of structure in a similar way to code reuse in conventional inheritance. A connecton name is just an alias that can be used to define the network structure. Each connecton name is associated to a connecton class. To build a connecton, names in the structure definition are replaced by an instance of a connecton class. The network structure is thus a template, and actual networks are obtained by replacing aliases by instances. In the DEMOS environment (as the illustrative embodiment of the inventive connecton paradigm disclosed herein), the following operations are defined over the structure of a network: addConnecton: aName, class: aClass, adds a new connecton of class, aClass, to the network structure; removeConnecton: aName, removes a connecton from the network structure; replaceConnecton: aName byClass: aClass, replaces the class associated with aName by aClass; link: aName gate: aGate to: bName gate: bGate filter: dFilter filter: rFilter, creates a link and filters between two connectons; link: aName gate: aGate to: bName gate: bGate filter: dFilter filter: rFilter, creates a link between two connectons; unlink: aName gate: aGate from: bName gate: bGate, deletes a link between two connectons; unlink: aConnecton gate: aGate, deletes all the links from aGate of aConnecton. In the DESMOS system connecton models are hierarchically organized. Connecton is the root class for all connecton classes. The class ConnectonExecutive is the superclass of all network executives. This class implements all basic operations that support changes in connecton network structure. These operations include adding and deleting connectons and links. Every specific domain connecton network must be a subclass of the class ConnectonExecutive. FIG. 10 represents a partial view of the DEMOS hierarchy, as described above. All the subclasses of the class ConnectonExecutive can inherit the structure of the parent class. The ConnectonExecutive class provides just an empty connecton network. Structural inheritance can be used for several purposes. For example, a connecton superclass can be used to provide the common structure to its connecton subclasses. These connecton subclasses therefore must only just add the structural differences. We illustrate the use of inheritance to create a NOR4 gate (FIG. 13) from an OR4 gate (FIG. 11). FIG. 11 represents the OR4 gate 1102, which includes 4 inputs in11112, in21114, in31116 and in41118, and one output gate out 1120. The OR4 gate 1102 is a network made of 3 basic two input OR gates OR1 1104, OR2 1106 and OR3 1108 and an OR4 executive 1110. The definition of the OR4 connecton class in given FIG. 12, where the definition of the network is made within the connecton Structure method. From the OR4 connecton class we can easily derive the NOR4 class depicted as NOR4 gate 1302 in FIG. 13. The DESMOS definition is given in FIG. 14, where the method connectonStructure only needs to define the differences from the initial OR4 gate 1102 depicted in FIG. 11. In FIG. 13, the NOR4 gate 1302 includes the OR gates 1104, 1006 and 1108, the NOR4 executive 1306 and the NOT gate 1304. In the definition of FIG. 14, the first line obtains the structure of the parent class. The second line adds a model named #NOT of connecton class NOT. Actual connectons are obtained by replacing aliases by connecton class instance. In this case, symbol #NOT is replaced by an instance of connecton class NOT named #NOT. XX. The MVC Architecture and the Dependency Mechanism We now describe how the Smalltalk MVC framework can be implemented using connectons, see S. Lewis. The Art and Science of Smalltalk. Prentice Hall, 1995. We use a simple graphical system 1502 represented in FIG. 15, which displays the speed of a car. The transducer connecton 1508 receives at gate apperature: 1514 the throttle aperture from the throttle connecton 1506 that send the throttle aperture via gate value: 1512. The transducer connecton 1508 then coverts the aperture throttle to a value of velocity, and this value is sent to the output gate speed: 1518. The level meter connecton 1510 receives the velocity at gate value: 1520 and displays the speed of the car. It is noted that the transducer connecton 1508 includes a gate x:y 1516 that is not linked to any other connecton. The transducer operates independently of the connectons linked to its output. In the system of FIG. 16, two graphical widget connectons 1604 and 1608 that display the value of the velocity and position have been added. The system of FIG. 16 also includes a control executive 1604. A plot chart connecton 1608 has been added and linked through the establishment of a new channel between the gate speed: 1518 of the transducer 1508 and the input gate sample: 1610 of the plot chart 1608. An XY-Plot connecton 1604 was also added to draw car position over time. The input gate x:y: 1606 of the XY-Plot chart 1604 is linked from the output gate x:y: 1516 of the transducer 1508. The aperture: action of the transducer is defined by aperture: aValue
.vertline.speed position.vertline.
speed := self computeSpeed: aValue.
position := self computeSpeed: aValue.
out speed: speed.
out x: (position x) y: (position y).
A solution using the Smalltalk dependency mechanism cannot discriminate messages for it uses the same update: message to update the list of all the dependents. Thus all the objects will receive an update even if the message is not directed to them. Another Smalltalk limitation exists when new messages are created for in many cases existing objects need to be modified to understand new update message parameters. The unstructured dependency mechanism of Smalltalk was replaced by the structured concepts of gate and channels in the connecton approach of the present invention. In this example, the advantages of the connecton programming are evident. XXI. Connectons vs. Objects The object paradigm relies on absolute method and instance addresses. The typical message sending consists of a name of an object followed by the name of the method and some arguments. If a widget displays a number on a window, the command to change the information would have the following format: aWidget display: aNumber aPicture x: newX y: newY. Although clear, this process of communication between objects has two main constraints to obtaining reuse. First, aWidget is typically a reference to an existing object. Second, display: is a message that the object can understand. To be truly reusable, objects should not rely on this specific information. The absolute address does not allow the object to be used with a new kind of widget that to show a number uses a method named show: instead of display:. A straightforward solution to solve the first problem is the use of an indirect reference. In this case, the variable aWidget could be instantiated after the creation of a specific widget object. However, this solution does not solve the problem of a possible different method name in the outside object. This simple solution has also another problem: it does not allow that the same message may be sent to an unknown number of other objects. Connectons overcome these problems by specifying the outside world through a reference to the pseudo variable out. Any messages that cannot be handled locally by the connecton are sent to the outer world in a general and simple way. The code to display a number using connectons would be out display: aNumber. out x: newX y: newY. As can be seen, the same message protocol is used to achieve different results. Both "displaying a number" and "moving a picture" are messages sent to outer connectons through the variable out. In consequence of the relative messages, names, actual widgets and pictures can have very different message names to handle the intended actions. The mapping between message names is handled by the linkage mechanism of connectons. Messages are ignored if the outside world does not exist. Moreover, the number of connectons linked to a gate is arbitrary. The current mechanism returns nil as a default value of a message sent to several connectons. When a message is sent to just one connecton, the current implementation returns by default the value sent by that connecton. Connectons provide a simple way to monitor variables. The explicit mechanism to monitor variables is less prone to error than the standard mechanism of active values or daemons. The DEMOS language, illustrating the connecton paradigm disclosed herein, can use all original Smalltalk libraries because it may also use the standard message protocol. Objects can be seen as connectons with input gates and no output gates. Objects, thus, can be used as terminal connectons. This flexibility achieved by connectons involves, however, a higher computational cost, mainly to translate output gates to input gates. Connecton-oriented programming can make effective use of a CASE tool where connections among connectons can be graphically depicted and edited. The translation between such a CASE tool and the actual code would be straightforward to those skilled in the art. Also, the realization of a library of connectons will be very simple to achieve due to connecton encapsulation. XXII. Connectons vs. Hardware Traditional hardware has been referred to herein as having a high quality standard, which is lacking in traditional software. The connecton paradigm of this invention, however, not only approaches the high hardware quality standard, but also can be clearly shown to overcome it. The first feature is hierarchy, while hardware is modular, it cannot implement hierarchical concepts. The second feature is that compared with hardware, the connecton structure is dynamic by design. Connectons can change composition and channels at run-time. Hardware is not typically automatically reconfigurable. XXIII. Connectons vs. Patterns To show the power of the Connecton paradigm, we now describe an example taken from the software design pattern approach and compare it with the corresponding Connecton solution. Most of the so called structural patterns described in, E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995, and remarkably, some of the behavior patterns can be replaced by connectons without the introduction of additional elements, or a simplification of the problem. The Chain of Responsibility pattern, categorized as a behavioral pattern, is a framework to pass commands through a chain of objects. Each object in the chain has two possibilities: to accept the command or to pass it to the next element in the chain if the command cannot be locally handled. Each pattern is based upon a set of special purpose classes. The connecton solution, depicted in FIG. 17, does not demand any special model to handle chains. A chain is just a special topology, that is, a chain is just a specific problem of Connecton composition. The chain connection 1702 depicted in FIG. 17 includes an executive connecton 1704, connectons A 1706, B 1708 and C 1710. The chain connecton 1702 includes a gate in: 1712 and a gate out: 1714. Each of the connectons 1706, 1708 and 1710 includes a gate in: 1716 and a gate out: 1718. Most of the structural patterns can be described by an ad hoc composition and do not represent a general purpose solution. Some of the patterns described in, see E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995, treated as independent, are in reality seen as the same in the Connecton paradigm. Examples are the patterns Composite and Facade that in the Connecton paradigm only present different topologies. Patterns seems thus to lead to an arbitrary taxonomy. We describe now in mode detail the Connecton solution for the Chain of Responsibility problem. Each connecton in the chain can be described by in: aMessage self respondsTo: aMessage ifFalse: [^out out: aMessage]. ^self accepts: aMessage Messages that cannot be handled locally are just sent to the outside. The actual code that will be invoked depends on the existing links, or in other words, it depends on the existing specific structure. Solutions categorized by the class-subclass relationship do not show any fundamental characteristic of the problems. Because traditional solutions based on Objects fail miserably to represent structure, one is forced to find specific solutions to every problem that demands for a structural representation. Because structure has shown to be an evasive issue, different solutions are commonly obtained for problems that appear to be different only because the structural perspective is not considered. Thus, significant programming effort is wasted because today's paradigms fail to represent structure. XXIV. Analysis and Design Traditional software engineering approaches divide the development of new information systems in 4 large phases: analysis, design, implementation and testing. Connectons can have a strong impact on these traditional phases for the first three are all done simultaneously. Analysis can be broadly defined as the specification of the problem and the identification of sets of inputs and outputs to the system. Design is usually referred as the process of translate the analysis specifications into programming modules, and implementation is the result of translating design into a computer language. These three phases are independent, so each phase produces some document to the next stage. The major drawback of this approach is that it is difficult to enforce the integration between these phases, and for example, there is not a mechanism to ensure that design has fulfilled all the analysis requirements. With connectons, analysis design and implementation are all done using the same tools. Analysis and design are actually the same procedure. At the end of the analysis phase, a set of hierarchical connectons and their interconnections is defined. That is, and surprisingly, the implementation model is almost finished. To complete the actual implementation, only basic connectons that are not yet defined in some connecton library need to be developed. Thus the Connecton paradigm represents a major breakthrough in software engineering. A repository of connectons is the kernel of connectware reuse, and by economical reasons, it will constrain the software construction process. Like an architect that chooses standard height and width for doors and windows, connectware architects must utilize, where possible, existing connectons. Thus, analysis and design are constrained by existing connectons. The test on connectons seems only to exist in the bottom up manner, and top-down testing seems to have no definition, for on the top there are only connections and no actual code. Thus it seems that test must be done hierarchically, from basic connectons to network connectons. Because connectons provide a modular approach, connectons can be tested independently. Special testing methodologies must be developed to access the correctness of dynamic structure connectons. XXV. Implementation Aspects While the connecton paradigm was described herein with respect to the DESMOS system, various other implementations (not limited to Smalltalk) of the connecton paradigm may be utilized in various systems. For example, the current implementation of the DEMOS system runs in one single processor computer and with one single thread of control. Connectons, however, may also be located in different processes, in different processors and even within different computers. The nature of the connecton programming does not change, only links must be completed with the physical location of the connectons. This location can include the process identifier, the processor identifier and the machine identifier. For example, if two connectons are located in different computers connected through the Internet, location must include the IP of the computers. Please note that in the implementation defined and described herein, this information is not necessary because all the connectons are in the same location. More particularly, the current implementation runs in a single thread of control. Multiple threads and multiple active connectons can be easily accommodated. Concomitantly, traditional methods for control of access to shared memory, e.g., semaphores and critical sections may be employed. While the described embodiment is synchronous, an asynchronous design may be easily implemented in a multithreaded version by those skilled in the art. Furthermore, the current implementation requires that the connectons be created from their models (classes) before use. Providing connectons with a persistent storage mechanism would allow connectons to be stored and loaded into memory without creation from scratch utilizing their class description. Persistency is a technique currently used for storing objects in databases. And as stated above, links may be stored in the network executive or may be distributed among connectons (based on efficiency). The message breaking mechanism described above is dependent upon the Smalltalk dialect used for implementing the connecton system. Other Smalltalk dialects have their own specificity for message breaking. In the DEMOS implementation described herein, the message breaking mechanism was implemented using the error handling mechanism of Smalltalk MT, see Smalltalk MT User's Guide. Object Connect, 1995. No other languages are known to provide these primitives to implement the message breaking mechanism described. However, it should be apparent to those skilled in the art how to incorporate the basic mechanisms for eliminating absolute object/methods addresses in the compilers of any of the multitude of existing computer languages. That is, although the mechanisms may be different from those employed in the Smalltalk language, the connecton paradigm is not limited thereto. If the operating system needs to change the physical location of a connecton, ex.: for load balancing purposes, only links need be updated by the operating system. The connecton structure should remain the same and no connecton should be re-programmed. Thus, operating system procedures, like load balancing procedures, do not change the nature of this invention. The several methods described may be merged, and an implementation that utilizes one or a group of the previous characteristics can be easily developed. For example, the multithreading version of the connecton paradigm can be constructed into a system that runs on several microprocessor computers linked by a computer network. Also, some technical difficulties must be solved, for connecton based languages demand capabilities not usually found in the most common compilers. Although static structure connectons can be implemented efficiently by simple changes in current compilers, dynamic structure connectons will demand better support of compilers. If the ability of dynamic structure software is not used, current compiler technology can produce Connecton code as efficient as Object code. In this case, hierarchical models could be flattened, that is, the hierarchy is removed, and all channels can be replaced by actual message calls. Multiple channels starting at the same gate could be replaced by an iteration by the compiler with this simplification, Connectons could be easily incorporated into current compiler technology. This is easily accomplished by those skilled in the art. In this case the out variable mechanism would have a simpler implementation than those described for the DESMOS system, that involves the Smalltalk error handling mechanism. Dynamic structure does not permit the removal of the hierarchy, and caching connectons and channels may prove a good solution to improve efficiency. Caching would avoid the repetition of the actions necessary to find all the components connected to a gate. This information could be kept and updated when a change in structure occurs. In the DESMOS systems links and Connectons gates are specified directly in the programming language. However, the implementation of a graphical interface, like for example a CASE tool, to help defining connectons will be easily accomplished by those skilled in the art. The present implementation of Connectons is currently stored in a computer hard disk and is loaded into computer RAM in order to run. Other forms for storing an implementation of connectons, like CDROM, DVD, floppy disk, or magnetic tape could also be used. A connecton implementation can also be stored and run from PROM, EPROM, EEPROM or any other computer memory technology. XXVI. Conclusions In conclusion, traditional objects describe only terminal connectons and thus are not fully reusable. Connecton reusability is achieved by removing all absolute addresses from connecton definition and by viewing software units as structural entities. Connectons, therefore provide full support for software reusability. Under the Connecton paradigm, software is built in a hierarchical and modular form. Connectons are thus suitable for building large software systems that can be easily reused. The Connecton paradigm scales well and it can be used in the implementation of systems, ranging from the most simple to the most complex. Connectons are a paradigm shift for software engineering for they encompass a new way for building software by the use of independent and reusable software units. Connectons will obviously have a strong impact on the way software is made. The process development cycle will be completely changed by the existence of a connecton repository that will influence all phases of software life cycle. This cycle will be constrained by economical factors and existing connectons will be used when possible, and impose strong constraints to the analysis in the same way that standard doors and windows constrain the project of a house. Connectons, because of their simplicity, open the door of software reuse to everyone, for its use does not need any special skills or expertise. Thus small and large software houses and individual programmers can turn their software work into reusable Connectonware just by using connecton programming. The reader should note that legacy is the major enemy of any new software paradigm. Work needs to be done to make existing software compatible with the new connectonware. Nevertheless, current objects are compatible with connectons and can be used not only to implement the state of connectons but can also be used as terminal connectons. Another possibility is to wrap current objects inside connectons. Finally, dynamic structure models as taught herein open a gate to the dynamic update of software systems. Because Connectons can be dynamically configured, one can easily foresee a scenario where software can be upgraded by changing some of the connectons that become obsolete. This is especially important in running non-stop systems, like real-time systems, where this task would have a large economical impact. The many features and advantages of the present invention are apparent from the detailed description, and thus, it is intended by the appended claims to cover all such features and advantages of the invention which fall within the true scope and spirit of same. Moreover, since numerous modifications will readily occur to those skilled in the art, it is not desired that the present invention be limited to the exact construction and operation illustrated and described herein and accordingly. All the suitable modifications that are equivalent are intended to fall within the scope of the claims.
|
Same subclass Same class Consider this |
||||||||||
