An Active and Intelligent Agent for Component ... - Semantic Scholar

3 downloads 24 Views 147KB Size Report
software developer makes the decision to formulate a query. On the ... observing a program editor, Emacs. Through ... program and a component they have learned in the past and know ..... CodeBroker is similar to Apple Data Detector in the.

An Active and Intelligent Agent for Component Location Yunwen Ye Software Research Associates Inc. 3-12 Yotsuya, Shinjuku, Tokyo 160-004 Email: [email protected]

Abstract Even though component-based software reuse has been shown to increase both the quality and efficiency of software development, there are still major barriers to its wide spread acceptance. Passive and conversational interface-based reuse repository systems support the developer only when he already knows a relevant component exists. In contrast, this paper describes an active and intelligent software agent, CodeBroker, which automates the location of reusable components. CodeBroker runs concurrently in the background of the development environment. Based on the developer’s actions, it locates relevant components and delivers them for software developers to reuse.

1 Introduction Component reuse improves both the quality and efficiency of software development [1]. Successful component reuse consists of three phases: locating the reusable components, comprehending them, and finally integrating them into one’s current work. Each of these phases is important in its own right and they all need tool support. As a supporting tool for reusable component location, a reuse repository system has three constituents: a collection of reusable components, a retrieval mechanism, and an interface for software developers to interact with. Most reuse repository systems have a conversational interface which is implemented either as a command line or a graphical user interface (GUI). To find a reusable component, software developers either type command lines or use direct manipulation to search or browse components. Conversational interfaces are passive because they have to be invoked explicitly by software developers. Those systems cannot support developers who do not attempt to reuse in the first place. This is a major problem, because empirical studies have shown that no attempt to reuse is the most significant failure mode of reuse [2]. In this paper, we argue, based on previous empirical studies and cognitive analysis, that the following two factors are the keys that prevent software developers from attempting to reuse: •

they do not know the existence of components that can be reused in the current situation; or

they think reuse is too costly to try it.

Brent Reeves TwinBear Research Boulder CO 80303, USA Email: [email protected] Conversational interface-based reuse repository systems can not overcome these two obstacles because they are designed to carry out the location task only after the software developer makes the decision to formulate a query. On the other hand, software reuse is not a standalone process, it takes place in the context of a development task. Inasmuch as most development activities are performed under computer-based development environments, it is possible for reuse repository systems to play an active role to promote the reuse of those components which would otherwise be missed by software developers who make no attempt to find them. Such active support can be realized through the implementation of software agents. Software agents are software entities that function continuously and autonomously in response to changes in their running environment without requiring constant human guidance or intervention [3]. This paper describes an active intelligent software agent, CodeBroker, for reusable component location. CodeBroker runs continuously in the background observing a program editor, Emacs. Through monitoring the developer’s actions in the context of the program editor, it infers requirements for reusable components from partially constructed programs. Without being explicitly invoked, components matching the inferred reuse requirements are retrieved and presented to the software developer.

2 Approaches to Component Location 2.1 Locating Reusable Components Most current reuse repository systems use a conversational interface. Software developers have to take the initiative to start the locating process. Through conversational interfaces, there are basically two ways for software developers to locate reusable components: browsing or searching. Browsing. In browsing, software developers follow a hierarchical structure, usually arranged according to inheritance relationships, to locate a component fitting their needs. Searching. In searching, software developers formulate a query, and the reuse repository system returns components similar to the query based on the retrieval mechanism employed. There is good computation support for searching, so it is relatively fast, but formulating queries is a cognitively

challenging task because software developers have to choose the right words that the reuse repository system can understand. People tend to find browsing interfaces more fun than searching interfaces because they do not need to commit resources at first and can incrementally develop their requirements after evaluating the components along the way [4]. However, browsing is not scalable; when the information space gets large, following the right link in a browsing interface requires users to have a good understanding of the whole system, which is very difficult for less experienced developers [5]. The information space is simply too large.

