13 research outputs found
FIFO anomaly is unbounded
Virtual memory of computers is usually implemented by demand paging. For some
page replacement algorithms the number of page faults may increase as the
number of page frames increases. Belady, Nelson and Shedler constructed
reference strings for which page replacement algorithm FIFO produces near twice
more page faults in a larger memory than in a smaller one. They formulated the
conjecture that 2 is a general bound. We prove that this ratio can be
arbitrarily large
Koka: Programming with Row Polymorphic Effect Types
We propose a programming model where effects are treated in a disciplined
way, and where the potential side-effects of a function are apparent in its
type signature. The type and effect of expressions can also be inferred
automatically, and we describe a polymorphic type inference system based on
Hindley-Milner style inference. A novel feature is that we support polymorphic
effects through row-polymorphism using duplicate labels. Moreover, we show that
our effects are not just syntactic labels but have a deep semantic connection
to the program. For example, if an expression can be typed without an exn
effect, then it will never throw an unhandled exception. Similar to Haskell's
`runST` we show how we can safely encapsulate stateful operations. Through the
state effect, we can also safely combine state with let-polymorphism without
needing either imperative type variables or a syntactic value restriction.
Finally, our system is implemented fully in a new language called Koka and has
been used successfully on various small to medium-sized sample programs ranging
from a Markdown processor to a tier-splitted chat application. You can try out
Koka live at www.rise4fun.com/koka/tutorial.Comment: In Proceedings MSFP 2014, arXiv:1406.153
Relational Logic with Framing and Hypotheses
Relational properties arise in many settings: relating two versions of a program that use different data representations, noninterference properties for security, etc. The main ingredient of relational verification, relating aligned pairs of intermediate steps, has been used in numerous guises, but existing relational program logics are narrow in scope. This paper introduces a logic based on novel syntax that weaves together product programs to express alignment of control flow points at which relational formulas are asserted. Correctness judgments feature hypotheses with relational specifications, discharged by a rule for the linking of procedure implementations. The logic supports reasoning about program-pairs containing both similar and dissimilar control and data structures. Reasoning about dynamically allocated objects is supported by a frame rule based on frame conditions amenable to SMT provers. We prove soundness and sketch how the logic can be used for data abstraction, loop optimizations, and secure information flow
Checking Observational Purity of Procedures
Verifying whether a procedure is observationally pure is useful in many
software engineering scenarios. An observationally pure procedure always
returns the same value for the same argument, and thus mimics a mathematical
function. The problem is challenging when procedures use private mutable global
variables, e.g., for memoization of frequently returned answers, and when they
involve recursion.
We present a novel verification approach for this problem. Our approach
involves encoding the procedure's code as a formula that is a disjunction of
path constraints, with the recursive calls being replaced in the formula with
references to a mathematical function symbol. Then, a theorem prover is invoked
to check whether the formula that has been constructed agrees with the function
symbol referred to above in terms of input-output behavior for all arguments.
We evaluate our approach on a set of realistic examples, using the Boogie
intermediate language and theorem prover. Our evaluation shows that the
invariants are easy to construct manually, and that our approach is effective
at verifying observationally pure procedures.Comment: FASE 201
Formal specification with JML
This text is a general, self contained, and tool independent introduction into the Java Modeling Language, JML. It is a preview of a chapter planned to appear in a book about the KeY approach and tool to the verification of Java software. JML is the dominating starting point of KeY style Java verification. However, this paper does not in any way depend on any tool nor verification methodology. Other chapters in this book talk about the usage of JML in KeY style verification. Here, we only refer to KeY in very few places, without relying on it. This introduction is written for all readers with an interest in formal specification of software in general, and anyone who wants to learn about the JML approach to specification in particular. The authors appreciate any comments or questions that help to improve the text
Logical Reasoning for Higher-Order Functions with Local State
We introduce an extension of Hoare logic for call-by-value higher-order
functions with ML-like local reference generation. Local references may be
generated dynamically and exported outside their scope, may store higher-order
functions and may be used to construct complex mutable data structures. This
primitive is captured logically using a predicate asserting reachability of a
reference name from a possibly higher-order datum and quantifiers over hidden
references. We explore the logic's descriptive and reasoning power with
non-trivial programming examples combining higher-order procedures and
dynamically generated local state. Axioms for reachability and local invariant
play a central role for reasoning about the examples.Comment: 68 page
Capturing and exploiting abstract views of states in OO verification
In this thesis, we study several implementation, specification and verification techniques for Object-Oriented (OO) programs. Our focus is on capturing conceptual structures in OO states in abstractions, and then exploiting such an abstract view of the state in specification and implementation approaches in a way that allows for formal verification. Generally, an OO state consists of many objects that reference each other in possibly complicated ways. At the same time, at any one point in the execution of the program, we can often reason about what is happening using an abstract view of the state that is much less complicated. To further improve the quality of implementations, better techniques must be developed for 1) specification of the abstract views that are used by the client and the programmer, and 2) the verification that an implementation satisfies its specification. This thesis contributes to that effort. We distinguish between client-level and programmer-level specification. A client-level specification acts as a contract between the client and the implementer. A programmer-level specification allows to reason formally about the implementation. We consider two specification formalisms that differ in the basic abstract view that is used: Algebraic Specification and OO Specification. We consider both client-level and programmer-level specifications based on algebraic specification. We contribute a novel syntax and semantics for the former, and we contribute an implementation approach for OO implementations based on the latter. We show that the implementation approach is suitable for problem-independent verification. We propose the programmer-level OO specification constructs inc and coop. The inc construct allows method specification to make explicit that a certain enumeration of invariants does not have to hold when that method is executed. The coop construct allows a field specification to make explicit that a certain enumeration of invariants might be invalidated when the field is updated. This allows for the specification and verification of OO designs in which in the process of updating one object, other objects with which it together implements a common purpose must be updated as well. We then generalize the inc and coop constructs by removing a restriction to enumerations of invariants. For instance, this is needed in the well-known Observer Pattern, where a Subject can have an arbitrary and dynamically changing number of Observers. A more general interpretation of invariants and accompanying proof system are provided as well. We contribute a programmer-level OO specification technique to capture layers in OO architectures, and we exploit these layers by providing a more liberal semantics of class invariants. We also provide a verification technique for the semantics. Layers are an abstraction at the architectural level in OO implementations that designate certain object structures in the design as sub-structures that are shared by other structures. An object in a higher layer is not relevant to the purpose of an object in the sub-structure. Given this intuition, an object in a higher layer is not part of the abstract view from an object in a lower layer. Therefore, the invariant of a higher layer object does not have to hold when a method of a lower-layer object is executing. Finally, we contribute a verification technique for pure methods and model fields, which are existing specification techniques for capturing an abstract view of the state in OO specifications. A method that is pure can be used as a function in predicates in class specifications. The function is axiomatized using the pre- and postcondition that are specified for the method. A model field abstracts part of the concrete state of an object into an abstract value. This too introduces an additional axiom in the underlying reasoning. The technique contributed establishes that such additional axioms do no introduce inconsistencies into the formal reasoning. It comes with heuristics that that make it amenable to automatic verification
Enforcing Abstract Immutability
Researchers have recently proposed a number of systems for expressing,
verifying, and inferring immutability declarations. These systems are
often rigid, and do not support "abstract immutability". An abstractly
immutable object is an object o which is immutable from the point of
view of any external methods. The C++ programming language is not
rigid–it allows developers to express intent by adding immutability
declarations to methods. Abstract immutability allows for performance
improvements such as caching, even in the presence of writes to object
fields. This dissertation presents a system to enforce abstract
immutability.
First, we explore abstract immutability in real-world systems. We
found that developers often incorrectly use abstract immutability,
perhaps because no programming language helps developers correctly
implement abstract immutability. We believe that this omission leads
to incorrect usages. Specifically, we wrote a dynamic analysis that
reports any writes through immutability declarations. To our knowledge,
this work was the first to explore how objects implement abstract
immutability (or fail to implement it). Our novel study found three
uses of abstract immutability: caching, delayed initialization, and
unit testing. Unit testing was a surprising application of abstract
immutability, and we believe that the ability to modify state is
needed for proper unit testing.
Next, we explore developers' revealed needs for immutability in the
source code. We found that the majority of classes contain a mix of
immutable and mutable methods, with a majority of the overall methods
being immutable. Immutability systems with only immutable or
all-mutating classes are insufficient: developers need immutability
declarations at method granularity. Our study then combined developer
immutability declarations with results from a static analysis to
estimate the true number of immutable methods. The static analysis
checked that no transitive writes to a receiver object occurred. Our
results indicated the need for a sophisticated analysis to check that
these apparently abstractly immutable methods were indeed abstractly
immutable.
Finally, we created a novel static analysis which checks that
developers follow abstract immutability. Specifically, we define
abstract immutability to mean that a class's set of immutable methods
is collectively free of writes to exposed fields. Our analysis found
incorrect usages of abstract immutability, such as incorrect caching.
This analysis is particularly valuable in the context of code
evolution, whereby subsequent programmers may make changes that break
previously-correct cache implementations, for instance. Our work
allows developers to trust that their code is abstractly immutable