scispace - formally typeset
Search or ask a question

Showing papers on "Program transformation published in 2009"


Proceedings ArticleDOI
Steven P. Reiss1
16 May 2009
TL;DR: This work lets users specify what they are looking for as precisely as possible using keywords, class or method signatures, test cases, contracts, and security constraints, and an open set of program transformations to map retrieved code into what the user asked for.
Abstract: Our goal is to use the vast repositories of available open source code to generate specific functions or classes that meet a user's specifications. The key words here are specifications and generate. We let users specify what they are looking for as precisely as possible using keywords, class or method signatures, test cases, contracts, and security constraints. Our system then uses an open set of program transformations to map retrieved code into what the user asked for. This approach is implemented in a prototype system for Java with a web interface.

348 citations


Proceedings ArticleDOI
21 Jan 2009
TL;DR: This work presents Certicrypt, a framework that enables the machine-checked construction and verification of code-based proofs, built upon the general-purpose proof assistant Coq, and draws on many areas, including probability, complexity, algebra, and semantics of programming languages.
Abstract: As cryptographic proofs have become essentially unverifiable, cryptographers have argued in favor of developing techniques that help tame the complexity of their proofs. Game-based techniques provide a popular approach in which proofs are structured as sequences of games and in which proof steps establish the validity of transitions between successive games. Code-based techniques form an instance of this approach that takes a code-centric view of games, and that relies on programming language theory to justify proof steps. While code-based techniques contribute to formalize the security statements precisely and to carry out proofs systematically, typical proofs are so long and involved that formal verification is necessary to achieve a high degree of confidence. We present Certicrypt, a framework that enables the machine-checked construction and verification of code-based proofs. Certicrypt is built upon the general-purpose proof assistant Coq, and draws on many areas, including probability, complexity, algebra, and semantics of programming languages. Certicrypt provides certified tools to reason about the equivalence of probabilistic programs, including a relational Hoare logic, a theory of observational equivalence, verified program transformations, and game-based techniques such as reasoning about failure events. The usefulness of Certicrypt is demonstrated through various examples, including a proof of semantic security of OAEP (with a bound that improves upon existing published results), and a proof of existential unforgeability of FDH signatures. Our work provides a first yet significant step towards Halevi's ambitious programme of providing tool support for cryptographic proofs.

257 citations


Proceedings ArticleDOI
09 Nov 2009
TL;DR: A privacy-protection framework is proposed that partitions a genomic computation, distributing the part on sensitive data to the data provider and the parts on the pubicData to the user of the data through program specialization.
Abstract: In this paper, we present a new approach to performing important classes of genomic computations (e.g., search for homologous genes) that makes a significant step towards privacy protection in this domain. Our approach leverages a key property of the human genome, namely that the vast majority of it is shared across humans (and hence public), and consequently relatively little of it is sensitive. Based on this observation, we propose a privacy-protection framework that partitions a genomic computation, distributing the part on sensitive data to the data provider and the part on the pubic data to the user of the data. Such a partition is achieved through program specialization that enables a biocomputing program to perform a concrete execution on public data and a symbolic execution on sensitive data. As a result, the program is simplified into an efficient query program that takes only sensitive genetic data as inputs. We prove the effectiveness of our techniques on a set of dynamic programming algorithms common in genomic computing. We develop a program transformation tool that automatically instruments a legacy program for specialization operations. We also demonstrate that our techniques can greatly facilitate secure multi-party computations on large biocomputing problems.

98 citations