developers have their individual reuse repositories “in memory,” so they can reuse-by-memory or reuse-byrecall [7]. For those components that have not yet been internalized, software developers have to resort to the mode of reuse-by-anticipation. The activation of reuseby-anticipation mode relies on the following two enabling factors:

2.2 Reuse Modes

3 Problems with Conversational Interfaces of Reuse Repository Systems

From the perspective of software developers, there are three reuse modes based upon their knowledge about the contents of a reuse repository: reuse-by-memory, reuse-by-recall and reuse-by-anticipation. Reuse-by-memory. In the reuse-by-memory mode, a developer may notice similarities between the new program and a component they have learned in the past and know very well. Therefore, they can reuse it easily even without the support of a reuse repository system.


developers anticipates the existence of reusable components; and


they perceives that the reuse cost is cheaper than developing the module from scratch.

Because of the passive nature of conversational interfaces of reuse repository systems, they become useful only after a software developer makes the decision to use them. However, as we will see in the following analysis, due to the existence of information islands, reuse utility concerns, and cognitive biases against reuse, software developers often do not make

Reuse-by-recall. In the reuse-by-recall mode, software

L4 L2 L3


(Vaguely Known)


(Well Known)

Unknown Components

Figure 1: Different Levels of Developers’ Knowledge about A Reuse Repository

developers know that some reusable components have similar functionality, but they do not know their exact names and functionality. They need to search the reuse repository to find them. A searching interface can serve most of the needs in this mode. Reuse-by-anticipation. In the reuse-by-anticipation mode, software developers anticipate, under the guidance of their previous experience and domain knowledge, the existence of certain reusable components, and attempt to locate them by browsing or searching. In this mode, the ease of locating what they want is crucial for the adoption of the reuse approach. Software developers have little resistance to the first two modes of reuse. As reported by Isoda, developers reuse those components repeatedly once they have reused them once [6]. This explains why individual ad hoc reuse has been taking place while organization-wide systematic reuse has not seen the same success: software

any attempt to use them.

3.1 Information Islands Successful operation of reuse-by-anticipation requires software developers to anticipate the existence of reusable components. Unfortunately, software developers’ anticipation of available reusable components does not always match real repository systems. Empirical studies have found that users (software developers in our case) have four levels of knowledge about the information space provided by a computer system, e.g., a reuse repository (Fig. 1) [8]. In Fig. 1, ovals represent a developer’s levels of knowledge of a reuse repository, and the rectangle, labeled L4, represents the actual information space of the repository. L1 represents those components that are well known, easily employed and regularly reused by a software developer. L1 corresponds to the reuse-bymemory mode. L2 contains components known vaguely

and reused only occasionally by a software developer, and they often require further evaluation or exploration before they can be reused. L2 corresponds to the reuseby-recall mode. L3 represents what software developers believe about the repository. Notice that we explicitly represent mistaken beliefs. L3 corresponds to the reuseby-anticipation mode. Many components fall in the area of (L4 – L3), which means their existence is not known to the software developer. Consequently, there is little possibility for the developer to reuse them because people do not ask for what they do not know [9]. Components in (L4 – L3) thus become information islands, inaccessible to software developers through the conversational interfaces of reuse repository systems [10, 11].

3.2 Reuse Utility Perceived low reuse utility is another reason that prohibits software developers from attempting to reuse. Human beings try to be utility maximizers in the decision-making process [12]. Reuse utility is the ratio of reuse value to reuse cost. While there are considerable costs involved in the set up of a reuse repository, from the perspective of software developers, their perception of reuse cost consists of the cost only associated with the reuse process—cost of the location, comprehension, and modification of reusable components. The reduction of location cost leads to the increase of reuse utility that in turn leads to more frequent reuse. Component location costs can be further broken down into the following items:

developers, developing from scratch is still the proven strategy; therefore, they are more likely to just start writing software from scratch. Another bias against reuse is loss aversion—a tendency to be far more sensitive to losses than to possible values [12]. Starting a reuse process requires a mental switch. The losses of working memory and working time are immediate, and the benefits are still unclear. Reducing the reuse losses to minimum is thus an important aspect of reuse systems.

Development Environment

User Locating Reuse Repository System Reusing

Development Environment

Conversational Interface-Based Reuse Process

(1) The cost of acquiring the metaknowledge of reuse repository, i.e., knowing the existence of reusable components.

Development Environment

(2) The cost of specifying the reuse query based on the current task. (3) The cost of executing the search process to find what is needed. (4) The cost of switching back and forth from working environments to reuse repository systems which causes the loss of working memory and the disruption of workflow; Reuse repository systems with conversational interfaces aim mainly at the reduction of the cost of item (3), and do not reduce the other costs.

3.3 Cognitive Biases against Reuse The estimation of reuse value and cost made by software developers is quite subjective and suffers from cognitive biases against reuse. Developers tend to underestimate reuse value and overestimate reuse cost. Once problem solvers have discovered a strategy that “gets the job done,” they are less willing to discover new strategies until they are completely stuck with the old strategy [12]. Even today, for most software



Reusable Component s

Reuse Agent

Reuse Agent-Based Reuse Process Figure 2: Comparison of Two Types of Interface to Reuse Repository Systems

4 Agent-Based Reuse Repository Systems A reuse agent is an autonomous interface agent that delivers reusable components without being given explicit queries. It monitors software developers’ activities in development environments and locates components relevant to the current task. Reuse agents hide the interface to reuse repository systems from

software developers and seamlessly integrate reuse repository systems into the development environments. Figure 2 illustrates the difference between conversational interface-based reuse repository systems and reuse agent-based reuse repository systems. The following paragraphs analyze the benefits of reuse agents in detail. A Bridge to Information Islands. Conversational interface-based reuse repository systems offer little support for software developers to reuse those software components residing on information islands. Reuse agents compare the current development task with reusable components and proactively present relevant ones to developers to promote the opportunity of reuse.

software developers’ needs for reusable components by monitoring their low-level interactions with the development environment. CodeBroker supports Java developers. Its repository consists of Java core API library and JGL3.0 (Java General Library from ObjectSpace Inc.) A reusable component is either a class or a method from these libraries.

Well-Informed Decision Making. Psychological studies of the human decision-making process have shown that the presence of other alternatives affects the final decision dramatically [12]. The presence of reusable components, automatically located by reuse agents, reminds software developers of possible alternative. It prompts software developers to make well-informed decisions after giving due consideration to reuse. Reduction of Reuse Cost. Reuse agents reduce the cost of reuse by streamlining developing activities and component locating activities. Software developers can access reusable components without switching their working contexts from developing to component locating. This is less disruptive to their workflow and helps overcome the loss aversion by reducing the immediate working memory loss and making the hidden value of reuse more conspicuous. Software developers do not need to explicitly specify any reuse queries and do not need to invoke a search explicitly. All of these factors contribute to the reduction of reuse cost and the increase of reuse utility. Augmenting Human Memory. Software developers easily reuse components they know well, because their memories assume the role of reuse repository systems and they do not need to go through an explicit and separate retrieval process. Reuse agents, acting as assistants of developers, can extend their memory capacity by loading those relevant reusable components into the working environment automatically.

5 Implementation of An Reuse Agent CodeBroker is an active and intelligent agent supporting the location of reusable components. Running continuously behind a program editor, it analyzes coding activities in order to create reuse queries, and retrieves and presents relevant components. CodeBroker is active because it requires no explicit invocation from software developers. It is intelligent because it can infer

Figure 3: Reusable Components Delivered Based on Comments

Figure 3 shows an example. Reusable components that are relevant to the programming task in the editor are displayed in the lower buffer.

