21,965 research outputs found
Size-Change Termination as a Contract
Termination is an important but undecidable program property, which has led
to a large body of work on static methods for conservatively predicting or
enforcing termination. One such method is the size-change termination approach
of Lee, Jones, and Ben-Amram, which operates in two phases: (1) abstract
programs into "size-change graphs," and (2) check these graphs for the
size-change property: the existence of paths that lead to infinite decreasing
sequences.
We transpose these two phases with an operational semantics that accounts for
the run-time enforcement of the size-change property, postponing (or entirely
avoiding) program abstraction. This choice has two key consequences: (1)
size-change termination can be checked at run-time and (2) termination can be
rephrased as a safety property analyzed using existing methods for systematic
abstraction.
We formulate run-time size-change checks as contracts in the style of Findler
and Felleisen. The result compliments existing contracts that enforce partial
correctness specifications to obtain contracts for total correctness. Our
approach combines the robustness of the size-change principle for termination
with the precise information available at run-time. It has tunable overhead and
can check for nontermination without the conservativeness necessary in static
checking. To obtain a sound and computable termination analysis, we apply
existing abstract interpretation techniques directly to the operational
semantics, avoiding the need for custom abstractions for termination. The
resulting analyzer is competitive with with existing, purpose-built analyzers
On Decidable Growth-Rate Properties of Imperative Programs
In 2008, Ben-Amram, Jones and Kristiansen showed that for a simple "core"
programming language - an imperative language with bounded loops, and
arithmetics limited to addition and multiplication - it was possible to decide
precisely whether a program had certain growth-rate properties, namely
polynomial (or linear) bounds on computed values, or on the running time.
This work emphasized the role of the core language in mitigating the
notorious undecidability of program properties, so that one deals with
decidable problems.
A natural and intriguing problem was whether more elements can be added to
the core language, improving its utility, while keeping the growth-rate
properties decidable. In particular, the method presented could not handle a
command that resets a variable to zero. This paper shows how to handle resets.
The analysis is given in a logical style (proof rules), and its complexity is
shown to be PSPACE-complete (in contrast, without resets, the problem was
PTIME). The analysis algorithm evolved from the previous solution in an
interesting way: focus was shifted from proving a bound to disproving it, and
the algorithm works top-down rather than bottom-up
Using Program Synthesis for Program Analysis
In this paper, we identify a fragment of second-order logic with restricted
quantification that is expressive enough to capture numerous static analysis
problems (e.g. safety proving, bug finding, termination and non-termination
proving, superoptimisation). We call this fragment the {\it synthesis
fragment}. Satisfiability of a formula in the synthesis fragment is decidable
over finite domains; specifically the decision problem is NEXPTIME-complete. If
a formula in this fragment is satisfiable, a solution consists of a satisfying
assignment from the second order variables to \emph{functions over finite
domains}. To concretely find these solutions, we synthesise \emph{programs}
that compute the functions. Our program synthesis algorithm is complete for
finite state programs, i.e. every \emph{function} over finite domains is
computed by some \emph{program} that we can synthesise. We can therefore use
our synthesiser as a decision procedure for the synthesis fragment of
second-order logic, which in turn allows us to use it as a powerful backend for
many program analysis tasks. To show the tractability of our approach, we
evaluate the program synthesiser on several static analysis problems.Comment: 19 pages, to appear in LPAR 2015. arXiv admin note: text overlap with
arXiv:1409.492
Path-Based Program Repair
We propose a path-based approach to program repair for imperative programs.
Our repair framework takes as input a faulty program, a logic specification
that is refuted, and a hint where the fault may be located. An iterative
abstraction refinement loop is then used to repair the program: in each
iteration, the faulty program part is re-synthesized considering a symbolic
counterexample, where the control-flow is kept concrete but the data-flow is
symbolic. The appeal of the idea is two-fold: 1) the approach lazily considers
candidate repairs and 2) the repairs are directly derived from the logic
specification. In contrast to prior work, our approach is complete for programs
with finitely many control-flow paths, i.e., the program is repaired if and
only if it can be repaired at the specified fault location. Initial results for
small programs indicate that the approach is useful for debugging programs in
practice.Comment: In Proceedings FESCA 2015, arXiv:1503.0437
Recurrence with affine level mappings is P-time decidable for CLP(R)
In this paper we introduce a class of constraint logic programs such that
their termination can be proved by using affine level mappings. We show that
membership to this class is decidable in polynomial time.Comment: To appear in Theory and Practice of Logic Programming (TPLP
Reducing the Number of Annotations in a Verification-oriented Imperative Language
Automated software verification is a very active field of research which has
made enormous progress both in theoretical and practical aspects. Recently, an
important amount of research effort has been put into applying these techniques
on top of mainstream programming languages. These languages typically provide
powerful features such as reflection, aliasing and polymorphism which are handy
for practitioners but, in contrast, make verification a real challenge. In this
work we present Pest, a simple experimental, while-style, multiprocedural,
imperative programming language which was conceived with verifiability as one
of its main goals. This language forces developers to concurrently think about
both the statements needed to implement an algorithm and the assertions
required to prove its correctness. In order to aid programmers, we propose
several techniques to reduce the number and complexity of annotations required
to successfully verify their programs. In particular, we show that high-level
iteration constructs may alleviate the need for providing complex loop
annotations.Comment: 15 pages, 8 figure
Inferring Termination Conditions for Logic Programs using Backwards Analysis
This paper focuses on the inference of modes for which a logic program is
guaranteed to terminate. This generalises traditional termination analysis
where an analyser tries to verify termination for a specified mode. Our
contribution is a methodology in which components of traditional termination
analysis are combined with backwards analysis to obtain an analyser for
termination inference. We identify a condition on the components of the
analyser which guarantees that termination inference will infer all modes which
can be checked to terminate. The application of this methodology to enhance a
traditional termination analyser to perform also termination inference is
demonstrated
- …