Proceedings ArticleDOI
12 Sep 2009
TL;DR: This paper develops a compile-time framework for data locality optimization via data layout transformation using a polyhedral model and demonstrates the effectiveness of the approach on a 16-core 2D tiled CMP.
Abstract: With increasing numbers of cores, future CMPs (Chip Multi-Processors) are likely to have a tiled architecture with a portion of shared L2 cache on each tile and a bank-interleaved distribution of the address space. Although such an organization is effective for avoiding access hot-spots, it can cause a significant number of non-local L2 accesses for many commonly occurring regular data access patterns. In this paper we develop a compile-time framework for data locality optimization via data layout transformation. Using a polyhedral model, the program's localizability is determined by analysis of its index set and array reference functions, followed by non-canonical data layout transformation to reduce non-local accesses for localizable computations. Simulation-based results on a 16-core 2D tiled CMP demonstrate the effectiveness of the approach. The developed program transformation technique is also useful in several other data layout transformation contexts.

80 citations


Proceedings ArticleDOI
22 Mar 2009
TL;DR: Performance results indicate that the profiles generated by Alchemist pinpoint strong candidates for parallelization, and can help significantly ease the burden of application migration to multicore environments.
Abstract: Effectively migrating sequential applications to take advantage of parallelism available on multicore platforms is a well-recognized challenge. This paper addresses important aspects of this issue by proposing a novel profiling technique to automatically detect available concurrency in C programs. The profiler, called Alchemist, operates completely transparently to applications, and identifies constructs at various levels of granularity (e.g., loops, procedures, and conditional statements) as candidates for asynchronous execution. Various dependences including read-after-write (RAW), write-after-read (WAR), and write-after-write (WAW), are detected between a construct and its continuation, the execution following the completion of the construct. The time-ordered {\em distance} between program points forming a dependence gives a measure of the effectiveness of parallelizing that construct, as well as identifying the transformations necessary to facilitate such parallelization. Using the notion of post-dominance, our profiling algorithm builds an execution index tree at run-time. This tree is used to differentiate among multiple instances of the same static construct, and leads to improved accuracy in the computed profile, useful to better identify constructs that are amenable to parallelization. Performance results indicate that the profiles generated by Alchemist pinpoint strong candidates for parallelization, and can help significantly ease the burden of application migration to multicore environments.

80 citations


Proceedings ArticleDOI
21 Jan 2009
TL;DR: The idea is to take a general-purpose language, Haskell, and write a higher-order function that takes (polymorphic) get-functions as arguments and returns appropriate put-Functions, inspired by relational parametricity and uses free theorems for proving the consistency conditions.
Abstract: A bidirectional transformation consists of a function get that takes a source (document or value) to a view and a function put that takes an updated view and the original source back to an updated source, governed by certain consistency conditions relating the two functions. Both the database and programming language communities have studied techniques that essentially allow a user to specify only one of get and put and have the other inferred automatically. All approaches so far to this bidirectionalization task have been syntactic in nature, either proposing a domain-specific language with limited expressiveness but built-in (and composable) backward components, or restricting get to a simple syntactic form from which some algorithm can synthesize an appropriate definition for put. Here we present a semantic approach instead. The idea is to take a general-purpose language, Haskell, and write a higher-order function that takes (polymorphic) get-functions as arguments and returns appropriate put-functions. All this on the level of semantic values, without being willing, or even able, to inspect the definition of get, and thus liberated from syntactic restraints. Our solution is inspired by relational parametricity and uses free theorems for proving the consistency conditions. It works beautifully.

79 citations


Journal ArticleDOI
TL;DR: The study reveals that large dependence clusters are surprisingly commonplace in C program source code, and most of the 45 programs studied have clusters of dependence that consume more than 10% of the whole program.
Abstract: A dependence cluster is a set of program statements, all of which are mutually inter-dependent. This article reports a large scale empirical study of dependence clusters in C program source code. The study reveals that large dependence clusters are surprisingly commonplace. Most of the 45 programs studied have clusters of dependence that consume more than 10p of the whole program. Some even have clusters consuming 80p or more. The widespread existence of clusters has implications for source code analyses such as program comprehension, software maintenance, software testing, reverse engineering, reuse, and parallelization.

75 citations