5.1 The System Architecture The system architecture of CodeBroker is shown in Fig. 4. It consists of three subsystems: Listener, Fetcher and Presenter. Listener extracts and formulates reuse queries by monitoring developers’ interactions with the program editor—Emacs. Those queries are then passed to Fetcher, which retrieves components matching the queries. Retrieved components are delivered in the Reusable Components Info display (RCI-display) by Presenter, after it has removed unwanted components based on the user profile of the developer.

5.2 Capturing Reuse Requirements For a reuse agent to deliver reusable components related to the current task, it must have an understanding of the task. This section describes this understanding and its implementation.

5.2.1 Concept, Constraint and Code A program has three aspects: concept, code and constraint. The concept of a program is its functional purpose; the code is the embodiment of the concept; and the constraint regulates the environment in which the program runs.

Program Editor Developers

Delivered Components

RCI-display Manip

Working Products


Presenter Delivers


Update User Profile Automatic update

Listener Analyzes

Concept Queries

Retrieved Components

Fetcher Retrieves

Signature Indexing

Constraint Queries

Data Action

Concept Indexing

Reuse Repository

Data flow (bubble shows the contents) Control flow (label shows the action)

Figure 4: The System Architecture of CodeBroker

In today’s environments, a program includes more than just source code. Software development is essentially a cooperative process among many developers, therefore programs must include both formal information for its executability and informal information for its readability by peer developers. Informal information includes structural indentation, comments, and identifier names. Comments and identifier names are important beacons for the understanding of programs, because they reveal the important concepts of programs [11]. The constraint of a program is manifested by its signature. A signature is the type expression of a module1, and defines its syntactical interface. The signature of a method specifies what type of input it takes and what type of output it produces. For example, for the method, int getRandomNumber (int from, int to)

its signature is getRandomNumber: int x int -> int

Combining the conceptual information revealed through comments and the constraints revealed through signatures, it is possible to find a component that can be reused in the current task, if the component shows both high relevance in concepts and high compatibility in constraints. Fortunately, in current development practices and development environments, comments and signature definitions come sequentially before the code implementation of programs. This gives reuse agents a chance to deliver reusable components before the 1

In this paper, a module refers to either a class or a method. It has the same connotation as a component. To avoid confusion, we use components to refer to reusable modules in the reuse repository and modules to refer to the programs under development.

program is implemented, and after it has captured the comments and signatures and used them to locate relevant components.

5.2.2 Implementation of Listener The goal of the subsystem Listener is to construct reuse queries based on an analysis of the current task of the software developer. Queries are extracted from comments and signatures. Concept queries are queries extracted from comments to reflect the conceptual requirements, i.e., functional requirements, of modules; constraint queries are extracted from signature definitions to represent the constraint requirements of modules. The specific comments extracted by Listener are document comments in Java programs. Document comments are special programming conventions in Java. They begin with /** and continue until the next */, and immediately precede the declaration of a module. Contents inside document comments are meant to describe the functionality, i.e., the concepts, of the following module. Whenever a software developer finishes the definition of a document comment, Listener extracts the contents, and creates a conceptual query. Let us look back at the example shown in Fig. 3. A software developer wants to generate a random number between two integers, and before he or she implements it, i.e., writes the code part of the program, the task is indicated in the document comment. As soon as the comment is finished (based on cursor placement), Listener extracts the content: “Create a random number between two limits.” This is used as a conceptual query to be passed to Fetcher and Presenter, which will deliver, in the RCI-display, components whose functional descriptions are similar based on the retrieval mechanism described later.

