400 likes | 419 Views
Explore GOP methodology addressing unfitness in programming context, using granules to build fit programs, with examples and strategies.
E N D
Granule-Oriented Programming Yinliang Zhao Xi’an Jiaotong University zhaoy@mail.xjtu.edu.cn XJTU
Granule-Oriented Programming • Introduction/Motivation • A GOP methodology • GOP Example I • GOP Example II • Code Granulation Space • Related Work • Conclusions & Future Work
Domain 100%Guaranteed? ≦100%? Problems Programs Existings 1. Introduction/Motivation Rethink the relationship between problems and programs: design phase & execution phase? • Experts might design and implement a perfect program according to the problem description. • Even the best program may still not solve that problem well enough. • Performance, accuracy, precision, and quality are defined for measuring how well the program works. Is it surely guaranteed that the program works well enough?
Why is that? • Lots of supports are needed in the execution of the program. E.g. runtime environment supports, meta-strategies, architectural supports, etc. • Functionalities that support program’s execution also cause them to work improperly. We employ context to denote such support.
Our observations: • Programs can be fit or unfit in their contexts • Unfitness phenomenon occurs in many software systems • Unfitness causes program not to work properly: • premature end of life cycle, • Quality, • Precision, • Performance, …
Contexts: • Runtime Env. • memory reference locality, • system overhead for message passing, • parameters and their costs, … • Meta-Strategies • object representation strategies, • object organization strategies, … • Architectural • performance-related, • restricted resources, • Interconnections, …
Unfitness Phenomena: • Support-related • performance, quality • runtime env. • meta-strategies • architectural • Problem-related • different problems in the same domain • Argument-related The goal is to localize unfitness in programming
Introduction/Motivation(Cont.) Little attention has been paid to unfitness in existing languages. This has led us to develop GOP concept. • Unfitness can be addressed in terms of divide-and-conquer principle. • Program can be divided into pieces where unfit ones are localized. • By compounding, some code pieces form a new program, in which the unfitness is eliminated. We employ granule as a well-formed and multi-layered view of “code pieces”.
2. A Methodology Basic Elements: • primary problem solving cases Problem description, algorithms, programs, … • code grinding • code granules • granule compounding • target program (compounded code)
Programming Languages PrimaryProblem SolvingCases Code Grinding Code Granules GranuleCompounding Target Program Figure 1. The basic elements of a GOP system.
Program’s context • In classical programming: • Context is implicit and should be included in problem description. • There is an invariable, no doubtful agreement between program and its context. • In GOP: • Context is related to functionalities that support the program to solve the domain problems. • Context should be first-class object.
How to deal with unfitness Assumption: Unfitness of a system is equivalent to unfitness of its subsystems. • In GOP: • Unfitness of a program is represented with unfitness of its granules • Context distribution • Granulation layer C c c c c c
3. GOP Example I • PPS0. Input data is an input file. These data are sorted in the main memory using quicksort. The results are written to an output file. • PPS1. Data are read from a slow stream and sorted in the main memory using quicksort. The results are written to an output file. • PPS2. Data are read from an input file and sorted in bounded physical memory. The results are saved to an output file.
Our Observations • Every PPS cases are fit to their original contexts. (Assumed); • If we match a PPS case with the other’s context, it may or may not cause unfitness, e.g., fitness of PPS2 to Ctx0 is kept,others not. • If we want to change the original contexts, it may cause unfitness, e.g., if a parallel architecture is adopted to support PPS1. • We can determine a new context by compounding PPS0 to PPS2. Moreover, we can also work out the target program by compounding. Fitness of this program is kept in the new context.
readport producer PPS1 mutual write - port - data - lock - infile - buffer -read - lock - buffer - buffer1 mutualread consumer - lock - buffer - buffer1 - lock - buffer1 - result merge - buffer1 - result quicksort PPS0 - buffer1 - quicksort read - file - buffer external merge PPS2 - file - buffer - memerysize Possible granules write file - outfile - result PPS?
else area.buf[k--]=area.buf[j--]; } } area.len+=buffer1.len; } int read_port(int *data, FILE *in){ /*Delay simulation*/ return(fscanf(in,"%d ", data)==EOF); } void mutual_write(int data){ int flag=0; while (!flag){ pthread_mutex_lock(&lock); if (buffer.next<BSIZE){ buffer.buf[buffer.next++]=data; flag=1; } pthread_mutex_unlock(&lock); } } void exception(char *p){ printf("ERROR: %s.\n", p); exit(0); } void write_file(FILE *out, int len, int *array){ int i; for(i=0;i<len;i++)fprintf(out,"%d ",array[i]); fclose(out); } int mutual_read(){ int flag=0, rsl; while(!flag){ pthread_mutex_lock(&lock); if (buffer.next>0){ memcpy(buffer1.buf, buffer.buf, sizeof(int)*buffer.next); buffer1.len=buffer.next; buffer.next=0; flag=1; rsl=0; }else if (buffer.notify>0)flag=rsl=1; pthread_mutex_unlock(&lock); } return(rsl); } void notify(){ pthread_mutex_lock(&lock); buffer.notify=1; pthread_mutex_unlock(&lock); } void producer(FILE *in){ int tmp; while(!(read_port(&tmp, in)))mutual_write(tmp); notify(); } void consumer(void ){ while(!mutual_read()){ PPS1 #define MEMORY_SIZE 1024 void external_Merge(int array[],int len,char *fn){ FILE *fp,*fpnew; int index=0,value; if ((fpnew=fopen(".tmpfile","w"))==NULL)exception("File open"); if ((fp=fopen(fn,"r"))==NULL)exception("File open"); while (fscanf(fp,"%d ",&value)!=EOF){ while(index<len) if(array[index]<value)fprintf(fpnew,"%d ",array[index++]); else break; fprintf(fpnew,"%d ",value); } while(index<len)fprintf(fpnew,"%d ",array[index++]); fclose(fpnew); remove(fn); rename(".tmpfile",fn); } int main(int argc,char **argv){ int len,array[MEMORY_SIZE]; FILE *in; char outfile[20]; if(argc!=3)exception("Parameters"); if((in=fopen(argv[1],"r"))==NULL)exception("File open"); strcpy(outfile,argv[2]); if(!creat(outfile,"r"))exception("File create"); while(len=read(in, array)){ quicksort(array,0,len-1); external_Merge(array,len,outfile); } fclose(in); } PPS2 {BSIZE/MEMORY_SIZE} #define BSIZE 20480 int partition(int arr[],int left, int right){ /*ignored*/} void quicksort(int arr[],int i,int j){ /*ignored*/} void exception(char *p){ /*simplified exception handler*/ printf("ERROR: %s.\n", p); exit(0); } int read(FILE *in, int array[]){ int i=0; while (!feof(in)&&(i<BSIZE)){ fscanf(in,"%d ",&array[i++]); } return i; } void write_file(FILE *out, int len, int *array){ int i; for(i=0;i<len;i++)fprintf(out,"%d ",array[i]); fclose(out); } PPS0 With Full Similarity
4. Example II / MOLOG LP Interpreter Code + - What new behaviors produced? ? The basic case What code should be added or removed? Dynamically add Dynamically remove
The experimental platform PPS case 3 Logic Programming Level Logic Programs 2LP Interpretation Level Code how to do?Code is weaved at 2nd level. Then run logic program at 3rd level. Verify the results. 1 Lisp/CLOS Evaluation Level
Selected PPS cases • timing: Display the elapsed time for a query. • trace: Trace the specified logic mechanisms. • contextcontrol: Unit based reasoning (unit:a set of clauses). • frame: Memory reference locality. • explanation: Print out inference details. • print: Formatted output for logic entities. • rp: A reflective prolog[1]. [1] Costantini,S. and Lanzarone,G.A., Metalevel Representation of Analogical Inference, LNAI549, 1991, 460-464
Experiment results • Code can be added or removed dynamically; • Cross reference between basic case and any selected PPS case is needed in grinding; • Granules from any case are compounded to form some high-level granules; • Granules are in shape of CLOS object; • Compounding is based on CLOS mechanisms;
(defmethod prove ((clause query-clause)) (catch 'end-query (let* ((var-bindings (make-new-names clause)) (goals (clause-body (instantiate clause var-bindings)))) (satisfy-goal-list goals '(nil) #'print-solution) t))) Basic case, granule <prove:> 3 MOLOG life cycle 1 2 4 ?- load(8q.pro). (defmethod prove :around ((q query-clause)) (time (call-next-method))) Selected case, similar granule (1)The timing case ?- queen([1,2,3,4],?l).
Execution Result: Continue search?(Y or N): yElapsed Real Time = 15.04 secondsTotal Run Time = 10.88 secondsUser Run Time = 10.76 secondsSystem Run Time = 0.12 secondsProcess Page Faults = 32Dynamic Bytes Consed = 0There were 3 calls to GCno?- 1 2 ;;; Dribble file "dm-time.dat" startedT> (molog)?- load(8q.pro).yes?- metacall("(load \"dm-time\")").;;; Loading source file "dm-time.lisp"#P"/home/zyl/clos300/n/dm-time.lisp" yes?- queen([1,2,3,4],?l).?L = [3,1,4,2]Continue search?(Y or N): y?L = [2,4,1,3] 3 (in-package 'molog) (defmethod prove :around ((q query-clause)) (time (call-next-method))) 4
(2)The RP case The metalevel architecture p(a). equivalent("b","a"). solve(%p($x)):- equivalent($x,$y),solve(%p($y)). /* 1 base level */ /* 2 metalevel */ /* 3 mel-level */ Referenced Goal Will be de-referenced into a base goal that is solved at base level
p(a). /*base level*/ equivalent("b","a"). /*metalevel*/ solve(%p($x)):-equivalent($x,$y),solve(%p($y)). /*mel lelvel*/ Solve ?-p(b) => solve goal p(b) => failed; Transform it into a mel goal, solve(<p>(“b”)), by reference; solve it; By mel clause, new goals equivalent(“b”,$y) and solve(<p>($y)) are derived with {<p>/%p, “b”/$x} With metalevel clause, the 1st goal succeeds, where {“a”/$y} The 2nd goal is de-referenced into a base level goal, p(a). And it succeeds. So the answer is yes.
Possible granules • define classes • make instances • goal solving • variable substitutions 1.4.1 molog-variable 1.4.1.2 metavariable 1.4.1.2.1 predicate-metavar ;%p 1.4.1.2.2 general-metavar ;$v 1.4.3 molog-constant 1.4.3.2 metaconstant 1.4.3.2.1 quoted-namecons ;e.g., "c", "?v" 1.4.3.2.2 bracketed-namecons ;e.g., <pred> • p(a). • equivalent("b","a"). • solve(%p($x)):-equivalent($x,$y),solve(%p($y)).
Possible granules prove print-solution satisfy-goal-list satisfy-goal Solving RP goals try-predicate Clause tree search try-clause-list try-clause RP variable substitution unify instantiate Variable substitution var-replace
Code for an added granule (defmethod satisfy-goal :around ((goal term) rest-goals env cont) (let ((class-name (class-name (class-of goal)))) (ecase class-name (term (call-next-method) (satisfy-goal (reference goal) rest-goals env cont)) (mel-term-class (multiple-value-bind (new-goal new-env) (dereference goal env) (satisfy-goal new-goal rest-goals new-env cont))) (refer-term-class (call-next-method)))))
Making RP instances Object creation make-term Class definition make-clause Define RP classes Parsing assert-clause make-molog-atom make-molog-structure defclass Possible granules
:-nl,write("==> Reflective Prolog..."), metacall((load "dm-rp.lisp")), nl,write("==>Example 3...").:-load(dm-rp2.pro), language(jack,?l).:-nl,write("==>Example 2..."), load(dm-rp1.pro), beautiful(cinderella). (in-package 'molog) (defclass direct-query-clause (query-clause) () ) (defmethod make-clause :around ((head null) (tail cons)) (change-class (call-next-method) 'direct-query-clause)) (defmethod assert-clause ((clause direct-query-clause)) (let* ((q (call-next-method)) (val (prove q))) (if val (format t "~%no") (format t "~%yes")) q)) View the results?
Summary • Granule compounding is based on method combination and class definition, or add-method/add-class; • Two kinds of “granules”: classes and methods; • Contexts are still implicit things in programming; But have been considered in every PPS cases; • By grinding, granules of the basic case and selected PPS cases can be compounded. • Context distribution is just a design concern.
5. Code Granulation Space • A layered view of granule collection; • Goal: to address unfitness in a well-formed and multi-layered framework; • Some issues:
Similarity detection. The main objective of program grinding is to localize unfitness by similarity analysis between PPS cases in the domain. Therefore, code similarity of granules indicates a more general granule is compounded. • Context distribution. The goal is to determine the relationships between PPS case and granules. A general idea about context distribution is that each granule is only responsible for nice fitness in its own context. • Zooming-in/zooming-out. Zooming-in and zooming-out are basic mechanisms to describe granulation layer: the low-level granules are compounded into high-level granules in code granulation space.
6. Related Work • Aspect-oriented programming AOP provides a means of grinding by which the code granules can be classified according to the aspects they belong. As the result, these code granules can be compounded and therefore form a granulation layer where every aspects are upper level granules. Aspect implies that it is sensitive to context. • Object-oriented programming Classes and methods can be special cases of code ingredients and granules in GOP. And sub-classing and message-passing can be special cases of granulation.
Related Work (cont.) • Reflection Reflection supports the program to deal with its own facilities in the course of domain problem solving. Provide language constructs or facilities to deal with the program’s context in more explicitly than non-reflective languages. The unfitness phenomenon has been explored in a certain extent with reflective facilities. • Component-based design Reusable components provide similar functionality as granules in order to localize special behavior and separate them with the other part of the system. • Generative programming a program can be partially derived from the existing programs.
7. Conclusions • Unfitness phenomenon exists in many software systems; • One way to deal with unfitness is to localize it in the program; • Unfitness of program can be represented with unfitness of granules. • Cross-reference between PPS cases is necessary for grinding programs into granules.
GOP Research Directions • Practice and application of granule-oriented programming; • Foundations of program grinding, code granulation space, and granule compounding; • Development of granule-oriented programming toolkit; • Technologies of granule-oriented software development; etc.
REFERENCES • Chaudron, M. R. V. and Laar, F.V. An upgrade mechanism based on publish/subscribe interaction. In Workshop on Dependable On-line Upgrading of Dist. Systems, COMPSAC 2002, (Oxford, England), Aug. 2002. • Czarnecki, K. and Eisenecker, U.W. Generative programming – methods, tools, and applications, Addision-Wesley, 2000 • Kiczales, G. Hilsdale, E., Hugunin, J., Kerstn, M., Palm, J. and Griswold, W. An Overview of AspectJ. In proc. European Conference on Object-Oriented Programming, 2001, Springer-Verlag LNCS 2072. • Smith, B.C. Reflection and Semantics in LISP. In Proceedings of the Symposium on Principles of Programming Languages (POPL). ACM. (1984) 23-35 • Szyperski, C. Component Software – Beyond Object-Oriented Programming, 2nd Ed., Addison-Wesley, ACM Press, 2002
LISP&CLOS Steele, G.L. Common Lisp the Language, 2nd edition, Digital Press, 1990 Kiczales, G. Rivieres, J. and Bobrow, D.G. The Art of the Metaobject Protocol. MIT Press, Cambridge, 1991 Meta-reasoning in Logic Costantini, S. Meta-reasoning: a survey. In: Robert, A. et al. (eds.) Computational Logic: Logic Programming and Beyond, Lecture Notes in artificial Intelligence 2407-2408, Springer-Verlag, 2002. Granular Computing Some GrC papers: http://www.cs.uregina.ca/~yyao/ Molog Zhao, Y.L. Zheng, S.Q. A logical meta-level architecture based on meta-objects. in Technical Digest of International Symposium on Information Science and Technology, International Academic Publishers (Beijing, 1996), 253-256.