Proceedings ArticleDOI
21 Jan 2009
TL;DR: This paper proposes an extension to CTL named CTLVW (CTL with variables and witnesses) that is a suitable basis for the semantics and implementation of the Coccinelles program matching language, and formalizes and describes its use in the context of Coccinelle.
Abstract: Reasoning about program control-flow paths is an important functionality of a number of recent program matching languages and associated searching and transformation tools. Temporal logic provides a well-defined means of expressing properties of control-flow paths in programs, and indeed an extension of the temporal logic CTL has been applied to the problem of specifying and verifying the transformations commonly performed by optimizing compilers. Nevertheless, in developing the Coccinelle program transformation tool for performing Linux collateral evolutions in systems code, we have found that existing variants of CTL do not adequately support rules that transform subterms other than the ones matching an entire formula. Being able to transform any of the subterms of a matched term seems essential in the domain targeted by Coccinelle.In this paper, we propose an extension to CTL named CTLVW (CTL with variables and witnesses) that is a suitable basis for the semantics and implementation of the Coccinelles program matching language. Our extension to CTL includes existential quantification over program fragments, which allows metavariables in the program matching language to range over different values within different control-flow paths, and a notion of witnesses that record such existential bindings for use in the subsequent program transformation process. We formalize CTL-VW and describe its use in the context of Coccinelle. We then assess the performance of the approach in practice, using a transformation rule that fixes several reference count bugs in Linux code.

74 citations


Dissertation
27 May 2009
TL;DR: This thesis uses Stratego; a domain-specific programming language for the specification of program transformation systems based on strategic rewriting and introduces operations on dynamic rules which enabled it to describe data-flow optimisations such as constant-propagation, Copy propagation, common sub-expression elimination and dead code elimination at a high level of abstraction.
Abstract: In this thesis we study the implementation of program transformations at a high abstraction level. We believe this leads to better productivity of the transformation developer. A program transformation system is a computer program which main goal is the transformation of programs. There are several reasons for generating a program from another one. For instance to obtain an optimised version or to improve the clarity of the code for maintenance purposes. The specification of program transformation requires the specification of how and when to transform. For the specification of how to transform, rewriting is a natural and elegant paradigm to describe modifications to a program. Term rewriting is a computational model based on rewrite rules. A rewrite rule represents a single stepwise modification to a program. The specification of when to transform refers to the identification of all the enabling conditions of a particular transformation to take place. To find all information for activating an optimisation, a program transformation requires the aid of program analysis techniques. How and when to transform are known as program transformation and analysis respectively. Typically this tasks are separately implemented. For the implementation of program transformations we use Stratego; a domain-specific programming language for the specification of program transformation systems based on strategic rewriting. Stratego differentiates from a pure rewriting system in the use of an strategy (a Stratego program) to control the rewriting process. We focus on the implementation of data-flow optimisations. A data-flow optimisation requires to collect information which is valid on any possible execution path of a program. This information is exploited to perform optimisations to a program. Simple rewrite systems only based on rewrite rules can only access the information available in the term that is being transformed. However data-flow optimisations need to collect information which is located at different points of a program, thus a data-flow optimisation requires context-sensitive information for its realisation. Dynamic rules (a Stratego extension) are designed to overcome this need. Dynamic rules are generated at run-time and can access information available from their definition context. A dynamic rule application allows to access information from a different program point. Our implementation of data-flow optimisations use dynamic rules to provide contex-sensitive information. We have introduced operations on dynamic rules which enabled us to describe data-flow optimisations such as constant-propagation, copy-propagation, common sub-expression elimination and dead code elimination at a high level of abstraction. A nice feature of our implementation is that integrates analysis and transformation into one task. We have defined generic data-flow frameworks for data-flow optimisations. The frameworks capture the similarities of data-flow optimisations and allow to be parameterized with different dynamic rules and strategies. The strategy parameters are applied at certain stages of the transformation to tune a transformation. The generic propagation strategies can combine different analyses and transformations by combining elements from several one-issue transformations. When two or more transformations share specific transformation features, it is possible to define a combination of transformations. Thus, a super-optimiser is presented which combines renaming, constant propagation, copy propagation and common sub-expression elimination.