Conceptual similarity is often not enough for components to be reused, because the type of reusable components should be compatible with that of the module. Type compatibility constraint is manifested in the signature of a module. As the software developer proceeds to declare the signature, it is extracted by Listener to create a constraint query. As Fig. 5 shows, as soon as the developer types the left bracket {, (just before the cursor), Listener creates a constraint query in the form of signatures: int x int -> int, and passes it to Fetcher and Presenter. Fig. 5 shows the result after

Figure 5: Reusable Components Delivered Based on Both Comments and Signature

the constraint query is processed. Notice that the first component in the RCI-display in Fig. 5 has exactly the same signature, shown in the second line of the pop-up window, as the one extracted from the editor and it can be immediately reused.

5.3 Retrieving Similar Components The retrieval mechanism used by Fetcher is the combination of Latent Semantic Analysis (LSA) [13] and Signature Matching (SM) [14]. LSA is used to compute the similarity existing between conceptual queries created by Listener and documents of reusable components in the repository. SM is used to determine the compatibility between constraint queries and signatures of components in the repository.

term by document matrix in which entries are normalized scores of the term frequency with which the term occurs in a given document. Terms are words used in documents with high-frequency words removed. The term by document matrix is then decomposed, by means of singular value decomposition, into the product of three matrices: a left singular vector, a diagonal matrix of singular values, and a right singular vector. These matrices are then reduced to k dimension by eliminating small singular values; the value of k often ranges in 40400 while it still remains an open question in determining the best value of k. A new matrix, viewed as semantic space of the domain, is reconstructed through the production of three reduced matrices. In this new matrix, each row represents the position of each term in the semantic space. Terms are re-represented in the newly created semantic space. The reduction of singular values is important because it captures only the major, overall pattern of associative relationships among terms by ignoring the noises accompanying most automatic thesaurus construction based simply on the co-occurrence statistics of terms [15]. After the semantic space is created, each reusable component is represented as a vector in the semantic space based on the indexing terms contained, and so is a query. The similarity of a query and a reusable component is thus determined by the Euclidean distance of the two vectors. Comparing to traditional free-text indexing techniques, LSA makes it possible to retrieve on the basis of conceptual contents. It is also reported that LSA can improve up to 30% in terms of retrieval effectiveness [15].

5.3.2 Signature Matching Signature matching is the process to determine the compatibility of two components in terms of their signatures. It is an indexing and retrieval mechanism based on the constraints of programs. The basic form of a signature of a method is Signature:InTypeExp->OutTypeExp,

where InTypeExp and OutTypeExp are type expressions resulted from applying Cartesian product constructor onto the input parameter types and output parameter types respectively.

5.3.1 Latent Semantic Analysis

Two signatures

LSA is a technology to improve free-text document retrieval. Free-text indexing suffers from the conceptbased retrieval problem, that is, if software developers searching for reusable components use words different from those used in the descriptions of components, the search will not succeed. By constructing a large semantic space of words to capture the overall pattern of associative relationships among words, LSA facilitates concept-based retrieval.

Sig1:InTypeExp1->OutTypeExp1 Sig2:InTypeExp2->OutTypeExp2 match if and only if InTypeExp1 is in structural conformance with InTypeExp2 and OutTypeExp1 is in structural conformance with OutTypeExp2. Two type

The indexing process of LSA starts with creating a semantic space with a large corpus of training documents in a specific domain. It first creates a large

expressions are structurally conformable if they are formed by applying the same type constructor to structurally conformant types. The above definition of signature matching is very restrictive because it misses some components whose signature does not exactly match, but are similar enough to be reusable after slight modification. Partial signature

matching relaxes the definition of structural conformance of types: A type is considered as conforming to its more generalized form or more specialized form [11]. The constraint compatibility value between two signatures is the production of the conformance value existing among their types. The type conformance value is 1.0 if two types are in structural conformance according to the definition of the programming language; it drops a certain percentage if one type conversion is needed, or there is an immediate inheritance relationship existing between them, and so forth.

5.4 Adapting to Each Developer The retrieved reusable components are presented in the RCI-display in decreasing order of similarity value. Each component is accompanied by its rank of similarity, similarity value, name and a short description (Fig. 3 and Fig. 5). Developers who are interested in a particular component can launch, by a mouse click, an external HTML browsing interface, to go to the corresponding place of the full Java documents. When signatures are taken into consideration, the similarity value is the average value of the conceptual similarity value returned by LSA and the constraint compatibility value returned by SM. The goal of active delivery in CodeBroker is to show software developers those components that fall into L3 (reuse-by-anticipation) and (L4 - L3) (information islands) in Fig. 1. Therefore, delivery of components from L2 (reuse-by-recall) and L1 (reuse-by-memory), especially L1, might be of little use, with the risk of making the unknown, really needed components less salient. Presenter uses a user profile for each developer to adapt the components retrieved by Fetcher to the developer’s knowledge level of the repository, to ensure that those components already known to the developer are not delivered. A user profile is a file listing all components known to a developer. Each item in the list could be a package, a class, or a method. A package or a class indicates none of their method components should be delivered; a method indicates that method only should not be delivered. The profile can be edited by developers manually, or updated through the interaction with CodeBroker. A right mouse click on the component delivered by Presenter brings the Skip Components Menu, as shown in Fig. 5. A developer can select the All Sessions command, which will update his or her user profile and that component, or components from that class or that package will not be automatically delivered again in later sessions.

6 Related Work 6.1 Agents for Information Exploration CodeBroker is similar to information agents. The closest work to CodeBroker is Remembrance Agent that augments human memory by proactively presenting the documents relevant to the user’s current writing [16]. Although its goal is to remind users of those documents that might have been forgotten, it makes no attempt to differentiate those documents that are still remembered and those forgotten. Another similar agent is Letizia that assists users in browsing the World Wide Web by providing suggestions of web pages within a few links of the current page [4]. It monitors and analyzes the past browsing activities of a user to build up a profile of user interests. This profile is then used to determine the most related web pages. In addition to the difference of application domains and information retrieval mechanisms used, CodeBroker is also different because it considers both the relevance to the task and the relevance to the user. Remembrance Agent seeks for information relevant to the task only and Letizia seeks for information relevant to the user only.

6.2 Agents for Streamlining Workflow CodeBroker is similar to Apple Data Detector in the attempt to reduce the excessive context switching. ADD smoothes the routine workflow of extracting structured information from everyday documents and performing the consequent actions automatically upon the request from users [17]. For example, when a portion of an email selected by users contains a string like “”, ADD is able to recognize it as a web address, and shows associated actions, such as “store as bookmarks”. If users choose the action, ADD executes it. Both CodeBroker and ADD take advantage of the semi-formal structure existing in the working environment, and automate the following actions to improve the ease of information manipulation. However, ADD is not active while CodeBroker is.

6.3 Software Reuse Repository Systems There has been much research on software reuse repository systems. Current reuse systems are limited due to their use of conversational interfaces. CodeBroker is most similar to those reuse repository systems that adopt the information retrieval approach to the indexing and retrieving of reusable components. Some systems index components based on the associated documents [18]; and some extract information directly from comments and names from source codes [19]. CodeBroker is also similar to those systems that use signature to index reusable components [14]. CodeBroker is more effective because (1) it uses LSA as its indexing and retrieving mechanism, and

(2) it utilizes both conceptual information and constraint information to retrieve the relevant components. Our future work includes doing more formal studies to document these claims.

7 Summary Research on various reuse repository systems has mainly focused on the retrieval mechanism and postulated that software developers know when to engage in a reuse process. But systematic analysis of reuse failures has indicated that no attempt to reuse is the biggest barrier to reuse [2]. We described an active and intelligent reuse agent CodeBroker that delivers reusable components into the current working environment of developers so that developers can readily access task-related and user-specific reusable components without making the explicit decision to formulate a query. CodeBroker is meant to complement traditional conversational interfaces of reuse repository systems by providing software developers with the access to those components whose existence is not even known to them. It can also reduce the cost of component location process to increase the utility of reuse so that reuse becomes easier and more appealing to software developers.

References [1] Basili, V., L. Briand, and W. Melo, “How Reuse Influences Productivity in Object-Oriented Systems,” Commun. of the ACM, 39(10), pp. 104-116, 1996. [2] Frakes, W. B. and C. J. Fox, “Quality Improvement Using a Software Reuse Failure Modes Models,” IEEE Transactions on Software Engineering, 22(4), pp. 274279, 1996. [3] Bradshaw, J. M., “An Introduction to Software Agents,” in Software Agents, J. M. Bradshaw, Ed. Menlo Park, CA: AAAI Press, 1997, pp. 1-46. [4] Lieberman, H., “Autonomous Interface Agents,” In Proceedings of Human Factors in Computing Systems 1997, Atlanta, GA USA, pp. 67-74.,1997. [5] Green, T. R. G., “The Nature of Programming,” in Psychology of Programming, J.-M. Hoc, T. R. G. Green, R. Samurcay, and D. J. Gilmore, Eds.: Academic Press, 1990, pp. 21-43. [6] Isoda, S., “Experiences of a Software Reuse Project,” Journal of Systems and Software, 30, pp. 171-186, 1995. [7] Mili, H., F. Mili, and A. Mili, “Reusing Software: Issues and Research Directions,” IEEE Transactions on Software Engineering, 21(6), pp. 528-562, 1995. [8] Fischer, G., A. C. Lemke, and T. Schwab, “KnowledgeBased Help Systems,” In Proceedings of Human Factors in Computing Systems 85, San Francisco, CA, pp. 161167.,1985. [9] Fischer, G. and B. N. Reeves, “Beyond Intelligent Interfaces: Exploring, Analyzing and Creating Success Models of Cooperative Problem Solving,” in Readings in Human-Computer Interaction: Toward the Year 2000, R. Baecker, J. Grudin, W. Buxton, and S. Greenberg, Eds.,

2nd ed. San Francisco, CA: Morgan Kaufmann Publishers, 1995, pp. 822-831. [10]Engelbart, D. C., “Knowledge-Domain Interoperability and an Open Hyperdocument System,” In Proceedings of Computer Supported Cooperative Work 1990, New York, NY, pp. 143-156.,1990. [11]Ye, Y. and G. Fischer, “Promoting Reuse with Active Reuse Repository Systems,” In Proceedings of the 6th International Conference on Software Reuse, Vienna, Austria, pp. (to appear).,2000. [12]Reisberg, D., Cognition. New York, NY: W. W. Norton & Company, 1997. [13]Landauer, T. K. and S. T. Dumais, “A Solution to Plato's Problem: The Latent Semantic Analysis Theory of Acquisition, Induction and Representation of Knowledge,” Psychological Review, 104(2), pp. 211-240, 1997. [14]Zaremski, A. M. and J. M. Wing, “Signature Matching: A Tool for Using Software Libraries,” ACM Transactions on Software Engineering and Methodology, 4(2), pp. 146170, 1995. [15]Deerwester, S., S. T. Dumais, G. W. Furnas, T. K. Kandauer, and R. Harshman, “Indexing by Latent Semantic Analysis,” Journal of the American Society for Information Science, 41(6), pp. 391-407, 1990. [16]Rhodes, B. J. and T. Starner, “Remembrance Agent: A Continuously Running Automated Information Retrieval System,” In Proceedings of the First International Conference on The Practical Application of Intelligent Agents and Multi Agent Technology, London, UK, pp. 487-495.,1996. [17]Nardi, B. A., J. R. Miller, and D. J. Wright, “Collaborative, Programmable Intelligent Agents,” Commun. of the ACM, 41(3), pp. 96-104, 1998. [18]Maarek, Y. S., D. M. Berry, and G. E. Kaiser, “An Information Retrieval Approach for Automatically Constructing Software Libraries,” IEEE Transactions on Software Engineering, 17(8), pp. 800-813, 1991. [19]Etzkorn, L. H. and C. G. Davis, “Automatically Identifying Reusable OO Legacy Code,” IEEE Computer, 30(10), pp. 66-71, 1997.

Suggest Documents