LeanMachines: State-based Modeling with Refinement (a Lean4 Framework)
We present a framework for the formal modeling of state-based systems in the context of the Lean4 programming language and proof assistant. In this context, the main objective is to support a step-wise refinement methodology inspired conceptually by the Event-B formal method. As a starting point, the LeanMachines framework proposes Lean4 constructions for the main Event-B concepts such as contexts, machines and events. Most importantly, the associated refinement principles are introduced in the form of typeclass constructions inspired by (and in fact built upon) the Mathlib mathematical framework. Beyond the basic concepts and structures, we also experiment with extensions of the framework. First, we develop an algebra of event combinators that allow to compose complex event structures out of simpler ones. These combinators are based on algebraic structures – functors, arrows, etc. – that have been developed and studied in the context of (functional) programming language theory. Our proposed formalization of the Event-B concepts is very shallow in the sense that all the constructions are directly based on the Lean4 logic and abstractions. One benefit is that proof obligations can be discharged using the tactic language of Lean4 with almost no embedding overhead such as an abstraction barrier that would require syntactic conversions, or the necessity to use some dedicated proof tactics. As an important design guideline, we enforce the fundamental principle of correctness-by-construction: machine states, events structures and refinement steps cannot be fully constructed without discharging the prescribed proof obligations.
- Research Article
- 10.36427/cejntrep.2.1.470
- Apr 28, 2020
- Central-European Journal of New Technologies in Research, Education and Practice
Teaching of programming language theory has a long track record at ELTE Faculty of Informatics. Traditionally, formal semantics and type systems of programming languages, similarly to other theory-oriented subjects, were taught with the pen and paper method. However, modern proof assistants call for replacing this old-fashioned way of teaching with novel and interactive methods that bring deeper understanding, provide better learning experience and build technical skills in applying formal methods. The authors have launched practice classes for two programming language theory subjects and carefully developed course material based on executable and verifiable definitions formalised in the Coq proof assistant. In this paper, we share our experiences regarding the design and implementation of the new material, we outline the pros and cons of using a proof assistant in the courses, and we describe how the presented method may be adapted to other courses.
- Book Chapter
44
- 10.1007/978-3-540-70594-9_17
- Jul 15, 2008
We present a Hoare logic for a call-by-value programming language equipped with recursive, higher-order functions, algebraic data types, and a polymorphic type system in the style of Hindley and Milner. It is the theoretical basis for a tool that extracts proof obligations out of programs annotated with logical assertions. These proof obligations, expressed in a typed, higher-order logic, are discharged using off-the-shelf automated or interactive theorem provers. Although the technical apparatus that we exploit is by now standard, its application to call-by-value functional programming languages appears to be new, and (we claim) deserves attention. As a sample application, we check the partial correctness of a balanced binary search tree implementation.
- Conference Article
- 10.4230/lipics.rta.2011.9
- Jan 1, 2011
- DROPS (Schloss Dagstuhl – Leibniz Center for Informatics)
Programming languages based on dependent type theory promise two great advances: flexibility and security. With the type-level computation afforded by dependent types, algorithms can be more generic, as the type system can express flexible interfaces via programming. Likewise, type-level computation can also express data structure invariants, so that programs can be proved correct through type checking. Furthermore, despite these extensions, programmers already know everything. Via the Curry-Howard isomorphism, the language of type-level computation and the verification logic is the programming language itself. There are two current approaches to the design of dependently-typed languages: Coq, Epigram, Agda, which grew out of the logics of proof assistants, require that all expressions terminate. These languages provide decidable type checking and strong correctness guarantees. In contrast, functional programming languages, like Haskell and Omega, have adapted the features dependent type theories, but retain a strict division between types and programs. These languages trade termination obligations for more limited correctness assurances. In this talk, I present a work-in-progress overview of the Trellys project. Trellys is new core language, designed to provide a smooth path from functional programming to dependently-typed programming. Unlike traditional dependent type theories and functional languages, Trellys allows programmers to work with total and partial functions uniformly. The language itself is composed of two fragments that share a common syntax and overlapping semantics: a simple logical language that guarantees total correctness and an expressive call-by-value programming language that guarantees types safety but not termination. Importantly, these two fragments interact. The logical fragment may soundly reason about effectful, partial functions. Program values may be used as evidence by the logic. We call this principle freedom of speech: whereas proofs themselves must terminate, they must be allowed to reason about any function a programmer might write. To retain consistency, the Trellys type system keeps track of where potentially non-terminating computations may appear, so that it can prevent them from being used as proofs.
- Single Book
37
- 10.7551/mitpress/5641.001.0001
- May 8, 2000
This collection of original essays reflects the breadth of current research in computer science. This collection of original essays reflects the breadth of current research in computer science. Robin Milner, a major figure in the field, has made many fundamental contributions, particularly in theoretical computer science, the theory of programming languages, and functional programming languages. Following a brief biography of Milner, the book contains five sections: Semantic Foundations, Programming Logic, Programming Languages, Concurrency, and Mobility. Together the pieces convey a seamless whole, ranging from highly abstract concepts to systems of great utility. Contributors Samson Abramsky, J. C. M. Baeten, Sergey Berezin, J. A. Bergstra, Gérard Berry, Lars Birkedal, Gérard Boudol, Edmund Clarke, Pierre Collette, Robert L. Constable, Pierre-Louis Curien, Jaco de Bakker, Uffe H. Engberg, William Ferreira, Fabio Gadducci, Mike Gordon, Robert Harper, Matthew Hennessy, Yoram Hirshfeld, C. A. R. Hoare, Gérard Huet, Paul B. Jackson, Alan S. A. Jeffrey, Somesh Jha, He Jifeng, Cliff B. Jones, Cosimo Laneve, Xinxin Liu, Will Marrero, Faron Moller, Ugo Montanari, Pavel Naumov, Mogens Nielsen, Joachim Parrow, Lawrence C. Paulson, Benjamin C. Pierce, Gordon Plotkin, M. A. Reniers, Amokrane Saïbi, Augusto Sampaio, Davide Sangiorgi, Scott A. Smolka, Eugene W. Stark, Christopher Stone, Mads Tofte, David N. Turner, Juan Uribe, Franck van Breugel, David Walker, Glynn Winskel
- Supplementary Content
2
- 10.25560/13693
- Oct 1, 2013
- Spiral (Imperial College London)
In the theory of programming languages, one often takes two complementary perspectives. In operational semantics, one defines and reasons about the behaviour of programs; and in denotational semantics, one abstracts away implementation details, and reasons about programs as mathematical objects or denotations. The denotational semantics should be compositional, meaning that denotations of programs are determined by the denotations of their parts. It should also be adequate with respect to operational equivalence: programs with the same denotation should be behaviourally indistinguishable. One often has to prove adequacy and compositionality independently for different languages, and the proofs are often laborious and repetitive. These proofs were provided systematically in the context of process algebras by the mathematical operational semantics framework of Turi and Plotkin – which represented transition systems as coalgebras, and program syntax by free algebras; operational specifications were given by distributive laws of syntax over behaviour. By framing the semantics on this abstract level, one derives denotational and operational semantics which are guaranteed to be adequate and compositional for a wide variety of examples. However, despite speculation on the possibility, it is hard to apply the framework to programming languages, because one obtains undesirably fine-grained behavioural equivalences, and unconventional notions of operational semantics. Moreover, the behaviour of these languages is often formalised in a different way – such as computational effects, which may be thought of as an interface between programs and external factors such as non-determinism or a variable store; and comodels, or transition systems which implement these effects. This thesis adapts the mathematical operational semantics framework to provide semantics for various classes of programming languages. After identifying the need for such an adaptation, we show how program behaviour may be characterised by final coalgebras in suitably order- enriched Kleisli categories. We define both operational and denotational semantics, first for languages with syntactic effects, and then for languages with effects and/or comodels given by a Lawvere theory. To ensure adequacy and compositionality, we define concrete and abstract operational rule-formats for these languages, based on the idea of evaluation-in-context; we give syntactic and then categorical proofs that those properties are guaranteed by operational specifications in these rule-formats.
- Research Article
8
- 10.1007/s11761-023-00363-x
- May 18, 2023
- Service Oriented Computing and Applications
A system based on the internet of things (IoT) consists of services deployed across several devices that collaborate to fulfil IoT system goals. The growth in the number of IoT services that has occurred concurrently with the growth in the number of IoT devices is posing a significant difficulty for the process of service composition. In order to satisfy increasing demand and rapid expansion while keeping a certain level of quality of service, IoT systems need a scalable IoT service composition. However, building the correct scalable service composition is not guaranteed in IoT systems. This paper proposes formal modeling and verification of the scalability in IoT service composition at design time based on Event-B formal method. To fulfil the requirements of IoT service composition, the proposed model addresses more key qualities, mainly availability and interoperability. Further, by relying on the refinement technique, we create our model sequentially from the requirements analysis level to the target level. Finally, we validate and verify the correctness of the proposed formal model using of the Rodin platform and several proof obligations. Our verified model of the scalable IoT service composition has met its 44 proof obligations, and the Rodin prover was responsible for automatically addressing all of these proof obligations.
- Conference Article
2
- 10.1145/2790449.2790510
- Jul 14, 2015
In a world where trusting software systems is problematic, formal methods and formal proofs should be able to help. Proof checking can play an important role in establishing trust since such checkers can be smaller and easier to verify than, for example, entire theorem provers or model checkers. Proof checking has played an important role in the history of programming languages and, I argue, in its future. In general, proof checkers rely on programming languages which must also be trusted. In many modern proof checkers and theorem provers, that programming language is a functional programming language, often a variant of ML. In fact, parts of ML (eg., strong typing, abstract datatypes, and higher-order programming) were designed to make ML into a trustworthy metalanguage for the finding and checking proofs in LCF [2].
- Research Article
- 10.24215/16666038.17.e19
- Oct 1, 2017
- Journal of Computer Science and Technology
Binary relational algebra provides semantic foundations for major areas of computing, such as database design, state-based modeling and functional programming. Remarkably, static checking support in these areas fails to exploit the full semantic content of relations. In particular, properties such as the simplicity or injectivity of relations are not statically enforced in operations such as database queries, state transitions, or composition of functional components. When data models, their constraints and operations are represented by point-free binary relational expressions, proof obligations can be expressed as inclusions between relational expressions. We developed a typedirected, strategic term rewriting system that can be used to simplify relational proof obligations and ultimately reduce them to tautologies. Such reductions can be used to provide extended static checking for design contraints commonly found in software modeling and development.
- Single Book
175
- 10.1017/cbo9780511626364
- Oct 13, 1998
First published in 1998, this textbook is a broad but rigourous survey of the theoretical basis for the design, definition and implementation of programming languages and of systems for specifying and proving programme behaviour. Both imperative and functional programming are covered, as well as the ways of integrating these aspects into more general languages. Recognising a unity of technique beneath the diversity of research in programming languages, the author presents an integrated treatment of the basic principles of the subject. He identifies the relatively small number of concepts, such as compositional semantics, binding structure, domains, transition systems and inference rules, that serve as the foundation of the field. Assuming only knowledge of elementary programming and mathematics, this text is perfect for advanced undergraduate and beginning graduate courses in programming language theory and also will appeal to researchers and professionals in designing or implementing computer languages.
- Book Chapter
- 10.1016/s0049-237x(08)71197-2
- Jan 1, 1968
- Studies in Logic and the Foundations of Mathematics
Problems in the Theory of Programming Languages
- Book Chapter
1
- 10.1007/978-3-319-27436-2_1
- Jan 1, 2015
In a world where trusting software systems is increasingly important, formal methods and formal proof can help provide trustable foundations. Proof checking can help to reduce the size of the trusted base since we do not need to trust an entire theorem prover if we can check the proofs they produce by a trusted and smaller checker. Many approaches to building proof checkers require embedding within them a full programming language. In most many modern proof checkers and theorem provers, that programming language is a functional programming language, often a variant of ML. In fact, parts of ML e.g., strong typing, abstract datatypes, and higher-order programming were designed to make ML into a trustworthy meta-language for checking proofs. While there is considerable overlap in the foundations of logic programming and proof checking both benefit from unification, backtracking search, efficient term structures, etc., the discipline of logic programming has, in fact, played a minor role in the history of proof checking. Ii¾źwill argue that logic programming can have a major role in the future of this important topic.
- Research Article
5
- 10.1007/s00165-016-0393-z
- Sep 5, 2016
- Formal Aspects of Computing
In a world where trusting software systems is increasingly important, formal methods and formal proof can help provide some basis for trust. Proof checking can help to reduce the size of the trusted base since we do not need to trust an entire theorem prover: instead, we only need to trust a (smaller and simpler) proof checker. Many approaches to building proof checkers require embedding within them a full programming language. In most modern proof checkers and theorem provers, that programming language is a functional programming language, often a variant of ML. In fact, aspects of ML (e.g., strong typing, abstract datatypes, and higher-order programming) were designed to make ML a trustworthy “meta-language” for checking proofs. While there is considerable overlap between logic programming and proof checking (e.g., both benefit from unification, backtracking search, efficient term structures, etc.), the discipline of logic programming has, in fact, played a minor role in the history of proof checking. I will argue that logic programming can have a major role in the future of this important topic.
- Book Chapter
8
- 10.1007/978-3-642-32202-0_4
- Jan 1, 2012
C++0x is the working title for the revision of the ISO standard of the C++ programming language that was originally planned for release in 2009 but that was delayed to 2011. The largest language extension in C++0x was “concepts”, that is, a collection of features for constraining template parameters. In September of 2008, the C++ standards committee voted the concepts extension into C++0x, but then in July of 2009, the committee voted the concepts extension back out of C++0x. This article is my account of the technical challenges and debates within the “concepts” effort in the years 2003 to 2009. To provide some background, the article also describes the design space for constrained parametric polymorphism, or what is colloquially know as constrained generics. While this article is meant to be generally accessible, the writing is aimed toward readers with background in functional programming and programming language theory. This article grew out of a lecture at the Spring School on Generic and Indexed Programming at the University of Oxford, March 2010.
- Single Report
4
- 10.15760/etd.2086
- Jan 1, 2000
Two major applications of lambda calculi in computer science are functional programming languages and mechanized reasoning systems (or, proof assistants). According to the Curry--Howard correspondence, it is possible, in principle, to design a unified language based on a typed lambda calculus for both logical reasoning and programming. However, the different requirements of programming languages and reasoning systems make it difficult to design such a unified language that provides both. Programming languages usually extend lambda calculi with programming-friendly features (e.g., recursive datatypes, general recursion) for supporting the flexibility to model various computations, while sacrificing logical consistency. Logical reasoning systems usually extend lambda calculi with logic-friendly features (e.g., induction principles, dependent types) for paradox-free inference over fine-grained properties, while being more restrictive in modeling computations. In this dissertation, we design and implement a language called Nax that embraces benefits of both. Nax accepts all recursive datatypes, thus, allowing the same flexibility of defining recursive datatypes as in functional languages. Nax supports a number of Mendler-style recursion schemes that can express various kinds of recursive computations and also guarantee termination. Nax supports term-indexed types to support specifications of fine-grained properties. In addition, Nax supports a conservative extension of Hindley--Milner type inference. The theoretical contributions of this dissertation include theories for Mendler-style recursion schemes and term-indexed types, which we developed to establish strong normalization and logical consistency of Nax.
- Single Book
12
- 10.1007/978-3-642-17330-1
- Jan 1, 2011
Programming languages are often classified according to their paradigms, e.g. imperative, functional, logic, constraint-based, object-oriented, or aspect-oriented. A paradigm characterizes the style, concepts, and methods of the language for describing situations and processes and for solving problems, and each paradigm serves best for programming in particular application areas. Real-world problems, however, are often best implemented by a combination of concepts from different paradigms, because they comprise aspects from several realms, and this combination is more comfortably realized using multiparadigm programming languages. This book deals with the theory and practice of multiparadigm constraint programming languages. The author first elaborates on programming paradigms and languages, constraints, and the merging of programming concepts which yields multiparadigm (constraint) programming languages. In the second part the author inspects two concrete approaches on multiparadigm constraint programming the concurrent constraint functional language CCFL, which combines the functional and the constraint-based paradigms and allows the description of concurrent processes; and a general framework for multiparadigm constraint programming and its implementation, Meta-S.The book is appropriate for researchers and graduate students in the areas of programming and artificial intelligence.