73 citations


Proceedings ArticleDOI
24 Aug 2009
TL;DR: This work presents a mostly-automated refactoring that makes existing Java programs reentrant by replacing global state with thread-local state and performing each execution in a fresh thread.
Abstract: A program is reentrant if distinct executions of that program on distinct inputs cannot affect each other. Reentrant programs have the desirable property that they can be deployed on parallel machines without additional concurrency control. Many existing Java programs are not reentrant because they rely on mutable global state. We present a mostly-automated refactoring that makes such programs reentrant by replacing global state with thread-local state and performing each execution in a fresh thread. The approach has the key advantage of yielding a program that is obviously safe for parallel execution; the program can then be optimized selectively for better performance. We implemented this refactoring in Reentrancer, a practical Eclipse-based tool. Reentrancer successfully eliminated observed reentrancy problems in five single-threaded Java benchmarks. For three of the benchmarks, Reentrancer enabled speedups on a multicore machine without any further code modification.

72 citations


Proceedings ArticleDOI
15 Jun 2009
TL;DR: An efficient translation validation algorithm for the Lazy Code Motion (LCM) optimization is developed and a LCM pass that is provably semantics-preserving and was integrated in the CompCert formally verified compiler is obtained.
Abstract: Translation validation establishes a posteriori the correctness of a run of a compilation pass or other program transformation. In this paper, we develop an efficient translation validation algorithm for the Lazy Code Motion (LCM) optimization. LCM is an interesting challenge for validation because it is a global optimization that moves code across loops. Consequently, care must be taken not to move computations that may fail before loops that may not terminate. Our validator includes a specific check for anticipability to rule out such incorrect moves. We present a mechanically-checked proof of correctness of the validation algorithm, using the Coq proof assistant. Combining our validator with an unverified implementation of LCM, we obtain a LCM pass that is provably semantics-preserving and was integrated in the CompCert formally verified compiler.

Journal ArticleDOI
TL;DR: This article describes a method for transforming any given set of Datalog rules into an efficient specialized implementation with guaranteed worst-case time and space complexities, and for computing the complexities from the rules.
Abstract: This article describes a method for transforming any given set of Datalog rules into an efficient specialized implementation with guaranteed worst-case time and space complexities, and for computing the complexities from the rules. The running time is optimal in the sense that only useful combinations of facts that lead to all hypotheses of a rule being simultaneously true are considered, and each such combination is considered exactly once in constant time. The associated space usage may sometimes be reduced using scheduling optimizations to eliminate some summands in the space usage formula. The transformation is based on a general method for algorithm design that exploits fixed-point computation, incremental maintenance of invariants, and combinations of indexed and linked data structures. We apply the method to a number of analysis problems, some with improved algorithm complexities and all with greatly improved algorithm understanding and greatly simplified complexity analysis.

Journal ArticleDOI
TL;DR: This work provides a formal framework for code obfuscation based on abstract interpretation and program semantics and proves that this framework provides an adequate setting to measure not only the potency of an obfuscation but also its resilience, i.e., the difficulty of undoing the obfuscation.
Abstract: In recent years code obfuscation has attracted research interest as a promising technique for protecting secret properties of programs. The basic idea of code obfuscation is to transform programs in order to hide their sensitive information while preserving their functionality. One of the major drawbacks of code obfuscation is the lack of a rigorous theoretical framework that makes it difficult to formally analyze and certify the effectiveness of obfuscating techniques. We face this problem by providing a formal framework for code obfuscation based on abstract interpretation and program semantics. In particular, we show that what is hidden and what is preserved by an obfuscating transformation can be expressed as abstract interpretations of program semantics. Being able to specify what is masked and what is preserved by an obfuscation allows us to understand its potency, namely the amount of obscurity that the transformation adds to programs. In the proposed framework, obfuscation and attackers are modeled as approximations of program semantics and the lattice of abstract interpretations provides a formal tool for comparing obfuscations with respect to their potency. In particular, we prove that our framework provides an adequate setting to measure not only the potency of an obfuscation but also its resilience, i.e., the difficulty of undoing the obfuscation. We consider code obfuscation by opaque predicate insertion and we show how the degree of abstraction needed to disclose different opaque predicates allows us to compare their potency and resilience.

