.TH PROPAGATE 1 "29 September 1992" "Demeter" "Demeter Software" .SH NAME propagate \- propagation pattern compiler for Demeter System/C++ .SH SYNOPSIS . .I propagate envname [ -i ] [ -c compname... ] .SH DESCRIPTION .I propagate is a translator from propagation pattern files to C++ files. Propagation patterns are written in files whose names end in .I .pp. They are translated and each resulting file is placed in the directory where the propagation pattern files live. .SH OPTIONS .IP envname Name of the environment. It should be the same as the value of variable .I TOPENVNAME in .I Imakefile. .IP -i Generate intermediate files in subdirectory .I inter-pps. .IP -c Read propagation pattern files imported from other components. .IP compname Name of the component used in this environment. .SH CD-PARAM-EXP The propagation patterns are written with respect to a class dictionary file named .I cd-param-exp in the subdirectory .I notmod/cds. This file is generated by .I sem-check. .SH NAMING OF RESULTING FILES For example, suppose that the name of a propagation pattern source file is .I sample.pp containing two propagation patterns .I void show() and .I void fun(). With switch .I -i on, there are 5 files which are generated. .RS 5.0 .br sample-DEM.c .RS 8.0 All the functions translated from .I sample.pp. .RE .br inter-pps/sample-1..pp .RS 8.0 An intermediate propagation pattern file for .I void show() with meta variables and renaming eliminated. .RE .br inter-pps/sample-1.trv .RS 8.0 Propagation schema of propagation pattern .I void show(). .RE .br .I inter-pps/sample-1-1.trn .RS 8.0 Propagation schema for the first transportation directive of propagation pattern .I void show(). .RE .br .I inter-pps/sample-1-2.trn .RS 8.0 Propagation schema for the second transportation directive of propagation pattern .I void show(). .RE .br inter-pps/sample-2..pp .RS 8.0 An intermediate propagation pattern file for .I void fun() with meta variables and renaming eliminated. .RE .br inter-pps/sample-2.trv .RS 8.0 Propagation schema of propagation pattern .I void fun(). .RE .SH SYNTAX The propagation pattern tool allows adaptive programming with class dictionary graphs. Each propagation pattern file contains zero or more propagation patterns. Each propagation pattern describes what kind of signature to be propagated, how the propagation schema is constructed to define a traversal, how objects are transported along the traversal and where users add their own code fragments to some classes. Each propagation pattern has five parts: .I signature part, meta declaration part, traversal part, transportation .I part and .I code fragment part. The complete syntax is determined by the the class dictionary for propagation patterns. .SH SIGNATURE PART The syntax of signature part is .RS 1.0 .I *operation* .br \t \t rettype fname(argtype argname [= (@ expression @)], ...) .br \t \t \t \t [ *init* (@ expression @) ] .br \t \t \t \t [ *access* class-set ] .RE .RE The syntax inside brackets is optional. .I rettype, argtype are any C++ type,. They can also be a type in Demeter syntax. See the man pages of .I sem-check. .I fname is a function name. .I argname is an argument name. .I expression is a C++ expression. .I class-set can be a singleton set, written as .I C or .I { C }, or a set of classes, written as .I { A, B , C }, or a set of any vertex, written as .I *. .I *init* clause gives an initial value of the return value of the function. Further calculation is done along the traversal based on the initial value, and the final result is returned to the caller. .I *access* clause gives a set of classes whose functions can be publicly accessed. If it is omitted, the set of vertices is determined by the source vertices of the propagation schema computed from the traversal directive. .I return_val is a keyword which carries the return value of a function during a object traversal. .I return_val can only be used when the return type of a function is not .I void. The type of .I return_val is the same as the return type. .SH META DECLARATION PART An example of meta declaration is .RS 4.0 .I *constraints* .br .R6 5.0 \t \t .I *classes* .br A,B,C .br \t \t .I *edge* *patterns* .br -> A,k,* .br \t \t .I *class-set* .br S1 = { A, B }; .br S2 = { C }; .br \t \t .I *directives* .br D = *from* A *to* B; .br .I *end* .RE .RE A meta declaration defines the contraints in a propagation pattern. The above constraints say that classes A, B and C have to be in the class dictionary graph the propagation pattern is going to be propagated on. k has to be the construction edge label outgoing from class A in the schema. There must be at least one knowledge path from A to B. Class set variables S1 and S2 and directive variable D are used in the propagation pattern to avoid redundancies. To use class set variable S1, use .I class-set S1. If you use S1 alone, S1 means a singleton class set, { S1 }. .SH TRAVERSAL PART Traversal part has the syntax such as .RS 1.0 *traverse* .br \t \t *from* class-set .br \t \t \t \t [ *through* edge patterns seperated by comma(,) ] .br \t \t \t \t [ *bypassing* edge patterns seperated by comma(,) ] .br \t \t \t \t [ *via* class-set .br \t \t \t \t \t \t [ *through* edge patterns seperated by comma(,) ] .br \t \t \t \t \t \t [ *bypassing* edge patterns seperated by comma(,) ] ] .br \t \t \t \t ... .br \t \t [ *to* class-set ] .RE .I classet is as described above. The syntax of edge patterns in the above specification is .RS 5.0 -> class-set, label-set, class-set .RS 8.0 a construction edge pattern .RE .br => class-set, class-set .RS 8.0 an alternation edge pattern .RE .br :> class-set, class-set .RS 8.0 an inheritance edge pattern .RE .br ~> class-set, class-set .RS 8.0 a repetition edge pattern .RE .RE The clause after .I *traverse* is called a .I propagation directive. It defines all the knowledge paths in a class dictioary graph. In some cases, .I *to-stop* is used instead of .I *to* if you do not take outgoing edges from the target vertices. For example, if you have a class dictionary in notmod/cds/cd-param-exp as follows. .RS 5.0 Example = Prefix. .br Prefix : Numerical | Compound. .br Numerical = DemNumber. .br Compound = Op Prefix Prefix. .br Op : Addsym | Mulsym. .br Addsym = "+". .br Mulsym = "*". .RE You can write the following propagation pattern. .RS 1.0 *operation* .br \t \t int count() .br \t \t *traverse* .br \t \t \t \t *from* Prefix *to* Numerical .RE This propagation says that we generate the member fuction "int count()" for the classes on the paths from Prefix to Numerical. We can also write another propagation pattern to have the same result. .RS 5.0 *operation* \t \t int count() .br \t \t *traverse* .br \t \t \t \t *from* Prefix .br \t \t \t \t \t \t *bypassing* -> *,*,Op .br \t \t \t \t *to-stop* Numerical .RE This means that we traverse the class dictionary graph from Prefix but not entering Op and stopping at Numerical. The following also has the same result. .RS 5.0 *operation* .br \t \t int count() .br \t \t *traverse* .br \t \t \t \t *from* Prefix .br \t \t \t \t \t \t *through* -> Compound,*,Prefix .br \t \t \t \t *to-stop* Numerical .RE This says that we traverse the class dictionary graph from Prefix to Numerical with all the paths containing the construction edges which are from Compound to Prefix. .SH TRANSPORTATION PART Traversal part has the syntax such as .RS 1.0 *carry* .br \t \t [ *in* | *out* | *inout* ] vartype varname, .br \t \t ... .br \t \t *from* class-set .br \t \t \t \t [ *through* edge patterns seperated by comma(,) ] .br \t \t \t \t [ *bypassing* edge patterns seperated by comma(,) ] .br \t \t \t \t [ *via* class-set .br \t \t \t \t \t \t [ *through* edge patterns seperated by comma(,) ] .br \t \t \t \t \t \t [ *bypassing* edge patterns seperated by comma(,) ] ] .br \t \t \t \t ... .br \t \t [ *to* class-set ] .br \t \t *at* class-set .br \t \t \t \t varname = (@ expression @) .br \t \t \t \t ... .RE Transportation directives are used to carry objects along object traversals. We will give an example below. .SH CODE FRAGMENT PART Additional code fragments can be added to the generated traversal code. Code fragments have the syntax such as .RS 5.0 *wrapper* .br \t \t \t \t class-set .br \t \t \t \t edge patterns seperated by comma(,) .br \t \t *prefix* .br \t \t \t \t (@ .br \t \t \t \t \t \t \t \t C++ statements .br \t \t \t \t @) .br \t \t *suffix* .br \t \t \t \t (@ .br \t \t \t \t \t \t \t \t C++ statements .br \t \t \t \t @) .RE Either prefix clause or suffix clause can be unprovided. Code fragments can be added to classes, construction, repetition, inheritance edges. The C++ statements in prefix clause are inserted before the generated traversal code. The C++ statements in suffix clause are inserted before the generated traversal code. .SH C FUNCTIONS AND HEAD INCLUSION You can write functions and header file inclusion at the very end of each propagation file. This part begins with *C* which is followed by functions and file inclusion statements enclosed by "(@" and "@)". .SH COMPLETE EXAMPLES If you want to count how many DemNumber-objects there are in a Prefix-object with respect to the above class dictionary, you can write the below propagation pattern. .RS 5.0 *operation* \t \t int count() *init* (@ 0 @) .br \t \t *traverse* .br \t \t \t \t *from* Example *to* Numerical .br \t \t *wrapper* Numerical .br \t \t \t \t *prefix* .br \t \t \t \t (@ .br \t \t \t \t \t \t return_val++; .br \t \t \t \t @) .br *C* .br (@ .br void Example::callCount() .br { .br cout << "In the object : \\n"; this->g_print(); cout << " there are " .br << this->count() .br << " DemNumber-objects\\n"; .br } .br @) .RE To show the syntax of object transportation, we give another solution to the same problem, although the *carry* clause is not really necessary. .RS 5.0 D = *from* Example *to* Numerical *operation* \t \t int count() .br \t \t *traverse* .br \t \t \t \t D .br \t \t *carry* *inout* int counter .br \t \t \t \t *along* D .br \t \t \t \t *at* Example .br \t \t \t \t \t \t \t \t counter = (@ 0 @) .br \t \t *wrapper* Example .br \t \t \t \t *suffix* .br \t \t \t \t (@ .br \t \t \t \t \t \t return_val = counter; .br \t \t \t \t @) .br \t \t *wrapper* Numerical .br \t \t \t \t *prefix* .br \t \t \t \t (@ .br \t \t \t \t \t \t counter++; .br \t \t \t \t @) .br *C* .br (@ .br void Example::callCount() .br { .br cout << "In the object : \\n"; this->g_print(); cout << " there are " .br << this->count() .br << " DemNumber-objects\\n"; .br } .br @) .RE