Proceedings ArticleDOI
07 Mar 2009
TL;DR: It is demonstrated that this analysis can automatically extract significant amounts of parallelism from many applications, and where it is ineffective it can provide software developers a useful list of functions that may be commutative provided semantic program changes that are not automatable.
Abstract: Extracting performance from many-core architectures requires software engineers to create multi-threaded applications, which significantly complicates the already daunting task of software development. One solution to this problem is automatic compile-time parallelization, which can ease the burden on software developers in many situations. Clearly, automatic parallelization in its present form is not suitable for many application domains and new compiler analyses are needed address its shortcomings.In this paper, we present one such analysis: a new approach for detecting commutative functions. Commutative functions are sections of code that can be executed in any order without affecting the outcome of the application, e.g., inserting elements into a set. Previous research on this topic had one significant limitation, in that the results of a commutative functions must produce identical memory layouts. This prevented previous techniques from detecting functions like malloc, which may return different pointers depending on the order in which it is called, but these differing results do not affect the overall output of the application. Our new commutativity analysis correctly identify these situations to better facilitate automatic parallelization. We demonstrate that this analysis can automatically extract significant amounts of parallelism from many applications, and where it is ineffective it can provide software developers a useful list of functions that may be commutative provided semantic program changes that are not automatable.

Proceedings ArticleDOI
21 Jan 2009
TL;DR: The motivation of the work is data-flow synchronous programming languages, used for building control-command embedded systems, but it also applies to imperative and functional programming.
Abstract: We propose a method for automatically generating abstract transformers for static analysis by abstract interpretation. The method focuses on linear constraints on programs operating on rational, real or floating-point variables and containing linear assignments and tests.In addition to loop-free code, the same method also applies for obtaining least fixed points as functions of the precondition, which permits the analysis of loops and recursive functions. Our algorithms are based on new quantifier elimination and symbolic manipulation techniques.Given the specification of an abstract domain, and a program block, our method automatically outputs an implementation of the corresponding abstract transformer. It is thus a form of program transformation.The motivation of our work is data-flow synchronous programming languages, used for building control-command embedded systems, but it also applies to imperative and functional programming.

Book ChapterDOI
24 Jul 2009
TL;DR: A framework that unifies unit testing and run-time verification (as well as static verification and static debugging) and preserves the use of a unified assertion language for all of these tasks is presented.
Abstract: We present a framework that unifies unit testing and run-time verification (as well as static verification and static debugging). A key contribution of our overall approach is that we preserve the use of a unified assertion language for all of these tasks. We first describe a method for compiling run-time checks for (parts of) assertions which cannot be verified at compile-time via program transformation. This transformation allows checking preconditions and postconditions, including conditional postconditions, properties at arbitrary program points, and certain computational properties. Most importantly, we propose a minimal addition to the assertion language which allows defining unit tests to be run in order to detect possible violations of the (partial) specifications expressed by the assertions. We have implemented the framework within the Ciao/CiaoPP system and effectively applied it to the verification of ISO Prolog compliance and to the detection of different types of bugs in the Ciao system source code. Experimental results are presented that illustrate different trade-offs among program size, running time, or levels of verbosity of the messages shown to the user.

Proceedings ArticleDOI
19 Jan 2009
TL;DR: A semantics-based transformation is proposed in the abstract interpretation framework and it aims at rewriting pieces of numerical codes in order to obtain results closer to what the computer would output if it used the exact arithmetic.
Abstract: This article introduces a new program transformation in order to enhance the numerical accuracy of floating-point computations. We consider that a program would return an exact result if the computations were carried out using real numbers. In practice, roundoff errors due to the finite representation of values arise during the execution. These errors are closely related to the way formulas are evaluated. Indeed, mathematically equivalent formulas, obtained using laws like associativity, distributivity, etc., may lead to very different numerical results in the computer arithmetic. We propose a semantics-based transformation in order to optimize the numerical accuracy of programs. This transformation is expressed in the abstract interpretation framework and it aims at rewriting pieces of numerical codes in order to obtain results closer to what the computer would output if it used the exact arithmetic.

Journal IssueDOI
TL;DR: This article presents a novel profiling approach, which is entirely based on program transformation techniques, in order to build a profiling data structure that provides calling-context-sensitive program execution statistics and to generate reproducible profiles.
Abstract: Virtual execution environments, such as the Java virtual machine, promote platform-independent software development. However, when it comes to analyzing algorithm complexity and performance bottlenecks, available tools focus on platform-specific metrics, such as the CPU time consumption on a particular system. Other drawbacks of many prevailing profiling tools are high overhead, significant measurement perturbation, as well as reduced portability of profiling tools, which are often implemented in platform-dependent native code. This article presents a novel profiling approach, which is entirely based on program transformation techniques, in order to build a profiling data structure that provides calling-context-sensitive program execution statistics. We explore the use of platform-independent profiling metrics in order to make the instrumentation entirely portable and to generate reproducible profiles. We implemented these ideas within a Java-based profiling tool called JP. A significant novelty is that this tool achieves complete bytecode coverage by statically instrumenting the core runtime libraries and dynamically instrumenting the rest of the code. JP provides a small and flexible API to write customized profiling agents in pure Java, which are periodically activated to process the collected profiling information. Performance measurements point out that, despite the presence of dynamic instrumentation, JP causes significantly less overhead than a prevailing tool for the profiling of Java code. Copyright © 2008 John Wiley & Sons, Ltd.

Proceedings ArticleDOI
08 Jul 2009
TL;DR: This paper introduces a novel approach in which transformations are used to improve testability of a program by generating a pseudo-oracle and shows that both random testing and genetic algorithms are capable of utilizing the pseudo- oracles to automatically find program failures.
Abstract: Testability transformations are source-to-source program transformations that are designed to improve the testability of a program. This paper introduces a novel approach in which transformations are used to improve testability of a program by generating a pseudo-oracle. A pseudo-oracle is an alternative version of a program under test whose output can be compared with the original. Differences in output between the two programs may indicate a fault in the original program. Two transformations are presented. The first can highlight numerical inaccuracies in programs and cumulative roundoff errors, whilst the second may detect the presence of race conditions in multi-threaded code. Once a pseudo-oracle is generated, techniques are applied from the field of search-based testing to automatically find differences in output between the two versions of the program. The results of an experimental study presented in the paper show that both random testing and genetic algorithms are capable of utilizing the pseudo-oracles to automatically find program failures. Using genetic algorithms it is possible to explicitly maximize the discrepancies between the original programs and their pseudo-oracles. This allows for the production of test cases where the observable failure is highly pronounced, enabling the tester to establish the seriousness of the underlying fault.

Journal ArticleDOI
TL;DR: The motivation of the work is data-flow synchronous programming languages, used for building control-command embedded systems, but it also applies to imperative and functional programming.
Abstract: We propose a method for automatically generating abstract transformers for static analysis by abstract interpretation. The method focuses on linear constraints on programs operating on rational, real or floating-point variables and containing linear assignments and tests. In addition to loop-free code, the same method also applies for obtaining least fixed points as functions of the precondition, which permits the analysis of loops and recursive functions. Our algorithms are based on new quantifier elimination and symbolic manipulation techniques. Given the specification of an abstract domain, and a program block, our method automatically outputs an implementation of the corresponding abstract transformer. It is thus a form of program transformation. The motivation of our work is data-flow synchronous programming languages, used for building control-command embedded systems, but it also applies to imperative and functional programming.

Journal ArticleDOI
01 Dec 2009
TL;DR: The analysis is based on a reduction of termination to two separate problems: reachability of recursive programs, and termination of non-recursive programs, which works through a program transformation that modifies the call sites and removes return edges.
Abstract: We propose a program analysis method for proving termination of recursive programs. The analysis is based on a reduction of termination to two separate problems: reachability of recursive programs, and termination of non-recursive programs. Our reduction works through a program transformation that modifies the call sites and removes return edges. In the new, non-recursive program, a procedure call may non-deterministically enter the procedure body (which means that it will never return) or apply a summary statement.

Proceedings ArticleDOI
07 Sep 2009
TL;DR: Tidier is a software tool that tidies Erlang source code, making it cleaner, simpler, and often also more efficient, and a set of refactorings which are general enough to be applied to the source code of programs written in Haskell or Clean and possibly even in non-functional languages.
Abstract: This paper describes the design goals and current status of tidier, a software tool that tidies Erlang source code, making it cleaner, simpler, and often also more efficient. In contrast to other refactoring tools, tidier is completely automatic and is not tied to any particular editor or IDE. Instead, tidier comes with a suite of code transformations that can be selected by its user via command-line options and applied in bulk on a set of modules or entire applications using a simple command. Alternatively, users can use tidier's GUI to inspect one by one the transformations that will be performed on their code and manually select only those that they fancy. We have used tidier to clean up various applications of Erlang/OTP and have tested it on many open source Erlang code bases of significant size. We briefly report our experiences and show opportunities for tidier's current set of transformations on existing Erlang code out there. As a by-product, our paper also documents what we believe are good coding practices in Erlang. Last but not least, our paper describes in detail the automatic code cleanup methodology we advocate and a set of refactorings which are general enough to be applied, as is or with only small modifications, to the source code of programs written in Haskell or Clean and possibly even in non-functional languages.

Journal ArticleDOI
TL;DR: A refinement to the notion of reductant based on PE techniques, that is called PE-reductant, is defined and it is demonstrated that the refined notion of PE- reductant is even able to increase the efficiency of multi-adjoint logic programs.

Book ChapterDOI
24 Jul 2009
TL;DR: A technique for identifying predicate arguments that play no role in determining the control flow of a logic program with respect to goals satisfying given mode and sharing restrictions is presented, and it is shown that such arguments can be detected by an automatic analysis.
Abstract: We present a technique for identifying predicate arguments that play no role in determining the control flow of a logic program with respect to goals satisfying given mode and sharing restrictions. We call such arguments non-discriminating arguments. We show that such arguments can be detected by an automatic analysis. Following this, we define a transformation procedure, called discriminator slicing , that removes the non-discriminating arguments, resulting in a program whose computation trees are isomorphic to those of the original program. Finally, we show how the results of the original program can be reconstructed from trace of the transformed program with the original arguments. Thus the overall result is a two-stage execution of a program, which can be applied usefully in several contexts; we describe a case study in optimising computations in the probabilistic logic program language PRISM, and discuss applications in tabling and partial evaluation. We also discuss briefly other possible ways of exploiting the non-discriminating arguments.

Journal ArticleDOI
TL;DR: The power of this approach to program optimization based on transformations is demonstrated by developing a set of optimizations using the transformation language and showing how the transformations can be converted into a form which makes it easier to apply them, while maintaining trust in the resulting optimizing steps.
Abstract: This article describes an approach to program optimization based on transformations, where temporal logic is used to specify side conditions, and strategies are created which expand the repertoire of transformations and provide a suitable level of abstraction. We demonstrate the power of this approach by developing a set of optimizations using our transformation language and showing how the transformations can be converted into a form which makes it easier to apply them, while maintaining trust in the resulting optimizing steps. The approach is illustrated through a transformational case study where we apply several optimizations to a small program.

Book ChapterDOI
27 Mar 2009
TL;DR: This paper shows that security engineering to prevent injection attacks need not be ad hoc and that protection can be introduced at different layers of a system by systematically applying general purpose security-oriented program transformations.
Abstract: Injection attacks and their defense require a lot of creativity from attackers and secure system developers. Unfortunately, as attackers rely increasingly on systematic approaches to find and exploit a vulnerability, developers follow the traditional way of writing ad hoc checks in source code. This paper shows that security engineering to prevent injection attacks need not be ad hoc. It shows that protection can be introduced at different layers of a system by systematically applying general purpose security-oriented program transformations. These program transformations are automated so that they can be applied to new systems at design and implementation stages, and to existing ones during maintenance.

Proceedings ArticleDOI
04 Oct 2009
TL;DR: The RuggedJ system accommodates all system classes, allowing both user and system classes alike to be referenced using a single object model, and considers the constraints imposed upon pervasive class transformation within Java.
Abstract: The indirection of object accesses is a common theme for target domains as diverse as transparent distribution, persistence, and program instrumentation. Virtualizing accesses to fields and methods (by redirecting calls through accessor and indirection methods) allows interposition of arbitrary code, extending the functionality of an application beyond that intended by the original developer.We present class modifications performed by our RuggedJ transparent distribution platform for standard Java virtual machines. RuggedJ abstracts over the location of objects by implementing a single object model for local and remote objects. However the implementation of this model is complicated by the presence of native and system code; classes loaded by Java's bootstrap class loader can be rewritten only in a limited manner, and so cannot be modified to conform to RuggedJ's complex object model. We observe that system code comprises the majority of a given Java application: an average of 76% in the applications we study. We consider the constraints imposed upon pervasive class transformation within Java, and present a framework for systematically rewriting arbitrary applications. Our system accommodates all system classes, allowing both user and system classes alike to be referenced using a single object model.

Journal ArticleDOI
TL;DR: Reasoning about program control-flow paths is an important functionality of a number of recent program matching languages and associated searching and transformation tools.
Abstract: Reasoning about program control-flow paths is an important functionality of a number of recent program matching languages and associated searching and transformation tools. Temporal logic provides ...

Book ChapterDOI
01 Sep 2009
TL;DR: A method based on logic program transformation, for verifying Computation Tree Logic (CTL*) properties of finite state reactive systems by applying unfold/fold rules that preserve the perfect model of the initial program.
Abstract: We present a method based on logic program transformation, for verifying Computation Tree Logic (CTL*) properties of finite state reactive systems. The finite state systems and the CTL* properties we want to verify, are encoded as logic programs on infinite lists. Our verification method consists of two steps. In the first step we transform the logic program that encodes the given system and the given property, into a monadic ω-program, that is, a stratified program defining nullary or unary predicates on infinite lists. This transformation is performed by applying unfold/fold rules that preserve the perfect model of the initial program. In the second step we verify the property of interest by using a proof method for monadic ω-programs.

Proceedings ArticleDOI
19 May 2009
TL;DR: This paper shows how security-oriented program transformations could be used to improve the security of a system's perimeter by introducing authentication, authorization and input validation components.
Abstract: A security-oriented program transformation maps programs to security-augmented programs, i.e. it introduces a protection mechanism to make programs more secure. Our previous work defined security-oriented program transformations [6], introduced a catalog of transformations [8], and showed how program transformations could be applied to systematically eradicate various types of data injection attacks [9]. This paper shows how security-oriented program transformations could be used to improve the security of a system's perimeter by introducing authentication, authorization and input validation components. The program transformation examples in this paper are JAVA specific, but the transformations could be implemented to use other authentication and authorization frameworks.